Skip to content

Move match_path from DefId to lint::LateContext #59738

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 2 additions & 104 deletions src/librustc/hir/def_id.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -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<LocalInternedString>;
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<Self::Region, Self::Error> {
Ok(())
}

fn print_type(self, _ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
Ok(())
}

fn print_dyn_existential(
self,
_predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
) -> Result<Self::DynExistential, Self::Error> {
Ok(())
}

fn path_crate(self, cnum: CrateNum) -> Result<Self::Path, Self::Error> {
Ok(vec![self.tcx.original_crate_name(cnum).as_str()])
}

fn path_qualified(
self,
self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> {
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<Self::Path, Self::Error>,
_disambiguated_data: &DisambiguatedDefPathData,
self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> {
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!("<impl {} for {}>", trait_ref, self_ty)).as_str()
},
None => Symbol::intern(&format!("<impl {}>", self_ty)).as_str(),
});

Ok(path)
}

fn path_append(
self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
disambiguated_data: &DisambiguatedDefPathData,
) -> Result<Self::Path, Self::Error> {
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<Self::Path, Self::Error>,
_args: &[Kind<'tcx>],
) -> Result<Self::Path, Self::Error> {
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 {}
Expand Down
113 changes: 111 additions & 2 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -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<LocalInternedString>;
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<Self::Region, Self::Error> {
Ok(())
}

fn print_type(self, _ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
Ok(())
}

fn print_dyn_existential(
self,
_predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
) -> Result<Self::DynExistential, Self::Error> {
Ok(())
}

fn path_crate(self, cnum: CrateNum) -> Result<Self::Path, Self::Error> {
Ok(vec![self.tcx.original_crate_name(cnum).as_str()])
}

fn path_qualified(
self,
self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> {
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<Self::Path, Self::Error>,
_disambiguated_data: &DisambiguatedDefPathData,
self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> {
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!("<impl {} for {}>", trait_ref, self_ty)).as_str()
},
None => Symbol::intern(&format!("<impl {}>", self_ty)).as_str(),
});

Ok(path)
}

fn path_append(
self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
disambiguated_data: &DisambiguatedDefPathData,
) -> Result<Self::Path, Self::Error> {
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<Self::Path, Self::Error>,
_args: &[Kind<'tcx>],
) -> Result<Self::Path, Self::Error> {
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> {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/lint/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"]);
}
}
}
Expand Down