-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Rustup #3889
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
Rustup #3889
Changes from all commits
31435cd
dcbd3ae
8eadbfd
2d8618e
dae5c9c
254fad9
3c4616d
180e07e
4832a85
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -129,54 +129,54 @@ fn get_ufcs_type_name( | |
method_def_id: def_id::DefId, | ||
self_arg: &Expr, | ||
) -> std::option::Option<String> { | ||
let expected_type_of_self = &cx.tcx.fn_sig(method_def_id).inputs_and_output().skip_binder()[0].sty; | ||
let actual_type_of_self = &cx.tables.node_type(self_arg.hir_id).sty; | ||
let expected_type_of_self = &cx.tcx.fn_sig(method_def_id).inputs_and_output().skip_binder()[0]; | ||
let actual_type_of_self = &cx.tables.node_type(self_arg.hir_id); | ||
|
||
if let Some(trait_id) = cx.tcx.trait_of_item(method_def_id) { | ||
if match_borrow_depth(expected_type_of_self, actual_type_of_self) { | ||
return Some(cx.tcx.item_path_str(trait_id)); | ||
if match_borrow_depth(expected_type_of_self, &actual_type_of_self) { | ||
return Some(cx.tcx.def_path_str(trait_id)); | ||
} | ||
} | ||
|
||
cx.tcx.impl_of_method(method_def_id).and_then(|_| { | ||
//a type may implicitly implement other type's methods (e.g. Deref) | ||
if match_types(expected_type_of_self, actual_type_of_self) { | ||
if match_types(expected_type_of_self, &actual_type_of_self) { | ||
return Some(get_type_name(cx, &actual_type_of_self)); | ||
} | ||
None | ||
}) | ||
} | ||
|
||
fn match_borrow_depth(lhs: &ty::TyKind<'_>, rhs: &ty::TyKind<'_>) -> bool { | ||
match (lhs, rhs) { | ||
(ty::Ref(_, t1, _), ty::Ref(_, t2, _)) => match_borrow_depth(&t1.sty, &t2.sty), | ||
fn match_borrow_depth(lhs: ty::Ty<'_>, rhs: ty::Ty<'_>) -> bool { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should import |
||
match (&lhs.sty, &rhs.sty) { | ||
(ty::Ref(_, t1, _), ty::Ref(_, t2, _)) => match_borrow_depth(&t1, &t2), | ||
(l, r) => match (l, r) { | ||
(ty::Ref(_, _, _), _) | (_, ty::Ref(_, _, _)) => false, | ||
(_, _) => true, | ||
}, | ||
} | ||
} | ||
|
||
fn match_types(lhs: &ty::TyKind<'_>, rhs: &ty::TyKind<'_>) -> bool { | ||
match (lhs, rhs) { | ||
fn match_types(lhs: ty::Ty<'_>, rhs: ty::Ty<'_>) -> bool { | ||
match (&lhs.sty, &rhs.sty) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, random note, cc @Manishearth @oli-obk: this looks like it could use the |
||
(ty::Bool, ty::Bool) | ||
| (ty::Char, ty::Char) | ||
| (ty::Int(_), ty::Int(_)) | ||
| (ty::Uint(_), ty::Uint(_)) | ||
| (ty::Str, ty::Str) => true, | ||
(ty::Ref(_, t1, _), ty::Ref(_, t2, _)) | ||
| (ty::Array(t1, _), ty::Array(t2, _)) | ||
| (ty::Slice(t1), ty::Slice(t2)) => match_types(&t1.sty, &t2.sty), | ||
| (ty::Slice(t1), ty::Slice(t2)) => match_types(&t1, &t2), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
(ty::Adt(def1, _), ty::Adt(def2, _)) => def1 == def2, | ||
(_, _) => false, | ||
} | ||
} | ||
|
||
fn get_type_name(cx: &LateContext<'_, '_>, kind: &ty::TyKind<'_>) -> String { | ||
match kind { | ||
ty::Adt(t, _) => cx.tcx.item_path_str(t.did), | ||
ty::Ref(_, r, _) => get_type_name(cx, &r.sty), | ||
_ => kind.to_string(), | ||
fn get_type_name(cx: &LateContext<'_, '_>, ty: ty::Ty<'_>) -> String { | ||
match ty.sty { | ||
ty::Adt(t, _) => cx.tcx.def_path_str(t.did), | ||
ty::Ref(_, r, _) => get_type_name(cx, &r), | ||
_ => ty.to_string(), | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,8 +24,10 @@ use if_chain::if_chain; | |
use matches::matches; | ||
use rustc::hir; | ||
use rustc::hir::def::Def; | ||
use rustc::hir::def_id::CrateNum; | ||
use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; | ||
use rustc::hir::intravisit::{NestedVisitorMap, Visitor}; | ||
use rustc::hir::map::DisambiguatedDefPathData; | ||
use rustc::hir::Node; | ||
use rustc::hir::*; | ||
use rustc::lint::{LateContext, Level, Lint, LintContext}; | ||
|
@@ -41,8 +43,7 @@ use rustc_errors::Applicability; | |
use syntax::ast::{self, LitKind}; | ||
use syntax::attr; | ||
use syntax::source_map::{Span, DUMMY_SP}; | ||
use syntax::symbol; | ||
use syntax::symbol::{keywords, Symbol}; | ||
use syntax::symbol::{keywords, LocalInternedString, Symbol}; | ||
|
||
use crate::reexport::*; | ||
|
||
|
@@ -97,19 +98,90 @@ pub fn in_macro(span: Span) -> bool { | |
/// Used to store the absolute path to a type. | ||
/// | ||
/// See `match_def_path` for usage. | ||
#[derive(Debug)] | ||
pub struct AbsolutePathBuffer { | ||
pub names: Vec<symbol::LocalInternedString>, | ||
pub struct AbsolutePathPrinter<'a, 'tcx> { | ||
pub tcx: TyCtxt<'a, 'tcx, 'tcx>, | ||
} | ||
|
||
impl ty::item_path::ItemPathBuffer for AbsolutePathBuffer { | ||
fn root_mode(&self) -> &ty::item_path::RootMode { | ||
const ABSOLUTE: &ty::item_path::RootMode = &ty::item_path::RootMode::Absolute; | ||
ABSOLUTE | ||
use rustc::ty::print::Printer; | ||
|
||
#[allow(clippy::diverging_sub_expression)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This sounds like a false positive - is an issue filled? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not really a FP: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I disagree, |
||
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 push(&mut self, text: &str) { | ||
self.names.push(symbol::Symbol::intern(text).as_str()); | ||
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> { | ||
// 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) | ||
} | ||
} | ||
|
||
|
@@ -121,12 +193,10 @@ impl ty::item_path::ItemPathBuffer for AbsolutePathBuffer { | |
/// ``` | ||
/// | ||
/// See also the `paths` module. | ||
pub fn match_def_path(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, path: &[&str]) -> bool { | ||
let mut apb = AbsolutePathBuffer { names: vec![] }; | ||
|
||
tcx.push_item_path(&mut apb, def_id, false); | ||
pub fn match_def_path<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, path: &[&str]) -> bool { | ||
let names = get_def_path(tcx, def_id); | ||
|
||
apb.names.len() == path.len() && apb.names.into_iter().zip(path.iter()).all(|(a, &b)| *a == *b) | ||
names.len() == path.len() && names.into_iter().zip(path.iter()).all(|(a, &b)| *a == *b) | ||
} | ||
|
||
/// Gets the absolute path of `def_id` as a vector of `&str`. | ||
|
@@ -138,12 +208,12 @@ pub fn match_def_path(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, path: &[&str]) -> | |
/// // The given `def_id` is that of an `Option` type | ||
/// }; | ||
/// ``` | ||
pub fn get_def_path(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Vec<&'static str> { | ||
flip1995 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
let mut apb = AbsolutePathBuffer { names: vec![] }; | ||
tcx.push_item_path(&mut apb, def_id, false); | ||
apb.names | ||
pub fn get_def_path<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Vec<&'static str> { | ||
AbsolutePathPrinter { tcx } | ||
.print_def_path(def_id, &[]) | ||
.unwrap() | ||
.iter() | ||
.map(syntax_pos::symbol::LocalInternedString::get) | ||
.map(LocalInternedString::get) | ||
.collect() | ||
} | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.