diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs index abfa96841d9..8536f38e48c 100644 --- a/src/librustc/hir/def_id.rs +++ b/src/librustc/hir/def_id.rs @@ -1,10 +1,9 @@ -use crate::ty::{self, print::Printer, subst::Kind, Ty, TyCtxt}; -use crate::hir::map::definitions::{DisambiguatedDefPathData, FIRST_FREE_HIGH_DEF_INDEX}; +use crate::ty::{self, TyCtxt}; +use crate::hir::map::definitions::FIRST_FREE_HIGH_DEF_INDEX; use rustc_data_structures::indexed_vec::Idx; use serialize; use std::fmt; use std::u32; -use syntax::symbol::{LocalInternedString, Symbol}; newtype_index! { pub struct CrateId { @@ -252,107 +251,6 @@ impl DefId { format!("module `{}`", tcx.def_path_str(*self)) } } - - /// Check if a `DefId`'s path matches the given absolute type path usage. - // Uplifted from rust-lang/rust-clippy - pub fn match_path<'a, 'tcx>(self, tcx: TyCtxt<'a, 'tcx, 'tcx>, path: &[&str]) -> bool { - pub struct AbsolutePathPrinter<'a, 'tcx> { - pub tcx: TyCtxt<'a, 'tcx, 'tcx>, - } - - impl<'tcx> Printer<'tcx, 'tcx> for AbsolutePathPrinter<'_, 'tcx> { - type Error = !; - - type Path = Vec; - type Region = (); - type Type = (); - type DynExistential = (); - - fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> { - self.tcx - } - - fn print_region(self, _region: ty::Region<'_>) -> Result { - Ok(()) - } - - fn print_type(self, _ty: Ty<'tcx>) -> Result { - Ok(()) - } - - fn print_dyn_existential( - self, - _predicates: &'tcx ty::List>, - ) -> Result { - Ok(()) - } - - fn path_crate(self, cnum: CrateNum) -> Result { - Ok(vec![self.tcx.original_crate_name(cnum).as_str()]) - } - - fn path_qualified( - self, - self_ty: Ty<'tcx>, - trait_ref: Option>, - ) -> Result { - if trait_ref.is_none() { - if let ty::Adt(def, substs) = self_ty.sty { - return self.print_def_path(def.did, substs); - } - } - - // This shouldn't ever be needed, but just in case: - Ok(vec![match trait_ref { - Some(trait_ref) => Symbol::intern(&format!("{:?}", trait_ref)).as_str(), - None => Symbol::intern(&format!("<{}>", self_ty)).as_str(), - }]) - } - - fn path_append_impl( - self, - print_prefix: impl FnOnce(Self) -> Result, - _disambiguated_data: &DisambiguatedDefPathData, - self_ty: Ty<'tcx>, - trait_ref: Option>, - ) -> Result { - let mut path = print_prefix(self)?; - - // This shouldn't ever be needed, but just in case: - path.push(match trait_ref { - Some(trait_ref) => { - Symbol::intern(&format!("", trait_ref, self_ty)).as_str() - }, - None => Symbol::intern(&format!("", self_ty)).as_str(), - }); - - Ok(path) - } - - fn path_append( - self, - print_prefix: impl FnOnce(Self) -> Result, - disambiguated_data: &DisambiguatedDefPathData, - ) -> Result { - let mut path = print_prefix(self)?; - path.push(disambiguated_data.data.as_interned_str().as_str()); - Ok(path) - } - - fn path_generic_args( - self, - print_prefix: impl FnOnce(Self) -> Result, - _args: &[Kind<'tcx>], - ) -> Result { - print_prefix(self) - } - } - - let names = AbsolutePathPrinter { tcx }.print_def_path(self, &[]).unwrap(); - - names.len() == path.len() - && names.into_iter().zip(path.iter()).all(|(a, &b)| *a == *b) - } } impl serialize::UseSpecializedEncodable for DefId {} diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index e5eafd768bb..15ea6403e38 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -25,7 +25,7 @@ use crate::lint::levels::{LintLevelSets, LintLevelsBuilder}; use crate::middle::privacy::AccessLevels; use crate::rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; use crate::session::{config, early_error, Session}; -use crate::ty::{self, TyCtxt, Ty}; +use crate::ty::{self, print::Printer, subst::Kind, TyCtxt, Ty}; use crate::ty::layout::{LayoutError, LayoutOf, TyLayout}; use crate::util::nodemap::FxHashMap; use crate::util::common::time; @@ -36,9 +36,10 @@ use syntax::edition; use syntax_pos::{MultiSpan, Span, symbol::{LocalInternedString, Symbol}}; use errors::DiagnosticBuilder; use crate::hir; -use crate::hir::def_id::{DefId, LOCAL_CRATE}; +use crate::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use crate::hir::intravisit as hir_visit; use crate::hir::intravisit::Visitor; +use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData}; use syntax::util::lev_distance::find_best_match_for_name; use syntax::visit as ast_visit; @@ -752,6 +753,114 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> { pub fn current_lint_root(&self) -> hir::HirId { self.last_node_with_lint_attrs } + + /// Check if a `DefId`'s path matches the given absolute type path usage. + // Uplifted from rust-lang/rust-clippy + pub fn match_path(&self, def_id: DefId, path: &[&str]) -> bool { + pub struct AbsolutePathPrinter<'a, 'tcx> { + pub tcx: TyCtxt<'a, 'tcx, 'tcx>, + } + + impl<'tcx> Printer<'tcx, 'tcx> for AbsolutePathPrinter<'_, 'tcx> { + type Error = !; + + type Path = Vec; + type Region = (); + type Type = (); + type DynExistential = (); + + fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> { + self.tcx + } + + fn print_region(self, _region: ty::Region<'_>) -> Result { + Ok(()) + } + + fn print_type(self, _ty: Ty<'tcx>) -> Result { + Ok(()) + } + + fn print_dyn_existential( + self, + _predicates: &'tcx ty::List>, + ) -> Result { + Ok(()) + } + + fn path_crate(self, cnum: CrateNum) -> Result { + Ok(vec![self.tcx.original_crate_name(cnum).as_str()]) + } + + fn path_qualified( + self, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + if trait_ref.is_none() { + if let ty::Adt(def, substs) = self_ty.sty { + return self.print_def_path(def.did, substs); + } + } + + // This shouldn't ever be needed, but just in case: + Ok(vec![match trait_ref { + Some(trait_ref) => Symbol::intern(&format!("{:?}", trait_ref)).as_str(), + None => Symbol::intern(&format!("<{}>", self_ty)).as_str(), + }]) + } + + fn path_append_impl( + self, + print_prefix: impl FnOnce(Self) -> Result, + _disambiguated_data: &DisambiguatedDefPathData, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + let mut path = print_prefix(self)?; + + // This shouldn't ever be needed, but just in case: + path.push(match trait_ref { + Some(trait_ref) => { + Symbol::intern(&format!("", trait_ref, self_ty)).as_str() + }, + None => Symbol::intern(&format!("", self_ty)).as_str(), + }); + + Ok(path) + } + + fn path_append( + self, + print_prefix: impl FnOnce(Self) -> Result, + disambiguated_data: &DisambiguatedDefPathData, + ) -> Result { + let mut path = print_prefix(self)?; + + // Skip `::{{constructor}}` on tuple/unit structs. + match disambiguated_data.data { + DefPathData::Ctor => return Ok(path), + _ => {} + } + + path.push(disambiguated_data.data.as_interned_str().as_str()); + Ok(path) + } + + fn path_generic_args( + self, + print_prefix: impl FnOnce(Self) -> Result, + _args: &[Kind<'tcx>], + ) -> Result { + print_prefix(self) + } + } + + let names = AbsolutePathPrinter { tcx: self.tcx }.print_def_path(def_id, &[]).unwrap(); + + names.len() == path.len() + && names.into_iter().zip(path.iter()).all(|(a, &b)| *a == *b) + } } impl<'a, 'tcx> LayoutOf for LateContext<'a, 'tcx> { diff --git a/src/librustc/lint/internal.rs b/src/librustc/lint/internal.rs index 030a9c1f935..0bafa93011e 100644 --- a/src/librustc/lint/internal.rs +++ b/src/librustc/lint/internal.rs @@ -100,7 +100,7 @@ fn lint_ty_kind_usage(cx: &LateContext<'_, '_>, segment: &PathSegment) -> bool { if segment.ident.as_str() == "TyKind" { if let Some(def) = segment.def { if let Some(did) = def.opt_def_id() { - return did.match_path(cx.tcx, &["rustc", "ty", "sty", "TyKind"]); + return cx.match_path(did, &["rustc", "ty", "sty", "TyKind"]); } } }