|
1 |
| -use crate::ty; |
2 |
| -use crate::ty::TyCtxt; |
3 |
| -use crate::hir::map::definitions::FIRST_FREE_HIGH_DEF_INDEX; |
| 1 | +use crate::ty::{self, print::Printer, subst::Kind, Ty, TyCtxt}; |
| 2 | +use crate::hir::map::definitions::{DisambiguatedDefPathData, FIRST_FREE_HIGH_DEF_INDEX}; |
4 | 3 | use rustc_data_structures::indexed_vec::Idx;
|
5 | 4 | use serialize;
|
6 | 5 | use std::fmt;
|
7 | 6 | use std::u32;
|
| 7 | +use syntax::symbol::{LocalInternedString, Symbol}; |
8 | 8 |
|
9 | 9 | newtype_index! {
|
10 | 10 | pub struct CrateId {
|
@@ -252,6 +252,107 @@ impl DefId {
|
252 | 252 | format!("module `{}`", tcx.def_path_str(*self))
|
253 | 253 | }
|
254 | 254 | }
|
| 255 | + |
| 256 | + /// Check if a `DefId`'s path matches the given absolute type path usage. |
| 257 | + // Uplifted from rust-lang/rust-clippy |
| 258 | + pub fn match_path<'a, 'tcx>(self, tcx: TyCtxt<'a, 'tcx, 'tcx>, path: &[&str]) -> bool { |
| 259 | + pub struct AbsolutePathPrinter<'a, 'tcx> { |
| 260 | + pub tcx: TyCtxt<'a, 'tcx, 'tcx>, |
| 261 | + } |
| 262 | + |
| 263 | + impl<'tcx> Printer<'tcx, 'tcx> for AbsolutePathPrinter<'_, 'tcx> { |
| 264 | + type Error = !; |
| 265 | + |
| 266 | + type Path = Vec<LocalInternedString>; |
| 267 | + type Region = (); |
| 268 | + type Type = (); |
| 269 | + type DynExistential = (); |
| 270 | + |
| 271 | + fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> { |
| 272 | + self.tcx |
| 273 | + } |
| 274 | + |
| 275 | + fn print_region(self, _region: ty::Region<'_>) -> Result<Self::Region, Self::Error> { |
| 276 | + Ok(()) |
| 277 | + } |
| 278 | + |
| 279 | + fn print_type(self, _ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> { |
| 280 | + Ok(()) |
| 281 | + } |
| 282 | + |
| 283 | + fn print_dyn_existential( |
| 284 | + self, |
| 285 | + _predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>, |
| 286 | + ) -> Result<Self::DynExistential, Self::Error> { |
| 287 | + Ok(()) |
| 288 | + } |
| 289 | + |
| 290 | + fn path_crate(self, cnum: CrateNum) -> Result<Self::Path, Self::Error> { |
| 291 | + Ok(vec![self.tcx.original_crate_name(cnum).as_str()]) |
| 292 | + } |
| 293 | + |
| 294 | + fn path_qualified( |
| 295 | + self, |
| 296 | + self_ty: Ty<'tcx>, |
| 297 | + trait_ref: Option<ty::TraitRef<'tcx>>, |
| 298 | + ) -> Result<Self::Path, Self::Error> { |
| 299 | + if trait_ref.is_none() { |
| 300 | + if let ty::Adt(def, substs) = self_ty.sty { |
| 301 | + return self.print_def_path(def.did, substs); |
| 302 | + } |
| 303 | + } |
| 304 | + |
| 305 | + // This shouldn't ever be needed, but just in case: |
| 306 | + Ok(vec![match trait_ref { |
| 307 | + Some(trait_ref) => Symbol::intern(&format!("{:?}", trait_ref)).as_str(), |
| 308 | + None => Symbol::intern(&format!("<{}>", self_ty)).as_str(), |
| 309 | + }]) |
| 310 | + } |
| 311 | + |
| 312 | + fn path_append_impl( |
| 313 | + self, |
| 314 | + print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, |
| 315 | + _disambiguated_data: &DisambiguatedDefPathData, |
| 316 | + self_ty: Ty<'tcx>, |
| 317 | + trait_ref: Option<ty::TraitRef<'tcx>>, |
| 318 | + ) -> Result<Self::Path, Self::Error> { |
| 319 | + let mut path = print_prefix(self)?; |
| 320 | + |
| 321 | + // This shouldn't ever be needed, but just in case: |
| 322 | + path.push(match trait_ref { |
| 323 | + Some(trait_ref) => { |
| 324 | + Symbol::intern(&format!("<impl {} for {}>", trait_ref, self_ty)).as_str() |
| 325 | + }, |
| 326 | + None => Symbol::intern(&format!("<impl {}>", self_ty)).as_str(), |
| 327 | + }); |
| 328 | + |
| 329 | + Ok(path) |
| 330 | + } |
| 331 | + |
| 332 | + fn path_append( |
| 333 | + self, |
| 334 | + print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, |
| 335 | + disambiguated_data: &DisambiguatedDefPathData, |
| 336 | + ) -> Result<Self::Path, Self::Error> { |
| 337 | + let mut path = print_prefix(self)?; |
| 338 | + path.push(disambiguated_data.data.as_interned_str().as_str()); |
| 339 | + Ok(path) |
| 340 | + } |
| 341 | + |
| 342 | + fn path_generic_args( |
| 343 | + self, |
| 344 | + print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, |
| 345 | + _args: &[Kind<'tcx>], |
| 346 | + ) -> Result<Self::Path, Self::Error> { |
| 347 | + print_prefix(self) |
| 348 | + } |
| 349 | + } |
| 350 | + |
| 351 | + let names = AbsolutePathPrinter { tcx }.print_def_path(self, &[]).unwrap(); |
| 352 | + |
| 353 | + names.len() == path.len() |
| 354 | + && names.into_iter().zip(path.iter()).all(|(a, &b)| *a == *b) |
| 355 | + } |
255 | 356 | }
|
256 | 357 |
|
257 | 358 | impl serialize::UseSpecializedEncodable for DefId {}
|
|
0 commit comments