Auto merge of #58140 - eddyb:advent-of-print, r=nikomatsakis

Refactor ppaux out of existence.

A long-time coming, this PR reorganizes and rewrites the pretty-printing architecture of rustc, specifically the parts that involve the typesystem (which used to be in `rustc::util::ppaux`).

*Note: these commits used to be in #57967 before being split off.*

The new API (i.e. the `Printer` and `PrettyPrint` traits) is in `rustc::ty::print`.

Design points, roughly:
* using associated types in `Printer` to allow building e.g. an AST, not just printing as a side-effect
* several overloading points for implementers of `PrettyPrinter`, e.g. how `<...>` is printed
* for `fmt::Display` impls, the value to print is lifted to the `ty::tls` `tcx`, and everything after that stays within the `ty::print` API, which requires `'tcx` to match between values and the printer's `tcx`, without going through `fmt::Display` again

Most of the behavior is unchanged, except for a few details, which should be clear from the test changes.

r? @nikomatsakis

Fixes https://github.com/rust-lang/rust/issues/55464
This commit is contained in:
bors 2019-03-15 13:58:03 +00:00
commit ad8a3eb039
143 changed files with 3405 additions and 2931 deletions

View file

@ -48,7 +48,6 @@ check:
$(Q)$(BOOTSTRAP) test $(BOOTSTRAP_ARGS)
check-aux:
$(Q)$(BOOTSTRAP) test \
src/test/pretty \
src/test/run-pass/pretty \
src/test/run-fail/pretty \
src/test/run-pass-valgrind/pretty \

View file

@ -897,12 +897,10 @@ host_test!(Rustdoc {
suite: "rustdoc"
});
test!(Pretty {
host_test!(Pretty {
path: "src/test/pretty",
mode: "pretty",
suite: "pretty",
default: false,
host: true
suite: "pretty"
});
test!(RunPassPretty {
path: "src/test/run-pass/pretty",
@ -993,11 +991,7 @@ impl Step for Compiletest {
});
}
if suite.ends_with("fulldeps") ||
// FIXME: Does pretty need librustc compiled? Note that there are
// fulldeps test suites with mode = pretty as well.
mode == "pretty"
{
if suite.ends_with("fulldeps") {
builder.ensure(compile::Rustc { compiler, target });
}

View file

@ -724,7 +724,7 @@ impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for DefId {
}
fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
tcx.item_path_str(*self)
tcx.def_path_str(*self)
}
}
@ -736,7 +736,7 @@ impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for DefIndex {
}
fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
tcx.item_path_str(DefId::local(*self))
tcx.def_path_str(DefId::local(*self))
}
}

View file

@ -249,7 +249,7 @@ impl DefId {
if self.is_local() && self.index == CRATE_DEF_INDEX {
format!("top-level module")
} else {
format!("module `{}`", tcx.item_path_str(*self))
format!("module `{}`", tcx.def_path_str(*self))
}
}
}

View file

@ -679,13 +679,13 @@ impl DefPathData {
return name
}
// note that this does not show up in user printouts
CrateRoot => "{{root}}",
CrateRoot => "{{crate}}",
Impl => "{{impl}}",
Misc => "{{?}}",
Misc => "{{misc}}",
ClosureExpr => "{{closure}}",
StructCtor => "{{constructor}}",
AnonConst => "{{constant}}",
ImplTrait => "{{impl-Trait}}",
ImplTrait => "{{opaque}}",
};
Symbol::intern(s).as_interned_str()

View file

@ -1351,7 +1351,8 @@ fn node_id_to_string(map: &Map<'_>, id: NodeId, include_id: bool) -> String {
// the user-friendly path, otherwise fall back to stringifying DefPath.
crate::ty::tls::with_opt(|tcx| {
if let Some(tcx) = tcx {
tcx.node_path_str(id)
let def_id = map.local_def_id(id);
tcx.def_path_str(def_id)
} else if let Some(path) = map.def_path_from_id(id) {
path.data.into_iter().map(|elem| {
elem.data.to_string()

View file

@ -223,7 +223,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
self.hir().span_by_hir_id(node),
),
_ => (
format!("the lifetime {} as defined on", fr.bound_region),
format!("the lifetime {} as defined on", region),
cm.def_span(self.hir().span_by_hir_id(node)),
),
},
@ -444,17 +444,109 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
terr: &TypeError<'tcx>,
sp: Span,
) {
use hir::def_id::CrateNum;
use hir::map::DisambiguatedDefPathData;
use ty::print::Printer;
use ty::subst::Kind;
struct AbsolutePathPrinter<'a, 'gcx, 'tcx> {
tcx: TyCtxt<'a, 'gcx, 'tcx>,
}
struct NonTrivialPath;
impl<'gcx, 'tcx> Printer<'gcx, 'tcx> for AbsolutePathPrinter<'_, 'gcx, 'tcx> {
type Error = NonTrivialPath;
type Path = Vec<String>;
type Region = !;
type Type = !;
type DynExistential = !;
fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx> {
self.tcx
}
fn print_region(
self,
_region: ty::Region<'_>,
) -> Result<Self::Region, Self::Error> {
Err(NonTrivialPath)
}
fn print_type(
self,
_ty: Ty<'tcx>,
) -> Result<Self::Type, Self::Error> {
Err(NonTrivialPath)
}
fn print_dyn_existential(
self,
_predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
) -> Result<Self::DynExistential, Self::Error> {
Err(NonTrivialPath)
}
fn path_crate(
self,
cnum: CrateNum,
) -> Result<Self::Path, Self::Error> {
Ok(vec![self.tcx.original_crate_name(cnum).to_string()])
}
fn path_qualified(
self,
_self_ty: Ty<'tcx>,
_trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> {
Err(NonTrivialPath)
}
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> {
Err(NonTrivialPath)
}
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().to_string());
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 report_path_match = |err: &mut DiagnosticBuilder<'_>, did1: DefId, did2: DefId| {
// Only external crates, if either is from a local
// module we could have false positives
if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate {
let exp_path = self.tcx.item_path_str(did1);
let found_path = self.tcx.item_path_str(did2);
let exp_abs_path = self.tcx.absolute_item_path_str(did1);
let found_abs_path = self.tcx.absolute_item_path_str(did2);
let abs_path = |def_id| {
AbsolutePathPrinter { tcx: self.tcx }
.print_def_path(def_id, &[])
};
// We compare strings because DefPath can be different
// for imported and non-imported crates
if exp_path == found_path || exp_abs_path == found_abs_path {
let same_path = || -> Result<_, NonTrivialPath> {
Ok(
self.tcx.def_path_str(did1) == self.tcx.def_path_str(did2) ||
abs_path(did1)? == abs_path(did2)?
)
};
if same_path().unwrap_or(false) {
let crate_name = self.tcx.crate_name(did1.krate);
err.span_note(
sp,
@ -658,7 +750,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
return Some(());
}
if let &ty::Adt(def, _) = &ta.sty {
let path_ = self.tcx.item_path_str(def.did.clone());
let path_ = self.tcx.def_path_str(def.did.clone());
if path_ == other_path {
self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, &other_ty);
return Some(());
@ -683,7 +775,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
/// For generic types with parameters with defaults, remove the parameters corresponding to
/// the defaults. This repeats a lot of the logic found in `PrintContext::parameterized`.
/// the defaults. This repeats a lot of the logic found in `ty::print::pretty`.
fn strip_generic_default_params(
&self,
def_id: DefId,
@ -742,11 +834,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
mutbl: hir::Mutability,
s: &mut DiagnosticStyledString,
) {
let r = &r.to_string();
let mut r = r.to_string();
if r == "'_" {
r.clear();
} else {
r.push(' ');
}
s.push_highlighted(format!(
"&{}{}{}",
"&{}{}",
r,
if r == "" { "" } else { " " },
if mutbl == hir::MutMutable { "mut " } else { "" }
));
s.push_normal(ty.to_string());
@ -757,8 +853,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let sub_no_defaults_1 = self.strip_generic_default_params(def1.did, sub1);
let sub_no_defaults_2 = self.strip_generic_default_params(def2.did, sub2);
let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
let path1 = self.tcx.item_path_str(def1.did.clone());
let path2 = self.tcx.item_path_str(def2.did.clone());
let path1 = self.tcx.def_path_str(def1.did.clone());
let path2 = self.tcx.def_path_str(def2.did.clone());
if def1.did == def2.did {
// Easy case. Replace same types with `_` to shorten the output and highlight
// the differing ones.
@ -1013,7 +1109,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
if exp_is_struct && &exp_found.expected == ret_ty.skip_binder() {
let message = format!(
"did you mean `{}(/* fields */)`?",
self.tcx.item_path_str(def_id)
self.tcx.def_path_str(def_id)
);
diag.span_label(span, message);
}
@ -1425,7 +1521,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
var_origin: RegionVariableOrigin,
) -> DiagnosticBuilder<'tcx> {
let br_string = |br: ty::BoundRegion| {
let mut s = br.to_string();
let mut s = match br {
ty::BrNamed(_, name) => name.to_string(),
_ => String::new(),
};
if !s.is_empty() {
s.push_str(" ");
}

View file

@ -1,8 +1,10 @@
use crate::hir::def::Namespace;
use crate::hir::{self, Local, Pat, Body, HirId};
use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
use crate::infer::InferCtxt;
use crate::infer::type_variable::TypeVariableOrigin;
use crate::ty::{self, Ty, Infer, TyVar};
use crate::ty::print::Print;
use syntax::source_map::CompilerDesugaringKind;
use syntax_pos::Span;
use errors::DiagnosticBuilder;
@ -64,18 +66,26 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
pub fn extract_type_name(&self, ty: &'a Ty<'tcx>) -> String {
pub fn extract_type_name(
&self,
ty: &'a Ty<'tcx>,
highlight: Option<ty::print::RegionHighlightMode>,
) -> String {
if let ty::Infer(ty::TyVar(ty_vid)) = (*ty).sty {
let ty_vars = self.type_variables.borrow();
if let TypeVariableOrigin::TypeParameterDefinition(_, name) =
*ty_vars.var_origin(ty_vid) {
name.to_string()
} else {
ty.to_string()
return name.to_string();
}
} else {
ty.to_string()
}
let mut s = String::new();
let mut printer = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS);
if let Some(highlight) = highlight {
printer.region_highlight_mode = highlight;
}
let _ = ty.print(printer);
s
}
pub fn need_type_info_err(&self,
@ -84,7 +94,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
ty: Ty<'tcx>)
-> DiagnosticBuilder<'gcx> {
let ty = self.resolve_type_vars_if_possible(&ty);
let name = self.extract_type_name(&ty);
let name = self.extract_type_name(&ty, None);
let mut err_span = span;
let mut labels = vec![(

View file

@ -1,14 +1,17 @@
use errors::DiagnosticBuilder;
use crate::hir::def::Namespace;
use crate::hir::def_id::DefId;
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
use crate::infer::lexical_region_resolve::RegionResolutionError;
use crate::infer::ValuePairs;
use crate::infer::{SubregionOrigin, TypeTrace};
use crate::traits::{ObligationCause, ObligationCauseCode};
use crate::ty;
use crate::ty::{self, TyCtxt};
use crate::ty::error::ExpectedFound;
use crate::ty::subst::SubstsRef;
use crate::util::ppaux::RegionHighlightMode;
use crate::ty::print::{Print, RegionHighlightMode, FmtPrinter};
use std::fmt::{self, Write};
impl NiceRegionError<'me, 'gcx, 'tcx> {
/// When given a `ConcreteFailure` for a function with arguments containing a named region and
@ -193,7 +196,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
cause.span(&self.tcx()),
&format!(
"implementation of `{}` is not general enough",
self.tcx().item_path_str(trait_def_id),
self.tcx().def_path_str(trait_def_id),
),
);
@ -201,7 +204,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
ObligationCauseCode::ItemObligation(def_id) => {
err.note(&format!(
"Due to a where-clause on `{}`,",
self.tcx().item_path_str(def_id),
self.tcx().def_path_str(def_id),
));
}
_ => (),
@ -309,13 +312,46 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
sup_placeholder: Option<ty::Region<'tcx>>,
has_sub: Option<usize>,
has_sup: Option<usize>,
expected_trait_ref: ty::TraitRef<'_>,
actual_trait_ref: ty::TraitRef<'_>,
expected_trait_ref: ty::TraitRef<'tcx>,
actual_trait_ref: ty::TraitRef<'tcx>,
vid: Option<ty::Region<'tcx>>,
expected_has_vid: Option<usize>,
actual_has_vid: Option<usize>,
any_self_ty_has_vid: bool,
) {
// HACK(eddyb) maybe move this in a more central location.
#[derive(Copy, Clone)]
struct Highlighted<'a, 'gcx, 'tcx, T> {
tcx: TyCtxt<'a, 'gcx, 'tcx>,
highlight: RegionHighlightMode,
value: T,
}
impl<'a, 'gcx, 'tcx, T> Highlighted<'a, 'gcx, 'tcx, T> {
fn map<U>(self, f: impl FnOnce(T) -> U) -> Highlighted<'a, 'gcx, 'tcx, U> {
Highlighted {
tcx: self.tcx,
highlight: self.highlight,
value: f(self.value),
}
}
}
impl<'a, 'gcx, 'tcx, T> fmt::Display for Highlighted<'a, 'gcx, 'tcx, T>
where T: for<'b, 'c> Print<'gcx, 'tcx,
FmtPrinter<'a, 'gcx, 'tcx, &'b mut fmt::Formatter<'c>>,
Error = fmt::Error,
>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut printer = ty::print::FmtPrinter::new(self.tcx, f, Namespace::TypeNS);
printer.region_highlight_mode = self.highlight;
self.value.print(printer)?;
Ok(())
}
}
// The weird thing here with the `maybe_highlighting_region` calls and the
// the match inside is meant to be like this:
//
@ -331,112 +367,93 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
// None, an then we check again inside the closure, but this
// setup sort of minimized the number of calls and so form.
RegionHighlightMode::maybe_highlighting_region(sub_placeholder, has_sub, || {
RegionHighlightMode::maybe_highlighting_region(sup_placeholder, has_sup, || {
match (has_sub, has_sup) {
(Some(n1), Some(n2)) => {
if any_self_ty_has_vid {
err.note(&format!(
"`{}` would have to be implemented for the type `{}`, \
for any two lifetimes `'{}` and `'{}`",
expected_trait_ref,
expected_trait_ref.self_ty(),
std::cmp::min(n1, n2),
std::cmp::max(n1, n2),
));
} else {
err.note(&format!(
"`{}` must implement `{}`, \
for any two lifetimes `'{}` and `'{}`",
expected_trait_ref.self_ty(),
expected_trait_ref,
std::cmp::min(n1, n2),
std::cmp::max(n1, n2),
));
}
let highlight_trait_ref = |trait_ref| Highlighted {
tcx: self.tcx(),
highlight: RegionHighlightMode::default(),
value: trait_ref,
};
let mut expected_trait_ref = highlight_trait_ref(expected_trait_ref);
expected_trait_ref.highlight.maybe_highlighting_region(sub_placeholder, has_sub);
expected_trait_ref.highlight.maybe_highlighting_region(sup_placeholder, has_sup);
err.note(&{
let passive_voice = match (has_sub, has_sup) {
(Some(_), _) | (_, Some(_)) => any_self_ty_has_vid,
(None, None) => {
expected_trait_ref.highlight.maybe_highlighting_region(vid, expected_has_vid);
match expected_has_vid {
Some(_) => true,
None => any_self_ty_has_vid,
}
(Some(n), _) | (_, Some(n)) => {
if any_self_ty_has_vid {
err.note(&format!(
"`{}` would have to be implemented for the type `{}`, \
for any lifetime `'{}`",
expected_trait_ref,
expected_trait_ref.self_ty(),
n,
));
} else {
err.note(&format!(
"`{}` must implement `{}`, for any lifetime `'{}`",
expected_trait_ref.self_ty(),
expected_trait_ref,
n,
));
}
}
(None, None) => RegionHighlightMode::maybe_highlighting_region(
vid,
expected_has_vid,
|| {
if let Some(n) = expected_has_vid {
err.note(&format!(
"`{}` would have to be implemented for the type `{}`, \
for some specific lifetime `'{}`",
expected_trait_ref,
expected_trait_ref.self_ty(),
n,
));
} else {
if any_self_ty_has_vid {
err.note(&format!(
"`{}` would have to be implemented for the type `{}`",
expected_trait_ref,
expected_trait_ref.self_ty(),
));
} else {
err.note(&format!(
"`{}` must implement `{}`",
expected_trait_ref.self_ty(),
expected_trait_ref,
));
}
}
},
),
}
})
};
let mut note = if passive_voice {
format!(
"`{}` would have to be implemented for the type `{}`",
expected_trait_ref,
expected_trait_ref.map(|tr| tr.self_ty()),
)
} else {
format!(
"`{}` must implement `{}`",
expected_trait_ref.map(|tr| tr.self_ty()),
expected_trait_ref,
)
};
match (has_sub, has_sup) {
(Some(n1), Some(n2)) => {
let _ = write!(note,
", for any two lifetimes `'{}` and `'{}`",
std::cmp::min(n1, n2),
std::cmp::max(n1, n2),
);
}
(Some(n), _) | (_, Some(n)) => {
let _ = write!(note,
", for any lifetime `'{}`",
n,
);
}
(None, None) => if let Some(n) = expected_has_vid {
let _ = write!(note,
", for some specific lifetime `'{}`",
n,
);
},
}
note
});
RegionHighlightMode::maybe_highlighting_region(
vid,
actual_has_vid,
|| match actual_has_vid {
Some(n) => {
if any_self_ty_has_vid {
err.note(&format!(
"but `{}` is actually implemented for the type `{}`, \
for some specific lifetime `'{}`",
actual_trait_ref,
actual_trait_ref.self_ty(),
n
));
} else {
err.note(&format!(
"but `{}` actually implements `{}`, for some specific lifetime `'{}`",
actual_trait_ref.self_ty(),
actual_trait_ref,
n
));
}
}
let mut actual_trait_ref = highlight_trait_ref(actual_trait_ref);
actual_trait_ref.highlight.maybe_highlighting_region(vid, actual_has_vid);
err.note(&{
let passive_voice = match actual_has_vid {
Some(_) => any_self_ty_has_vid,
None => true,
};
_ => {
err.note(&format!(
"but `{}` is actually implemented for the type `{}`",
actual_trait_ref,
actual_trait_ref.self_ty(),
));
}
},
);
let mut note = if passive_voice {
format!(
"but `{}` is actually implemented for the type `{}`",
actual_trait_ref,
actual_trait_ref.map(|tr| tr.self_ty()),
)
} else {
format!(
"but `{}` actually implements `{}`",
actual_trait_ref.map(|tr| tr.self_ty()),
actual_trait_ref,
)
};
if let Some(n) = actual_has_vid {
let _ = write!(note, ", for some specific lifetime `'{}`", n);
}
note
});
}
}

View file

@ -3,7 +3,7 @@
use crate::hir;
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
use crate::ty::{self, Region, Ty};
use crate::ty::{self, DefIdTree, Region, Ty};
use crate::hir::def_id::DefId;
use syntax_pos::Span;
@ -44,7 +44,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
let (id, bound_region) = match *anon_region {
ty::ReFree(ref free_region) => (free_region.scope, free_region.bound_region),
ty::ReEarlyBound(ref ebr) => (
self.tcx().parent_def_id(ebr.def_id).unwrap(),
self.tcx().parent(ebr.def_id).unwrap(),
ty::BoundRegion::BrNamed(ebr.def_id, ebr.name),
),
_ => return None, // not a free region

View file

@ -91,7 +91,7 @@ impl_stable_hash_for!(struct FreeRegionMap<'tcx> {
impl<'a, 'tcx> Lift<'tcx> for FreeRegionMap<'a> {
type Lifted = FreeRegionMap<'tcx>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<FreeRegionMap<'tcx>> {
self.relation.maybe_map(|&fr| fr.lift_to_tcx(tcx))
self.relation.maybe_map(|&fr| tcx.lift(&fr))
.map(|relation| FreeRegionMap { relation })
}
}

View file

@ -31,6 +31,7 @@
#![deny(rust_2018_idioms)]
#![allow(explicit_outlives_requirements)]
#![feature(arbitrary_self_types)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(core_intrinsics)]
@ -134,7 +135,6 @@ pub mod ty;
pub mod util {
pub mod captures;
pub mod common;
pub mod ppaux;
pub mod nodemap;
pub mod profiling;
pub mod bug;

View file

@ -12,7 +12,7 @@ use crate::hir::CodegenFnAttrFlags;
use crate::hir::def_id::{DefId, LOCAL_CRATE};
use crate::lint;
use crate::middle::privacy;
use crate::ty::{self, TyCtxt};
use crate::ty::{self, DefIdTree, TyCtxt};
use crate::util::nodemap::FxHashSet;
use rustc_data_structures::fx::FxHashMap;
@ -78,7 +78,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
Def::PrimTy(..) | Def::SelfTy(..) | Def::SelfCtor(..) |
Def::Local(..) | Def::Upvar(..) => {}
Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => {
if let Some(enum_id) = self.tcx.parent_def_id(variant_id) {
if let Some(enum_id) = self.tcx.parent(variant_id) {
self.check_def_id(enum_id);
}
if !self.ignore_variant_stack.contains(&variant_id) {

View file

@ -64,7 +64,7 @@ use crate::hir::Node;
use crate::infer::InferCtxt;
use crate::hir::def::{Def, CtorKind};
use crate::ty::adjustment;
use crate::ty::{self, Ty, TyCtxt};
use crate::ty::{self, DefIdTree, Ty, TyCtxt};
use crate::ty::fold::TypeFoldable;
use crate::ty::layout::VariantIdx;
@ -786,7 +786,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
// FnMut | copied -> &'env mut | upvar -> &'env mut -> &'up bk
// FnOnce | copied | upvar -> &'up bk
let kind = match self.node_ty(fn_hir_id)?.sty {
let ty = self.node_ty(fn_hir_id)?;
let kind = match ty.sty {
ty::Generator(..) => ty::ClosureKind::FnOnce,
ty::Closure(closure_def_id, closure_substs) => {
match self.infcx {
@ -803,7 +804,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
.closure_kind(closure_def_id, self.tcx.global_tcx()),
}
}
ref t => span_bug!(span, "unexpected type for fn in mem_categorization: {:?}", t),
_ => span_bug!(span, "unexpected type for fn in mem_categorization: {:?}", ty),
};
let closure_expr_def_id = self.tcx.hir().local_def_id(fn_node_id);
@ -1064,7 +1065,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
let bk = ty::BorrowKind::from_mutbl(mutbl);
BorrowedPtr(bk, r)
}
ref ty => bug!("unexpected type in cat_deref: {:?}", ty)
_ => bug!("unexpected type in cat_deref: {:?}", base_cmt.ty)
};
let ret = cmt_ {
hir_id: node.hir_id(),
@ -1132,7 +1133,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
variant_did: DefId)
-> cmt<'tcx> {
// univariant enums do not need downcasts
let base_did = self.tcx.parent_def_id(variant_did).unwrap();
let base_did = self.tcx.parent(variant_did).unwrap();
if self.tcx.adt_def(base_did).variants.len() != 1 {
let base_ty = base_cmt.ty;
let ret = Rc::new(cmt_ {
@ -1274,16 +1275,17 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
return Err(())
}
Def::VariantCtor(def_id, CtorKind::Fn) => {
let enum_def = self.tcx.parent_def_id(def_id).unwrap();
let enum_def = self.tcx.parent(def_id).unwrap();
(self.cat_downcast_if_needed(pat, cmt, def_id),
self.tcx.adt_def(enum_def).variant_with_id(def_id).fields.len())
}
Def::StructCtor(_, CtorKind::Fn) | Def::SelfCtor(..) => {
match self.pat_ty_unadjusted(&pat)?.sty {
let ty = self.pat_ty_unadjusted(&pat)?;
match ty.sty {
ty::Adt(adt_def, _) => {
(cmt, adt_def.non_enum_variant().fields.len())
}
ref ty => {
_ => {
span_bug!(pat.span,
"tuple struct pattern unexpected type {:?}", ty);
}
@ -1334,9 +1336,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
PatKind::Tuple(ref subpats, ddpos) => {
// (p1, ..., pN)
let expected_len = match self.pat_ty_unadjusted(&pat)?.sty {
let ty = self.pat_ty_unadjusted(&pat)?;
let expected_len = match ty.sty {
ty::Tuple(ref tys) => tys.len(),
ref ty => span_bug!(pat.span, "tuple pattern unexpected type {:?}", ty),
_ => span_bug!(pat.span, "tuple pattern unexpected type {:?}", ty),
};
for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
let subpat_ty = self.pat_ty_adjusted(&subpat)?; // see (*2)

View file

@ -17,7 +17,7 @@ use rustc_macros::HashStable;
use syntax::source_map;
use syntax::ast;
use syntax_pos::{Span, DUMMY_SP};
use crate::ty::TyCtxt;
use crate::ty::{DefIdTree, TyCtxt};
use crate::ty::query::Providers;
use crate::hir;
@ -650,7 +650,7 @@ impl<'tcx> ScopeTree {
pub fn early_free_scope<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
br: &ty::EarlyBoundRegion)
-> Scope {
let param_owner = tcx.parent_def_id(br.def_id).unwrap();
let param_owner = tcx.parent(br.def_id).unwrap();
let param_owner_id = tcx.hir().as_local_hir_id(param_owner).unwrap();
let scope = tcx.hir().maybe_body_owned_by_by_hir_id(param_owner_id).map(|body_id| {
@ -679,7 +679,7 @@ impl<'tcx> ScopeTree {
-> Scope {
let param_owner = match fr.bound_region {
ty::BoundRegion::BrNamed(def_id, _) => {
tcx.parent_def_id(def_id).unwrap()
tcx.parent(def_id).unwrap()
}
_ => fr.scope
};

View file

@ -593,7 +593,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
.map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry));
if !skip {
let path = self.item_path_str(def_id);
let path = self.def_path_str(def_id);
let message = format!("use of deprecated item '{}'", path);
lint_deprecated(def_id,
id,
@ -620,7 +620,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
if let Some(id) = id {
if let Some(stability) = stability {
if let Some(depr) = &stability.rustc_depr {
let path = self.item_path_str(def_id);
let path = self.def_path_str(def_id);
if deprecation_in_effect(&depr.since.as_str()) {
let message = format!("use of deprecated item '{}'", path);
lint_deprecated(def_id,

View file

@ -2,7 +2,7 @@
//!
//! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/index.html
use crate::hir::def::CtorKind;
use crate::hir::def::{CtorKind, Namespace};
use crate::hir::def_id::DefId;
use crate::hir::{self, HirId, InlineAsm};
use crate::mir::interpret::{ConstValue, EvalErrorKind, Scalar};
@ -34,7 +34,7 @@ use crate::ty::{
self, AdtDef, CanonicalUserTypeAnnotations, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt,
UserTypeAnnotationIndex,
};
use crate::util::ppaux;
use crate::ty::print::{FmtPrinter, Printer};
pub use crate::mir::interpret::AssertMessage;
@ -2062,7 +2062,7 @@ impl<'tcx> Debug for Place<'tcx> {
Base(PlaceBase::Static(box self::Static { def_id, ty })) => write!(
fmt,
"({}: {:?})",
ty::tls::with(|tcx| tcx.item_path_str(def_id)),
ty::tls::with(|tcx| tcx.def_path_str(def_id)),
ty
),
Base(PlaceBase::Promoted(ref promoted)) => write!(
@ -2369,7 +2369,10 @@ impl<'tcx> Debug for Rvalue<'tcx> {
};
// When printing regions, add trailing space if necessary.
let region = if ppaux::verbose() || ppaux::identify_regions() {
let print_region = ty::tls::with(|tcx| {
tcx.sess.verbose() || tcx.sess.opts.debugging_opts.identify_regions
});
let region = if print_region {
let mut region = region.to_string();
if region.len() > 0 {
region.push(' ');
@ -2403,7 +2406,13 @@ impl<'tcx> Debug for Rvalue<'tcx> {
AggregateKind::Adt(adt_def, variant, substs, _user_ty, _) => {
let variant_def = &adt_def.variants[variant];
ppaux::parameterized(fmt, substs, variant_def.did, &[])?;
let f = &mut *fmt;
ty::tls::with(|tcx| {
let substs = tcx.lift(&substs).expect("could not lift for printing");
FmtPrinter::new(tcx, f, Namespace::ValueNS)
.print_def_path(variant_def.did, substs)?;
Ok(())
})?;
match variant_def.ctor_kind {
CtorKind::Const => Ok(()),
@ -2729,7 +2738,7 @@ pub fn fmt_const_val(f: &mut impl Write, const_val: ty::Const<'_>) -> fmt::Resul
}
// print function definitions
if let FnDef(did, _) = ty.sty {
return write!(f, "{}", item_path_str(did));
return write!(f, "{}", def_path_str(did));
}
// print string literals
if let ConstValue::Slice(ptr, len) = value {
@ -2754,8 +2763,8 @@ pub fn fmt_const_val(f: &mut impl Write, const_val: ty::Const<'_>) -> fmt::Resul
write!(f, "{:?}:{}", value, ty)
}
fn item_path_str(def_id: DefId) -> String {
ty::tls::with(|tcx| tcx.item_path_str(def_id))
fn def_path_str(def_id: DefId) -> String {
ty::tls::with(|tcx| tcx.def_path_str(def_id))
}
impl<'tcx> graph::DirectedGraph for Mir<'tcx> {

View file

@ -854,10 +854,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
_ => vec![ArgKind::empty()],
};
let expected = match expected_trait_ref.skip_binder().substs.type_at(1).sty {
let expected_ty = expected_trait_ref.skip_binder().substs.type_at(1);
let expected = match expected_ty.sty {
ty::Tuple(ref tys) => tys.iter()
.map(|t| ArgKind::from_expected_ty(t, Some(span))).collect(),
ref sty => vec![ArgKind::Arg("_".to_owned(), sty.to_string())],
_ => vec![ArgKind::Arg("_".to_owned(), expected_ty.to_string())],
};
if found.len() == expected.len() {
@ -1284,11 +1285,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
let span = self.sess.source_map().def_span(span);
let mut err = struct_span_err!(self.sess, span, E0072,
"recursive type `{}` has infinite size",
self.item_path_str(type_def_id));
self.def_path_str(type_def_id));
err.span_label(span, "recursive type has infinite size");
err.help(&format!("insert indirection (e.g., a `Box`, `Rc`, or `&`) \
at some point to make `{}` representable",
self.item_path_str(type_def_id)));
self.def_path_str(type_def_id)));
err
}
@ -1298,7 +1299,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
violations: Vec<ObjectSafetyViolation>)
-> DiagnosticBuilder<'tcx>
{
let trait_str = self.item_path_str(trait_def_id);
let trait_str = self.def_path_str(trait_def_id);
let span = self.sess.source_map().def_span(span);
let mut err = struct_span_err!(
self.sess, span, E0038,
@ -1523,7 +1524,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
region, object_ty));
}
ObligationCauseCode::ItemObligation(item_def_id) => {
let item_name = tcx.item_path_str(item_def_id);
let item_name = tcx.def_path_str(item_def_id);
let msg = format!("required by `{}`", item_name);
if let Some(sp) = tcx.hir().span_if_local(item_def_id) {
@ -1686,10 +1687,10 @@ impl ArgKind {
ty::Tuple(ref tys) => ArgKind::Tuple(
span,
tys.iter()
.map(|ty| ("_".to_owned(), ty.sty.to_string()))
.map(|ty| ("_".to_owned(), ty.to_string()))
.collect::<Vec<_>>()
),
_ => ArgKind::Arg("_".to_owned(), t.sty.to_string()),
_ => ArgKind::Arg("_".to_owned(), t.to_string()),
}
}
}

View file

@ -650,7 +650,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'gcx, 'tcx>(
) -> bool {
debug!("type_known_to_meet_bound_modulo_regions(ty={:?}, bound={:?})",
ty,
infcx.tcx.item_path_str(def_id));
infcx.tcx.def_path_str(def_id));
let trait_ref = ty::TraitRef {
def_id,
@ -665,7 +665,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'gcx, 'tcx>(
let result = infcx.predicate_must_hold_modulo_regions(&obligation);
debug!("type_known_to_meet_ty={:?} bound={} => {:?}",
ty, infcx.tcx.item_path_str(def_id), result);
ty, infcx.tcx.def_path_str(def_id), result);
if result && (ty.has_infer_types() || ty.has_closure_types()) {
// Because of inference "guessing", selection can sometimes claim
@ -692,13 +692,13 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'gcx, 'tcx>(
Ok(()) => {
debug!("type_known_to_meet_bound_modulo_regions: ty={:?} bound={} success",
ty,
infcx.tcx.item_path_str(def_id));
infcx.tcx.def_path_str(def_id));
true
}
Err(e) => {
debug!("type_known_to_meet_bound_modulo_regions: ty={:?} bound={} errors={:?}",
ty,
infcx.tcx.item_path_str(def_id),
infcx.tcx.def_path_str(def_id),
e);
false
}

View file

@ -133,7 +133,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
hir::CRATE_HIR_ID,
*span,
&format!("the trait `{}` cannot be made into an object",
self.item_path_str(trait_def_id)),
self.def_path_str(trait_def_id)),
&violation.error_msg());
false
} else {

View file

@ -276,7 +276,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
-> String
{
let name = tcx.item_name(trait_ref.def_id);
let trait_str = tcx.item_path_str(trait_ref.def_id);
let trait_str = tcx.def_path_str(trait_ref.def_id);
let generics = tcx.generics_of(trait_ref.def_id);
let generic_map = generics.params.iter().filter_map(|param| {
let value = match param.kind {

View file

@ -1549,7 +1549,7 @@ fn assoc_ty_def<'cx, 'gcx, 'tcx>(
// should have failed in astconv.
bug!("No associated type `{}` for {}",
assoc_ty_name,
tcx.item_path_str(impl_def_id))
tcx.def_path_str(impl_def_id))
}
}

View file

@ -411,7 +411,7 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_, '_, '_>, impl_def_id: DefId) -> Option<
w.push('<');
w.push_str(&substs.iter()
.map(|k| k.to_string())
.filter(|k| &k[..] != "'_")
.filter(|k| k != "'_")
.collect::<Vec<_>>().join(", "));
w.push('>');
}

View file

@ -165,7 +165,8 @@ impl<'tcx> fmt::Display for traits::WhereClause<'tcx> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
use crate::traits::WhereClause::*;
// Bypass ppaux because it does not print out anonymous regions.
// Bypass `ty::print` because it does not print out anonymous regions.
// FIXME(eddyb) implement a custom `PrettyPrinter`, or move this to `ty::print`.
fn write_region_name<'tcx>(
r: ty::Region<'tcx>,
fmt: &mut fmt::Formatter<'_>
@ -256,7 +257,7 @@ impl fmt::Display for traits::QuantifierKind {
}
/// Collect names for regions / types bound by a quantified goal / clause.
/// This collector does not try to do anything clever like in ppaux, it's just used
/// This collector does not try to do anything clever like in `ty::print`, it's just used
/// for debug output in tests anyway.
struct BoundNamesCollector {
// Just sort by name because `BoundRegion::BrNamed` does not have a `BoundVar` index anyway.

View file

@ -26,7 +26,7 @@ use crate::ty::subst::{Kind, InternalSubsts, SubstsRef, Subst};
use crate::ty::ReprOptions;
use crate::traits;
use crate::traits::{Clause, Clauses, GoalKind, Goal, Goals};
use crate::ty::{self, Ty, TypeAndMut};
use crate::ty::{self, DefIdTree, Ty, TypeAndMut};
use crate::ty::{TyS, TyKind, List};
use crate::ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorSubsts, Region, Const, LazyConst};
use crate::ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate, Predicate};
@ -1594,7 +1594,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
let (suitable_region_binding_scope, bound_region) = match *region {
ty::ReFree(ref free_region) => (free_region.scope, free_region.bound_region),
ty::ReEarlyBound(ref ebr) => (
self.parent_def_id(ebr.def_id).unwrap(),
self.parent(ebr.def_id).unwrap(),
ty::BoundRegion::BrNamed(ebr.def_id, ebr.name),
),
_ => return None, // not a free region

View file

@ -71,6 +71,13 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
}
}
let br_string = |br: ty::BoundRegion| {
match br {
ty::BrNamed(_, name) => format!(" {}", name),
_ => String::new(),
}
};
match *self {
CyclicTy(_) => write!(f, "cyclic type of infinite size"),
Mismatch => write!(f, "types differ"),
@ -105,15 +112,13 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
}
RegionsInsufficientlyPolymorphic(br, _) => {
write!(f,
"expected bound lifetime parameter{}{}, found concrete lifetime",
if br.is_named() { " " } else { "" },
br)
"expected bound lifetime parameter{}, found concrete lifetime",
br_string(br))
}
RegionsOverlyPolymorphic(br, _) => {
write!(f,
"expected concrete lifetime, found bound lifetime parameter{}{}",
if br.is_named() { " " } else { "" },
br)
"expected concrete lifetime, found bound lifetime parameter{}",
br_string(br))
}
RegionsPlaceholderMismatch => {
write!(f, "one type is more general than the other")
@ -125,9 +130,9 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
Traits(values) => ty::tls::with(|tcx| {
report_maybe_different(f,
&format!("trait `{}`",
tcx.item_path_str(values.expected)),
tcx.def_path_str(values.expected)),
&format!("trait `{}`",
tcx.item_path_str(values.found)))
tcx.def_path_str(values.found)))
}),
IntMismatch(ref values) => {
write!(f, "expected `{:?}`, found `{:?}`",
@ -146,8 +151,8 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
}
ProjectionMismatched(ref values) => ty::tls::with(|tcx| {
write!(f, "expected {}, found {}",
tcx.item_path_str(values.expected),
tcx.item_path_str(values.found))
tcx.def_path_str(values.expected),
tcx.def_path_str(values.found))
}),
ProjectionBoundsLength(ref values) => {
write!(f, "expected {} associated type bindings, found {}",
@ -169,8 +174,8 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
ty::Uint(_) | ty::Float(_) | ty::Str | ty::Never => self.to_string().into(),
ty::Tuple(ref tys) if tys.is_empty() => self.to_string().into(),
ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.item_path_str(def.did)).into(),
ty::Foreign(def_id) => format!("extern type `{}`", tcx.item_path_str(def_id)).into(),
ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.def_path_str(def.did)).into(),
ty::Foreign(def_id) => format!("extern type `{}`", tcx.def_path_str(def_id)).into(),
ty::Array(_, n) => match n {
ty::LazyConst::Evaluated(n) => match n.assert_usize(tcx) {
Some(n) => format!("array of {} elements", n).into(),
@ -185,7 +190,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
let tymut_string = tymut.to_string();
if tymut_string == "_" || //unknown type name,
tymut_string.len() > 10 || //name longer than saying "reference",
region.to_string() != "" //... or a complex type
region.to_string() != "'_" //... or a complex type
{
format!("{}reference", match mutbl {
hir::Mutability::MutMutable => "mutable ",
@ -199,7 +204,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
ty::FnPtr(_) => "fn pointer".into(),
ty::Dynamic(ref inner, ..) => {
if let Some(principal) = inner.principal() {
format!("trait {}", tcx.item_path_str(principal.def_id())).into()
format!("trait {}", tcx.def_path_str(principal.def_id())).into()
} else {
"trait".into()
}

View file

@ -1,10 +1,11 @@
use crate::hir::Unsafety;
use crate::hir::def::Namespace;
use crate::hir::def_id::DefId;
use crate::ty::{self, Ty, PolyFnSig, TypeFoldable, SubstsRef, TyCtxt};
use crate::ty::print::{FmtPrinter, Printer};
use crate::traits;
use rustc_target::spec::abi::Abi;
use rustc_macros::HashStable;
use crate::util::ppaux;
use std::fmt;
use std::iter;
@ -175,7 +176,13 @@ impl<'tcx> InstanceDef<'tcx> {
impl<'tcx> fmt::Display for Instance<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
ppaux::parameterized(f, self.substs, self.def_id(), &[])?;
ty::tls::with(|tcx| {
let substs = tcx.lift(&self.substs).expect("could not lift for printing");
FmtPrinter::new(tcx, &mut *f, Namespace::ValueNS)
.print_def_path(self.def_id(), substs)?;
Ok(())
})?;
match self.def {
InstanceDef::Item(_) => Ok(()),
InstanceDef::VtableShim(_) => {

View file

@ -1,573 +0,0 @@
use crate::hir::map::DefPathData;
use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use crate::ty::{self, DefIdTree, Ty, TyCtxt};
use crate::middle::cstore::{ExternCrate, ExternCrateSource};
use syntax::ast;
use syntax::symbol::{keywords, LocalInternedString, Symbol};
use std::cell::Cell;
use std::fmt::Debug;
thread_local! {
static FORCE_ABSOLUTE: Cell<bool> = Cell::new(false);
static FORCE_IMPL_FILENAME_LINE: Cell<bool> = Cell::new(false);
static SHOULD_PREFIX_WITH_CRATE: Cell<bool> = Cell::new(false);
}
/// Enforces that item_path_str always returns an absolute path and
/// also enables "type-based" impl paths. This is used when building
/// symbols that contain types, where we want the crate name to be
/// part of the symbol.
pub fn with_forced_absolute_paths<F: FnOnce() -> R, R>(f: F) -> R {
FORCE_ABSOLUTE.with(|force| {
let old = force.get();
force.set(true);
let result = f();
force.set(old);
result
})
}
/// Force us to name impls with just the filename/line number. We
/// normally try to use types. But at some points, notably while printing
/// cycle errors, this can result in extra or suboptimal error output,
/// so this variable disables that check.
pub fn with_forced_impl_filename_line<F: FnOnce() -> R, R>(f: F) -> R {
FORCE_IMPL_FILENAME_LINE.with(|force| {
let old = force.get();
force.set(true);
let result = f();
force.set(old);
result
})
}
/// Adds the `crate::` prefix to paths where appropriate.
pub fn with_crate_prefix<F: FnOnce() -> R, R>(f: F) -> R {
SHOULD_PREFIX_WITH_CRATE.with(|flag| {
let old = flag.get();
flag.set(true);
let result = f();
flag.set(old);
result
})
}
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// Returns a string identifying this `DefId`. This string is
/// suitable for user output. It is relative to the current crate
/// root, unless with_forced_absolute_paths was used.
pub fn item_path_str(self, def_id: DefId) -> String {
let mode = FORCE_ABSOLUTE.with(|force| {
if force.get() {
RootMode::Absolute
} else {
RootMode::Local
}
});
let mut buffer = LocalPathBuffer::new(mode);
debug!("item_path_str: buffer={:?} def_id={:?}", buffer, def_id);
self.push_item_path(&mut buffer, def_id, false);
buffer.into_string()
}
/// Returns a string identifying this local node-id.
pub fn node_path_str(self, id: ast::NodeId) -> String {
self.item_path_str(self.hir().local_def_id(id))
}
/// Returns a string identifying this def-id. This string is
/// suitable for user output. It always begins with a crate identifier.
pub fn absolute_item_path_str(self, def_id: DefId) -> String {
let mut buffer = LocalPathBuffer::new(RootMode::Absolute);
debug!("absolute_item_path_str: buffer={:?} def_id={:?}", buffer, def_id);
self.push_item_path(&mut buffer, def_id, false);
buffer.into_string()
}
/// Returns the "path" to a particular crate. This can proceed in
/// various ways, depending on the `root_mode` of the `buffer`.
/// (See `RootMode` enum for more details.)
///
/// `pushed_prelude_crate` argument should be `true` when the buffer
/// has had a prelude crate pushed to it. If this is the case, then
/// we do not want to prepend `crate::` (as that would not be a valid
/// path).
pub fn push_krate_path<T>(self, buffer: &mut T, cnum: CrateNum, pushed_prelude_crate: bool)
where T: ItemPathBuffer + Debug
{
debug!(
"push_krate_path: buffer={:?} cnum={:?} LOCAL_CRATE={:?}",
buffer, cnum, LOCAL_CRATE
);
match *buffer.root_mode() {
RootMode::Local => {
// In local mode, when we encounter a crate other than
// LOCAL_CRATE, execution proceeds in one of two ways:
//
// 1. for a direct dependency, where user added an
// `extern crate` manually, we put the `extern
// crate` as the parent. So you wind up with
// something relative to the current crate.
// 2. for an extern inferred from a path or an indirect crate,
// where there is no explicit `extern crate`, we just prepend
// the crate name.
//
// Returns `None` for the local crate.
if cnum != LOCAL_CRATE {
let opt_extern_crate = self.extern_crate(cnum.as_def_id());
if let Some(ExternCrate {
src: ExternCrateSource::Extern(def_id),
direct: true,
..
}) = *opt_extern_crate
{
debug!("push_krate_path: def_id={:?}", def_id);
self.push_item_path(buffer, def_id, pushed_prelude_crate);
} else {
let name = self.crate_name(cnum).as_str();
debug!("push_krate_path: name={:?}", name);
buffer.push(&name);
}
} else if self.sess.rust_2018() && !pushed_prelude_crate {
SHOULD_PREFIX_WITH_CRATE.with(|flag| {
// We only add the `crate::` keyword where appropriate. In particular,
// when we've not previously pushed a prelude crate to this path.
if flag.get() {
buffer.push(&keywords::Crate.name().as_str())
}
})
}
}
RootMode::Absolute => {
// In absolute mode, just write the crate name
// unconditionally.
let name = self.original_crate_name(cnum).as_str();
debug!("push_krate_path: original_name={:?}", name);
buffer.push(&name);
}
}
}
/// If possible, this pushes a global path resolving to `external_def_id` that is visible
/// from at least one local module and returns true. If the crate defining `external_def_id` is
/// declared with an `extern crate`, the path is guaranteed to use the `extern crate`.
pub fn try_push_visible_item_path<T>(
self,
buffer: &mut T,
external_def_id: DefId,
pushed_prelude_crate: bool,
) -> bool
where T: ItemPathBuffer + Debug
{
debug!(
"try_push_visible_item_path: buffer={:?} external_def_id={:?}",
buffer, external_def_id
);
let visible_parent_map = self.visible_parent_map(LOCAL_CRATE);
let (mut cur_def, mut cur_path) = (external_def_id, Vec::<LocalInternedString>::new());
loop {
debug!(
"try_push_visible_item_path: cur_def={:?} cur_path={:?} CRATE_DEF_INDEX={:?}",
cur_def, cur_path, CRATE_DEF_INDEX,
);
// If `cur_def` is a direct or injected extern crate, push the path to the crate
// followed by the path to the item within the crate and return.
if cur_def.index == CRATE_DEF_INDEX {
match *self.extern_crate(cur_def) {
Some(ExternCrate {
src: ExternCrateSource::Extern(def_id),
direct: true,
..
}) => {
debug!("try_push_visible_item_path: def_id={:?}", def_id);
self.push_item_path(buffer, def_id, pushed_prelude_crate);
cur_path.iter().rev().for_each(|segment| buffer.push(&segment));
return true;
}
None => {
buffer.push(&self.crate_name(cur_def.krate).as_str());
cur_path.iter().rev().for_each(|segment| buffer.push(&segment));
return true;
}
_ => {},
}
}
let mut cur_def_key = self.def_key(cur_def);
debug!("try_push_visible_item_path: cur_def_key={:?}", cur_def_key);
// For a UnitStruct or TupleStruct we want the name of its parent rather than <unnamed>.
if let DefPathData::StructCtor = cur_def_key.disambiguated_data.data {
let parent = DefId {
krate: cur_def.krate,
index: cur_def_key.parent.expect("DefPathData::StructCtor missing a parent"),
};
cur_def_key = self.def_key(parent);
}
let visible_parent = visible_parent_map.get(&cur_def).cloned();
let actual_parent = self.parent(cur_def);
let data = cur_def_key.disambiguated_data.data;
debug!(
"try_push_visible_item_path: data={:?} visible_parent={:?} actual_parent={:?}",
data, visible_parent, actual_parent,
);
let symbol = match data {
// In order to output a path that could actually be imported (valid and visible),
// we need to handle re-exports correctly.
//
// For example, take `std::os::unix::process::CommandExt`, this trait is actually
// defined at `std::sys::unix::ext::process::CommandExt` (at time of writing).
//
// `std::os::unix` rexports the contents of `std::sys::unix::ext`. `std::sys` is
// private so the "true" path to `CommandExt` isn't accessible.
//
// In this case, the `visible_parent_map` will look something like this:
//
// (child) -> (parent)
// `std::sys::unix::ext::process::CommandExt` -> `std::sys::unix::ext::process`
// `std::sys::unix::ext::process` -> `std::sys::unix::ext`
// `std::sys::unix::ext` -> `std::os`
//
// This is correct, as the visible parent of `std::sys::unix::ext` is in fact
// `std::os`.
//
// When printing the path to `CommandExt` and looking at the `cur_def_key` that
// corresponds to `std::sys::unix::ext`, we would normally print `ext` and then go
// to the parent - resulting in a mangled path like
// `std::os::ext::process::CommandExt`.
//
// Instead, we must detect that there was a re-export and instead print `unix`
// (which is the name `std::sys::unix::ext` was re-exported as in `std::os`). To
// do this, we compare the parent of `std::sys::unix::ext` (`std::sys::unix`) with
// the visible parent (`std::os`). If these do not match, then we iterate over
// the children of the visible parent (as was done when computing
// `visible_parent_map`), looking for the specific child we currently have and then
// have access to the re-exported name.
DefPathData::Module(actual_name) |
DefPathData::TypeNs(actual_name) if visible_parent != actual_parent => {
visible_parent
.and_then(|parent| {
self.item_children(parent)
.iter()
.find(|child| child.def.def_id() == cur_def)
.map(|child| child.ident.as_str())
})
.unwrap_or_else(|| actual_name.as_str())
},
_ => {
data.get_opt_name().map(|n| n.as_str()).unwrap_or_else(|| {
// Re-exported `extern crate` (#43189).
if let DefPathData::CrateRoot = data {
self.original_crate_name(cur_def.krate).as_str()
} else {
Symbol::intern("<unnamed>").as_str()
}
})
},
};
debug!("try_push_visible_item_path: symbol={:?}", symbol);
cur_path.push(symbol);
match visible_parent {
Some(def) => cur_def = def,
None => return false,
};
}
}
pub fn push_item_path<T>(self, buffer: &mut T, def_id: DefId, pushed_prelude_crate: bool)
where T: ItemPathBuffer + Debug
{
debug!(
"push_item_path: buffer={:?} def_id={:?} pushed_prelude_crate={:?}",
buffer, def_id, pushed_prelude_crate
);
match *buffer.root_mode() {
RootMode::Local if !def_id.is_local() =>
if self.try_push_visible_item_path(buffer, def_id, pushed_prelude_crate) { return },
_ => {}
}
let key = self.def_key(def_id);
debug!("push_item_path: key={:?}", key);
match key.disambiguated_data.data {
DefPathData::CrateRoot => {
assert!(key.parent.is_none());
self.push_krate_path(buffer, def_id.krate, pushed_prelude_crate);
}
DefPathData::Impl => {
self.push_impl_path(buffer, def_id, pushed_prelude_crate);
}
// Unclear if there is any value in distinguishing these.
// Probably eventually (and maybe we would even want
// finer-grained distinctions, e.g., between enum/struct).
data @ DefPathData::Misc |
data @ DefPathData::TypeNs(..) |
data @ DefPathData::Trait(..) |
data @ DefPathData::TraitAlias(..) |
data @ DefPathData::AssocTypeInTrait(..) |
data @ DefPathData::AssocTypeInImpl(..) |
data @ DefPathData::AssocExistentialInImpl(..) |
data @ DefPathData::ValueNs(..) |
data @ DefPathData::Module(..) |
data @ DefPathData::TypeParam(..) |
data @ DefPathData::LifetimeParam(..) |
data @ DefPathData::ConstParam(..) |
data @ DefPathData::EnumVariant(..) |
data @ DefPathData::Field(..) |
data @ DefPathData::AnonConst |
data @ DefPathData::MacroDef(..) |
data @ DefPathData::ClosureExpr |
data @ DefPathData::ImplTrait |
data @ DefPathData::GlobalMetaData(..) => {
let parent_did = self.parent_def_id(def_id).unwrap();
// Keep track of whether we are one recursion away from the `CrateRoot` and
// pushing the name of a prelude crate. If we are, we'll want to know this when
// printing the `CrateRoot` so we don't prepend a `crate::` to paths.
let mut is_prelude_crate = false;
if let DefPathData::CrateRoot = self.def_key(parent_did).disambiguated_data.data {
if self.extern_prelude.contains_key(&data.as_interned_str().as_symbol()) {
is_prelude_crate = true;
}
}
self.push_item_path(
buffer, parent_did, pushed_prelude_crate || is_prelude_crate
);
buffer.push(&data.as_interned_str().as_symbol().as_str());
},
DefPathData::StructCtor => { // present `X` instead of `X::{{constructor}}`
let parent_def_id = self.parent_def_id(def_id).unwrap();
self.push_item_path(buffer, parent_def_id, pushed_prelude_crate);
}
}
}
fn push_impl_path<T>(
self,
buffer: &mut T,
impl_def_id: DefId,
pushed_prelude_crate: bool,
)
where T: ItemPathBuffer + Debug
{
debug!("push_impl_path: buffer={:?} impl_def_id={:?}", buffer, impl_def_id);
let parent_def_id = self.parent_def_id(impl_def_id).unwrap();
// Always use types for non-local impls, where types are always
// available, and filename/line-number is mostly uninteresting.
let use_types = !impl_def_id.is_local() || {
// Otherwise, use filename/line-number if forced.
let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get());
!force_no_types
};
if !use_types {
return self.push_impl_path_fallback(buffer, impl_def_id, pushed_prelude_crate);
}
// Decide whether to print the parent path for the impl.
// Logically, since impls are global, it's never needed, but
// users may find it useful. Currently, we omit the parent if
// the impl is either in the same module as the self-type or
// as the trait.
let self_ty = self.type_of(impl_def_id);
let in_self_mod = match characteristic_def_id_of_type(self_ty) {
None => false,
Some(ty_def_id) => self.parent_def_id(ty_def_id) == Some(parent_def_id),
};
let impl_trait_ref = self.impl_trait_ref(impl_def_id);
let in_trait_mod = match impl_trait_ref {
None => false,
Some(trait_ref) => self.parent_def_id(trait_ref.def_id) == Some(parent_def_id),
};
if !in_self_mod && !in_trait_mod {
// If the impl is not co-located with either self-type or
// trait-type, then fallback to a format that identifies
// the module more clearly.
self.push_item_path(buffer, parent_def_id, pushed_prelude_crate);
if let Some(trait_ref) = impl_trait_ref {
buffer.push(&format!("<impl {} for {}>", trait_ref, self_ty));
} else {
buffer.push(&format!("<impl {}>", self_ty));
}
return;
}
// Otherwise, try to give a good form that would be valid language
// syntax. Preferably using associated item notation.
if let Some(trait_ref) = impl_trait_ref {
// Trait impls.
buffer.push(&format!("<{} as {}>", self_ty, trait_ref));
return;
}
// Inherent impls. Try to print `Foo::bar` for an inherent
// impl on `Foo`, but fallback to `<Foo>::bar` if self-type is
// anything other than a simple path.
match self_ty.sty {
ty::Adt(adt_def, substs) => {
if substs.types().next().is_none() { // ignore regions
self.push_item_path(buffer, adt_def.did, pushed_prelude_crate);
} else {
buffer.push(&format!("<{}>", self_ty));
}
}
ty::Foreign(did) => self.push_item_path(buffer, did, pushed_prelude_crate),
ty::Bool |
ty::Char |
ty::Int(_) |
ty::Uint(_) |
ty::Float(_) |
ty::Str => {
buffer.push(&self_ty.to_string());
}
_ => {
buffer.push(&format!("<{}>", self_ty));
}
}
}
fn push_impl_path_fallback<T>(
self,
buffer: &mut T,
impl_def_id: DefId,
pushed_prelude_crate: bool,
)
where T: ItemPathBuffer + Debug
{
// If no type info is available, fall back to
// pretty printing some span information. This should
// only occur very early in the compiler pipeline.
let parent_def_id = self.parent_def_id(impl_def_id).unwrap();
self.push_item_path(buffer, parent_def_id, pushed_prelude_crate);
let hir_id = self.hir().as_local_hir_id(impl_def_id).unwrap();
let item = self.hir().expect_item_by_hir_id(hir_id);
let span_str = self.sess.source_map().span_to_string(item.span);
buffer.push(&format!("<impl at {}>", span_str));
}
/// Returns the `DefId` of `def_id`'s parent in the def tree. If
/// this returns `None`, then `def_id` represents a crate root or
/// inlined root.
pub fn parent_def_id(self, def_id: DefId) -> Option<DefId> {
let key = self.def_key(def_id);
key.parent.map(|index| DefId { krate: def_id.krate, index: index })
}
}
/// As a heuristic, when we see an impl, if we see that the
/// 'self type' is a type defined in the same module as the impl,
/// we can omit including the path to the impl itself. This
/// function tries to find a "characteristic `DefId`" for a
/// type. It's just a heuristic so it makes some questionable
/// decisions and we may want to adjust it later.
pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
match ty.sty {
ty::Adt(adt_def, _) => Some(adt_def.did),
ty::Dynamic(data, ..) => data.principal_def_id(),
ty::Array(subty, _) |
ty::Slice(subty) => characteristic_def_id_of_type(subty),
ty::RawPtr(mt) => characteristic_def_id_of_type(mt.ty),
ty::Ref(_, ty, _) => characteristic_def_id_of_type(ty),
ty::Tuple(ref tys) => tys.iter()
.filter_map(|ty| characteristic_def_id_of_type(ty))
.next(),
ty::FnDef(def_id, _) |
ty::Closure(def_id, _) |
ty::Generator(def_id, _, _) |
ty::Foreign(def_id) => Some(def_id),
ty::Bool |
ty::Char |
ty::Int(_) |
ty::Uint(_) |
ty::Str |
ty::FnPtr(_) |
ty::Projection(_) |
ty::Placeholder(..) |
ty::UnnormalizedProjection(..) |
ty::Param(_) |
ty::Opaque(..) |
ty::Infer(_) |
ty::Bound(..) |
ty::Error |
ty::GeneratorWitness(..) |
ty::Never |
ty::Float(_) => None,
}
}
/// Unifying Trait for different kinds of item paths we might
/// construct. The basic interface is that components get pushed: the
/// instance can also customize how we handle the root of a crate.
pub trait ItemPathBuffer {
fn root_mode(&self) -> &RootMode;
fn push(&mut self, text: &str);
}
#[derive(Debug)]
pub enum RootMode {
/// Try to make a path relative to the local crate. In
/// particular, local paths have no prefix, and if the path comes
/// from an extern crate, start with the path to the `extern
/// crate` declaration.
Local,
/// Always prepend the crate name to the path, forming an absolute
/// path from within a given set of crates.
Absolute,
}
#[derive(Debug)]
struct LocalPathBuffer {
root_mode: RootMode,
str: String,
}
impl LocalPathBuffer {
fn new(root_mode: RootMode) -> LocalPathBuffer {
LocalPathBuffer {
root_mode,
str: String::new(),
}
}
fn into_string(self) -> String {
self.str
}
}
impl ItemPathBuffer for LocalPathBuffer {
fn root_mode(&self) -> &RootMode {
&self.root_mode
}
fn push(&mut self, text: &str) {
if !self.str.is_empty() {
self.str.push_str("::");
}
self.str.push_str(text);
}
}

View file

@ -95,10 +95,10 @@ mod erase_regions;
pub mod fast_reject;
pub mod fold;
pub mod inhabitedness;
pub mod item_path;
pub mod layout;
pub mod _match;
pub mod outlives;
pub mod print;
pub mod query;
pub mod relate;
pub mod steal;
@ -1000,7 +1000,7 @@ impl<'a, 'gcx, 'tcx> Generics {
}
/// Bounds on generics.
#[derive(Clone, Default, HashStable)]
#[derive(Clone, Default, Debug, HashStable)]
pub struct GenericPredicates<'tcx> {
pub parent: Option<DefId>,
pub predicates: Vec<(Predicate<'tcx>, Span)>,
@ -1505,7 +1505,7 @@ impl<'tcx> Predicate<'tcx> {
/// `[[], [U:Bar<T>]]`. Now if there were some particular reference
/// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
/// [usize:Bar<isize>]]`.
#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct InstantiatedPredicates<'tcx> {
pub predicates: Vec<Predicate<'tcx>>,
}
@ -2055,7 +2055,7 @@ impl ReprOptions {
}
// This is here instead of layout because the choice must make it into metadata.
if !tcx.consider_optimizing(|| format!("Reorder fields of {:?}", tcx.item_path_str(did))) {
if !tcx.consider_optimizing(|| format!("Reorder fields of {:?}", tcx.def_path_str(did))) {
flags.insert(ReprFlags::IS_LINEAR);
}
ReprOptions { int: size, align: max_align, pack: min_pack, flags: flags }
@ -2892,14 +2892,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
pub fn expect_variant_def(self, def: Def) -> &'tcx VariantDef {
match def {
Def::Variant(did) | Def::VariantCtor(did, ..) => {
let enum_did = self.parent_def_id(did).unwrap();
let enum_did = self.parent(did).unwrap();
self.adt_def(enum_did).variant_with_id(did)
}
Def::Struct(did) | Def::Union(did) => {
self.adt_def(did).non_enum_variant()
}
Def::StructCtor(ctor_did, ..) => {
let did = self.parent_def_id(ctor_did).expect("struct ctor has no parent");
let did = self.parent(ctor_did).expect("struct ctor has no parent");
self.adt_def(did).non_enum_variant()
}
_ => bug!("expect_variant_def used with unexpected def {:?}", def)

View file

@ -0,0 +1,327 @@
use crate::hir::map::{DefPathData, DisambiguatedDefPathData};
use crate::hir::def_id::{CrateNum, DefId};
use crate::ty::{self, DefIdTree, Ty, TyCtxt};
use crate::ty::subst::{Kind, Subst};
use rustc_data_structures::fx::FxHashSet;
// `pretty` is a separate module only for organization.
mod pretty;
pub use self::pretty::*;
pub trait Print<'gcx, 'tcx, P> {
type Output;
type Error;
fn print(&self, cx: P) -> Result<Self::Output, Self::Error>;
}
/// Interface for outputting user-facing "type-system entities"
/// (paths, types, lifetimes, constants, etc.) as a side-effect
/// (e.g. formatting, like `PrettyPrinter` implementors do) or by
/// constructing some alternative representation (e.g. an AST),
/// which the associated types allow passing through the methods.
///
/// For pretty-printing/formatting in particular, see `PrettyPrinter`.
// FIXME(eddyb) find a better name, this is more general than "printing".
pub trait Printer<'gcx: 'tcx, 'tcx>: Sized {
type Error;
type Path;
type Region;
type Type;
type DynExistential;
fn tcx(&'a self) -> TyCtxt<'a, 'gcx, 'tcx>;
fn print_def_path(
self,
def_id: DefId,
substs: &'tcx [Kind<'tcx>],
) -> Result<Self::Path, Self::Error> {
self.default_print_def_path(def_id, substs)
}
fn print_impl_path(
self,
impl_def_id: DefId,
substs: &'tcx [Kind<'tcx>],
self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> {
self.default_print_impl_path(impl_def_id, substs, self_ty, trait_ref)
}
fn print_region(
self,
region: ty::Region<'_>,
) -> Result<Self::Region, Self::Error>;
fn print_type(
self,
ty: Ty<'tcx>,
) -> Result<Self::Type, Self::Error>;
fn print_dyn_existential(
self,
predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
) -> Result<Self::DynExistential, Self::Error>;
fn path_crate(
self,
cnum: CrateNum,
) -> Result<Self::Path, Self::Error>;
fn path_qualified(
self,
self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error>;
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>;
fn path_append(
self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
disambiguated_data: &DisambiguatedDefPathData,
) -> Result<Self::Path, Self::Error>;
fn path_generic_args(
self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
args: &[Kind<'tcx>],
) -> Result<Self::Path, Self::Error>;
// Defaults (should not be overriden):
fn default_print_def_path(
self,
def_id: DefId,
substs: &'tcx [Kind<'tcx>],
) -> Result<Self::Path, Self::Error> {
debug!("default_print_def_path: def_id={:?}, substs={:?}", def_id, substs);
let key = self.tcx().def_key(def_id);
debug!("default_print_def_path: key={:?}", key);
match key.disambiguated_data.data {
DefPathData::CrateRoot => {
assert!(key.parent.is_none());
self.path_crate(def_id.krate)
}
DefPathData::Impl => {
let generics = self.tcx().generics_of(def_id);
let mut self_ty = self.tcx().type_of(def_id);
let mut impl_trait_ref = self.tcx().impl_trait_ref(def_id);
if substs.len() >= generics.count() {
self_ty = self_ty.subst(self.tcx(), substs);
impl_trait_ref = impl_trait_ref.subst(self.tcx(), substs);
}
self.print_impl_path(def_id, substs, self_ty, impl_trait_ref)
}
_ => {
let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id };
let mut parent_substs = substs;
let mut trait_qualify_parent = false;
if !substs.is_empty() {
let generics = self.tcx().generics_of(def_id);
parent_substs = &substs[..generics.parent_count.min(substs.len())];
match key.disambiguated_data.data {
// Closures' own generics are only captures, don't print them.
DefPathData::ClosureExpr => {}
// If we have any generic arguments to print, we do that
// on top of the same path, but without its own generics.
_ => if !generics.params.is_empty() && substs.len() >= generics.count() {
let args = self.generic_args_to_print(generics, substs);
return self.path_generic_args(
|cx| cx.print_def_path(def_id, parent_substs),
args,
);
}
}
// FIXME(eddyb) try to move this into the parent's printing
// logic, instead of doing it when printing the child.
trait_qualify_parent =
generics.has_self &&
generics.parent == Some(parent_def_id) &&
parent_substs.len() == generics.parent_count &&
self.tcx().generics_of(parent_def_id).parent_count == 0;
}
self.path_append(
|cx: Self| if trait_qualify_parent {
let trait_ref = ty::TraitRef::new(
parent_def_id,
cx.tcx().intern_substs(parent_substs),
);
cx.path_qualified(trait_ref.self_ty(), Some(trait_ref))
} else {
cx.print_def_path(parent_def_id, parent_substs)
},
&key.disambiguated_data,
)
}
}
}
fn generic_args_to_print(
&self,
generics: &'tcx ty::Generics,
substs: &'tcx [Kind<'tcx>],
) -> &'tcx [Kind<'tcx>] {
let mut own_params = generics.parent_count..generics.count();
// Don't print args for `Self` parameters (of traits).
if generics.has_self && own_params.start == 0 {
own_params.start = 1;
}
// Don't print args that are the defaults of their respective parameters.
own_params.end -= generics.params.iter().rev().take_while(|param| {
match param.kind {
ty::GenericParamDefKind::Lifetime => false,
ty::GenericParamDefKind::Type { has_default, .. } => {
has_default && substs[param.index as usize] == Kind::from(
self.tcx().type_of(param.def_id).subst(self.tcx(), substs)
)
}
ty::GenericParamDefKind::Const => false, // FIXME(const_generics:defaults)
}
}).count();
&substs[own_params]
}
fn default_print_impl_path(
self,
impl_def_id: DefId,
_substs: &'tcx [Kind<'tcx>],
self_ty: Ty<'tcx>,
impl_trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> {
debug!("default_print_impl_path: impl_def_id={:?}, self_ty={}, impl_trait_ref={:?}",
impl_def_id, self_ty, impl_trait_ref);
let key = self.tcx().def_key(impl_def_id);
let parent_def_id = DefId { index: key.parent.unwrap(), ..impl_def_id };
// Decide whether to print the parent path for the impl.
// Logically, since impls are global, it's never needed, but
// users may find it useful. Currently, we omit the parent if
// the impl is either in the same module as the self-type or
// as the trait.
let in_self_mod = match characteristic_def_id_of_type(self_ty) {
None => false,
Some(ty_def_id) => self.tcx().parent(ty_def_id) == Some(parent_def_id),
};
let in_trait_mod = match impl_trait_ref {
None => false,
Some(trait_ref) => self.tcx().parent(trait_ref.def_id) == Some(parent_def_id),
};
if !in_self_mod && !in_trait_mod {
// If the impl is not co-located with either self-type or
// trait-type, then fallback to a format that identifies
// the module more clearly.
self.path_append_impl(
|cx| cx.print_def_path(parent_def_id, &[]),
&key.disambiguated_data,
self_ty,
impl_trait_ref,
)
} else {
// Otherwise, try to give a good form that would be valid language
// syntax. Preferably using associated item notation.
self.path_qualified(self_ty, impl_trait_ref)
}
}
}
/// As a heuristic, when we see an impl, if we see that the
/// 'self type' is a type defined in the same module as the impl,
/// we can omit including the path to the impl itself. This
/// function tries to find a "characteristic `DefId`" for a
/// type. It's just a heuristic so it makes some questionable
/// decisions and we may want to adjust it later.
pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
match ty.sty {
ty::Adt(adt_def, _) => Some(adt_def.did),
ty::Dynamic(data, ..) => data.principal_def_id(),
ty::Array(subty, _) |
ty::Slice(subty) => characteristic_def_id_of_type(subty),
ty::RawPtr(mt) => characteristic_def_id_of_type(mt.ty),
ty::Ref(_, ty, _) => characteristic_def_id_of_type(ty),
ty::Tuple(ref tys) => tys.iter()
.filter_map(|ty| characteristic_def_id_of_type(ty))
.next(),
ty::FnDef(def_id, _) |
ty::Closure(def_id, _) |
ty::Generator(def_id, _, _) |
ty::Foreign(def_id) => Some(def_id),
ty::Bool |
ty::Char |
ty::Int(_) |
ty::Uint(_) |
ty::Str |
ty::FnPtr(_) |
ty::Projection(_) |
ty::Placeholder(..) |
ty::UnnormalizedProjection(..) |
ty::Param(_) |
ty::Opaque(..) |
ty::Infer(_) |
ty::Bound(..) |
ty::Error |
ty::GeneratorWitness(..) |
ty::Never |
ty::Float(_) => None,
}
}
impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for ty::RegionKind {
type Output = P::Region;
type Error = P::Error;
fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
cx.print_region(self)
}
}
impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for ty::Region<'_> {
type Output = P::Region;
type Error = P::Error;
fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
cx.print_region(self)
}
}
impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for Ty<'tcx> {
type Output = P::Type;
type Error = P::Error;
fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
cx.print_type(self)
}
}
impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P>
for &'tcx ty::List<ty::ExistentialPredicate<'tcx>>
{
type Output = P::DynExistential;
type Error = P::Error;
fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
cx.print_dyn_existential(self)
}
}

File diff suppressed because it is too large Load diff

View file

@ -71,7 +71,7 @@ pub(super) trait QueryDescription<'tcx>: QueryAccessors<'tcx> {
impl<'tcx, M: QueryAccessors<'tcx, Key=DefId>> QueryDescription<'tcx> for M {
default fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
if !tcx.sess.verbose() {
format!("processing `{}`", tcx.item_path_str(def_id)).into()
format!("processing `{}`", tcx.def_path_str(def_id)).into()
} else {
let name = unsafe { ::std::intrinsics::type_name::<M>() };
format!("processing {:?} with query `{}`", def_id, name).into()
@ -301,7 +301,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::layout_raw<'tcx> {
impl<'tcx> QueryDescription<'tcx> for queries::super_predicates_of<'tcx> {
fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
format!("computing the supertraits of `{}`",
tcx.item_path_str(def_id)).into()
tcx.def_path_str(def_id)).into()
}
}
@ -322,7 +322,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::type_param_predicates<'tcx> {
impl<'tcx> QueryDescription<'tcx> for queries::coherent_trait<'tcx> {
fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
format!("coherence checking all impls of trait `{}`",
tcx.item_path_str(def_id)).into()
tcx.def_path_str(def_id)).into()
}
}
@ -359,7 +359,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::inferred_outlives_crate<'tcx> {
impl<'tcx> QueryDescription<'tcx> for queries::mir_shims<'tcx> {
fn describe(tcx: TyCtxt<'_, '_, '_>, def: ty::InstanceDef<'tcx>) -> Cow<'static, str> {
format!("generating MIR shim for `{}`",
tcx.item_path_str(def.def_id())).into()
tcx.def_path_str(def.def_id())).into()
}
}
@ -394,7 +394,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_eval<'tcx> {
) -> Cow<'static, str> {
format!(
"const-evaluating + checking `{}`",
tcx.item_path_str(key.value.instance.def.def_id()),
tcx.def_path_str(key.value.instance.def.def_id()),
).into()
}
@ -415,7 +415,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_eval_raw<'tcx> {
fn describe(tcx: TyCtxt<'_, '_, '_>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
-> Cow<'static, str>
{
format!("const-evaluating `{}`", tcx.item_path_str(key.value.instance.def.def_id())).into()
format!("const-evaluating `{}`", tcx.def_path_str(key.value.instance.def.def_id())).into()
}
#[inline]
@ -513,7 +513,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::trait_of_item<'tcx> {
impl<'tcx> QueryDescription<'tcx> for queries::const_is_rvalue_promotable_to_static<'tcx> {
fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
format!("const checking if rvalue is promotable to static `{}`",
tcx.item_path_str(def_id)).into()
tcx.def_path_str(def_id)).into()
}
#[inline]
@ -532,21 +532,21 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_is_rvalue_promotable_to_sta
impl<'tcx> QueryDescription<'tcx> for queries::rvalue_promotable_map<'tcx> {
fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
format!("checking which parts of `{}` are promotable to static",
tcx.item_path_str(def_id)).into()
tcx.def_path_str(def_id)).into()
}
}
impl<'tcx> QueryDescription<'tcx> for queries::is_mir_available<'tcx> {
fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
format!("checking if item is mir available: `{}`",
tcx.item_path_str(def_id)).into()
tcx.def_path_str(def_id)).into()
}
}
impl<'tcx> QueryDescription<'tcx> for queries::codegen_fulfill_obligation<'tcx> {
fn describe(tcx: TyCtxt<'_, '_, '_>,
key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)) -> Cow<'static, str> {
format!("checking if `{}` fulfills its obligations", tcx.item_path_str(key.1.def_id()))
format!("checking if `{}` fulfills its obligations", tcx.def_path_str(key.1.def_id()))
.into()
}
@ -565,19 +565,19 @@ impl<'tcx> QueryDescription<'tcx> for queries::codegen_fulfill_obligation<'tcx>
impl<'tcx> QueryDescription<'tcx> for queries::trait_impls_of<'tcx> {
fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
format!("trait impls of `{}`", tcx.item_path_str(def_id)).into()
format!("trait impls of `{}`", tcx.def_path_str(def_id)).into()
}
}
impl<'tcx> QueryDescription<'tcx> for queries::is_object_safe<'tcx> {
fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
format!("determine object safety of trait `{}`", tcx.item_path_str(def_id)).into()
format!("determine object safety of trait `{}`", tcx.def_path_str(def_id)).into()
}
}
impl<'tcx> QueryDescription<'tcx> for queries::is_const_fn_raw<'tcx> {
fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
format!("checking if item is const fn: `{}`", tcx.item_path_str(def_id)).into()
format!("checking if item is const fn: `{}`", tcx.def_path_str(def_id)).into()
}
}
@ -883,7 +883,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::output_filenames<'tcx> {
impl<'tcx> QueryDescription<'tcx> for queries::vtable_methods<'tcx> {
fn describe(tcx: TyCtxt<'_, '_, '_>, key: ty::PolyTraitRef<'tcx> ) -> Cow<'static, str> {
format!("finding all methods for trait {}", tcx.item_path_str(key.def_id())).into()
format!("finding all methods for trait {}", tcx.def_path_str(key.def_id())).into()
}
}
@ -927,7 +927,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::optimized_mir<'tcx> {
impl<'tcx> QueryDescription<'tcx> for queries::substitute_normalize_and_test_predicates<'tcx> {
fn describe(tcx: TyCtxt<'_, '_, '_>, key: (DefId, SubstsRef<'tcx>)) -> Cow<'static, str> {
format!("testing substituted normalized predicates:`{}`", tcx.item_path_str(key.0)).into()
format!("testing substituted normalized predicates:`{}`", tcx.def_path_str(key.0)).into()
}
}
@ -945,7 +945,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::target_features_whitelist<'tcx> {
impl<'tcx> QueryDescription<'tcx> for queries::instance_def_size_estimate<'tcx> {
fn describe(tcx: TyCtxt<'_, '_, '_>, def: ty::InstanceDef<'tcx>) -> Cow<'static, str> {
format!("estimating size for `{}`", tcx.item_path_str(def.def_id())).into()
format!("estimating size for `{}`", tcx.def_path_str(def.def_id())).into()
}
}

View file

@ -4,11 +4,10 @@
use crate::dep_graph::{DepNodeIndex, DepNode, DepKind, SerializedDepNodeIndex};
use crate::ty::tls;
use crate::ty::{TyCtxt};
use crate::ty::{self, TyCtxt};
use crate::ty::query::Query;
use crate::ty::query::config::{QueryConfig, QueryDescription};
use crate::ty::query::job::{QueryJob, QueryResult, QueryInfo};
use crate::ty::item_path;
use crate::util::common::{profq_msg, ProfileQueriesMsg, QueryMsg};
@ -299,7 +298,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
// sometimes cycles itself, leading to extra cycle errors.
// (And cycle errors around impls tend to occur during the
// collect/coherence phases anyhow.)
item_path::with_forced_impl_filename_line(|| {
ty::print::with_forced_impl_filename_line(|| {
let span = fix_span(stack[1 % stack.len()].span, &stack[0].query);
let mut err = struct_span_err!(self.sess,
span,

View file

@ -351,10 +351,8 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
{
let tcx = relation.tcx();
let a_sty = &a.sty;
let b_sty = &b.sty;
debug!("super_relate_tys: a_sty={:?} b_sty={:?}", a_sty, b_sty);
match (a_sty, b_sty) {
debug!("super_relate_tys: a={:?} b={:?}", a, b);
match (&a.sty, &b.sty) {
(&ty::Infer(_), _) |
(_, &ty::Infer(_)) =>
{

View file

@ -3,17 +3,288 @@
//! hand, though we've recently added some macros (e.g.,
//! `BraceStructLiftImpl!`) to help with the tedium.
use crate::hir::def::Namespace;
use crate::mir::ProjectionKind;
use crate::mir::interpret::ConstValue;
use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid, InferConst};
use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use crate::ty::print::{FmtPrinter, Printer};
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
use smallvec::SmallVec;
use crate::mir::interpret;
use std::fmt;
use std::marker::PhantomData;
use std::rc::Rc;
impl fmt::Debug for ty::GenericParamDef {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let type_name = match self.kind {
ty::GenericParamDefKind::Lifetime => "Lifetime",
ty::GenericParamDefKind::Type {..} => "Type",
ty::GenericParamDefKind::Const => "Const",
};
write!(f, "{}({}, {:?}, {})",
type_name,
self.name,
self.def_id,
self.index)
}
}
impl fmt::Debug for ty::TraitDef {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
ty::tls::with(|tcx| {
FmtPrinter::new(tcx, f, Namespace::TypeNS)
.print_def_path(self.def_id, &[])?;
Ok(())
})
}
}
impl fmt::Debug for ty::AdtDef {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
ty::tls::with(|tcx| {
FmtPrinter::new(tcx, f, Namespace::TypeNS)
.print_def_path(self.did, &[])?;
Ok(())
})
}
}
impl fmt::Debug for ty::ClosureUpvar<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "ClosureUpvar({:?},{:?})",
self.def,
self.ty)
}
}
impl fmt::Debug for ty::UpvarId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let name = ty::tls::with(|tcx| {
tcx.hir().name_by_hir_id(self.var_path.hir_id)
});
write!(f, "UpvarId({:?};`{}`;{:?})",
self.var_path.hir_id,
name,
self.closure_expr_id)
}
}
impl fmt::Debug for ty::UpvarBorrow<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "UpvarBorrow({:?}, {:?})",
self.kind, self.region)
}
}
impl fmt::Debug for ty::ExistentialTraitRef<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}
impl fmt::Debug for ty::adjustment::Adjustment<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?} -> {}", self.kind, self.target)
}
}
impl fmt::Debug for ty::BoundRegion {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
ty::BrAnon(n) => write!(f, "BrAnon({:?})", n),
ty::BrFresh(n) => write!(f, "BrFresh({:?})", n),
ty::BrNamed(did, name) => {
write!(f, "BrNamed({:?}:{:?}, {})",
did.krate, did.index, name)
}
ty::BrEnv => write!(f, "BrEnv"),
}
}
}
impl fmt::Debug for ty::RegionKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
ty::ReEarlyBound(ref data) => {
write!(f, "ReEarlyBound({}, {})",
data.index,
data.name)
}
ty::ReClosureBound(ref vid) => {
write!(f, "ReClosureBound({:?})", vid)
}
ty::ReLateBound(binder_id, ref bound_region) => {
write!(f, "ReLateBound({:?}, {:?})", binder_id, bound_region)
}
ty::ReFree(ref fr) => fr.fmt(f),
ty::ReScope(id) => write!(f, "ReScope({:?})", id),
ty::ReStatic => write!(f, "ReStatic"),
ty::ReVar(ref vid) => vid.fmt(f),
ty::RePlaceholder(placeholder) => {
write!(f, "RePlaceholder({:?})", placeholder)
}
ty::ReEmpty => write!(f, "ReEmpty"),
ty::ReErased => write!(f, "ReErased"),
}
}
}
impl fmt::Debug for ty::FreeRegion {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "ReFree({:?}, {:?})", self.scope, self.bound_region)
}
}
impl fmt::Debug for ty::Variance {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match *self {
ty::Covariant => "+",
ty::Contravariant => "-",
ty::Invariant => "o",
ty::Bivariant => "*",
})
}
}
impl fmt::Debug for ty::FnSig<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "({:?}; c_variadic: {})->{:?}",
self.inputs(), self.c_variadic, self.output())
}
}
impl fmt::Debug for ty::TyVid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "_#{}t", self.index)
}
}
impl<'tcx> fmt::Debug for ty::ConstVid<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "_#{}c", self.index)
}
}
impl fmt::Debug for ty::IntVid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "_#{}i", self.index)
}
}
impl fmt::Debug for ty::FloatVid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "_#{}f", self.index)
}
}
impl fmt::Debug for ty::RegionVid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "'_#{}r", self.index())
}
}
impl fmt::Debug for ty::InferTy {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
ty::TyVar(ref v) => v.fmt(f),
ty::IntVar(ref v) => v.fmt(f),
ty::FloatVar(ref v) => v.fmt(f),
ty::FreshTy(v) => write!(f, "FreshTy({:?})", v),
ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v),
ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v),
}
}
}
impl fmt::Debug for ty::IntVarValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
ty::IntType(ref v) => v.fmt(f),
ty::UintType(ref v) => v.fmt(f),
}
}
}
impl fmt::Debug for ty::FloatVarValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl fmt::Debug for ty::TraitRef<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// FIXME(#59188) this is used across the compiler to print
// a `TraitRef` qualified (with the Self type explicit),
// instead of having a different way to make that choice.
write!(f, "<{} as {}>", self.self_ty(), self)
}
}
impl fmt::Debug for Ty<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}
impl fmt::Debug for ty::ParamTy {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}/#{}", self.name, self.idx)
}
}
impl fmt::Debug for ty::ParamConst {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}/#{}", self.name, self.index)
}
}
impl fmt::Debug for ty::TraitPredicate<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "TraitPredicate({:?})", self.trait_ref)
}
}
impl fmt::Debug for ty::ProjectionPredicate<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.ty)
}
}
impl fmt::Debug for ty::Predicate<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
ty::Predicate::Trait(ref a) => a.fmt(f),
ty::Predicate::Subtype(ref pair) => pair.fmt(f),
ty::Predicate::RegionOutlives(ref pair) => pair.fmt(f),
ty::Predicate::TypeOutlives(ref pair) => pair.fmt(f),
ty::Predicate::Projection(ref pair) => pair.fmt(f),
ty::Predicate::WellFormed(ty) => write!(f, "WellFormed({:?})", ty),
ty::Predicate::ObjectSafe(trait_def_id) => {
write!(f, "ObjectSafe({:?})", trait_def_id)
}
ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
write!(f, "ClosureKind({:?}, {:?}, {:?})",
closure_def_id, closure_substs, kind)
}
ty::Predicate::ConstEvaluatable(def_id, substs) => {
write!(f, "ConstEvaluatable({:?}, {:?})", def_id, substs)
}
}
}
}
///////////////////////////////////////////////////////////////////////////
// Atomic structs
//
@ -48,10 +319,14 @@ CloneTypeFoldableAndLiftImpls! {
// really meant to be folded. In general, we can only fold a fully
// general `Region`.
crate::ty::BoundRegion,
crate::ty::Placeholder<crate::ty::BoundRegion>,
crate::ty::ClosureKind,
crate::ty::FreeRegion,
crate::ty::InferTy,
crate::ty::IntVarValue,
crate::ty::ParamConst,
crate::ty::ParamTy,
crate::ty::RegionVid,
crate::ty::UniverseIndex,
crate::ty::Variance,
::syntax_pos::Span,
@ -60,6 +335,7 @@ CloneTypeFoldableAndLiftImpls! {
///////////////////////////////////////////////////////////////////////////
// Lift implementations
// FIXME(eddyb) replace all the uses of `Option::map` with `?`.
impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) {
type Lifted = (A::Lifted, B::Lifted);
fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
@ -156,6 +432,23 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialTraitRef<'a> {
}
}
impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialPredicate<'a> {
type Lifted = ty::ExistentialPredicate<'tcx>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
match self {
ty::ExistentialPredicate::Trait(x) => {
tcx.lift(x).map(ty::ExistentialPredicate::Trait)
}
ty::ExistentialPredicate::Projection(x) => {
tcx.lift(x).map(ty::ExistentialPredicate::Projection)
}
ty::ExistentialPredicate::AutoTrait(def_id) => {
Some(ty::ExistentialPredicate::AutoTrait(*def_id))
}
}
}
}
impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
type Lifted = ty::TraitPredicate<'tcx>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
@ -480,6 +773,13 @@ impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> {
}
}
BraceStructLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for ty::TypeAndMut<'a> {
type Lifted = ty::TypeAndMut<'tcx>;
ty, mutbl
}
}
BraceStructLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for ty::Instance<'a> {
type Lifted = ty::Instance<'tcx>;

View file

@ -9,7 +9,7 @@ use polonius_engine::Atom;
use rustc_data_structures::indexed_vec::Idx;
use rustc_macros::HashStable;
use crate::ty::subst::{InternalSubsts, Subst, SubstsRef, Kind, UnpackedKind};
use crate::ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable};
use crate::ty::{self, AdtDef, DefIdTree, TypeFlags, Ty, TyCtxt, TypeFoldable};
use crate::ty::{List, TyS, ParamEnvAnd, ParamEnv};
use crate::util::captures::Captures;
use crate::mir::interpret::{Scalar, Pointer};
@ -84,7 +84,7 @@ impl BoundRegion {
/// N.B., if you change this, you'll probably want to change the corresponding
/// AST structure in `libsyntax/ast.rs` as well.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug,
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
RustcEncodable, RustcDecodable, HashStable)]
pub enum TyKind<'tcx> {
/// The primitive boolean type. Written as `bool`.
@ -383,9 +383,10 @@ impl<'tcx> ClosureSubsts<'tcx> {
///
/// If you have an inference context, use `infcx.closure_sig()`.
pub fn closure_sig(self, def_id: DefId, tcx: TyCtxt<'_, 'tcx, 'tcx>) -> ty::PolyFnSig<'tcx> {
match self.closure_sig_ty(def_id, tcx).sty {
let ty = self.closure_sig_ty(def_id, tcx);
match ty.sty {
ty::FnPtr(sig) => sig,
ref t => bug!("closure_sig_ty is not a fn-ptr: {:?}", t),
_ => bug!("closure_sig_ty is not a fn-ptr: {:?}", ty),
}
}
}
@ -1590,7 +1591,7 @@ impl RegionKind {
pub fn free_region_binding_scope(&self, tcx: TyCtxt<'_, '_, '_>) -> DefId {
match self {
ty::ReEarlyBound(br) => {
tcx.parent_def_id(br.def_id).unwrap()
tcx.parent(br.def_id).unwrap()
}
ty::ReFree(fr) => fr.scope,
_ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self),

View file

@ -12,8 +12,8 @@ use smallvec::SmallVec;
use rustc_macros::HashStable;
use core::intrinsics;
use std::cmp::Ordering;
use std::fmt;
use std::cmp::Ordering;
use std::marker::PhantomData;
use std::mem;
use std::num::NonZeroUsize;
@ -70,6 +70,16 @@ impl<'tcx> UnpackedKind<'tcx> {
}
}
impl fmt::Debug for Kind<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.unpack() {
UnpackedKind::Lifetime(lt) => lt.fmt(f),
UnpackedKind::Type(ty) => ty.fmt(f),
UnpackedKind::Const(ct) => ct.fmt(f),
}
}
}
impl<'tcx> Ord for Kind<'tcx> {
fn cmp(&self, other: &Kind<'_>) -> Ordering {
self.unpack().cmp(&other.unpack())
@ -115,34 +125,14 @@ impl<'tcx> Kind<'tcx> {
}
}
impl<'tcx> fmt::Debug for Kind<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.unpack() {
UnpackedKind::Lifetime(lt) => write!(f, "{:?}", lt),
UnpackedKind::Type(ty) => write!(f, "{:?}", ty),
UnpackedKind::Const(ct) => write!(f, "{:?}", ct),
}
}
}
impl<'tcx> fmt::Display for Kind<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.unpack() {
UnpackedKind::Lifetime(lt) => write!(f, "{}", lt),
UnpackedKind::Type(ty) => write!(f, "{}", ty),
UnpackedKind::Const(ct) => write!(f, "{}", ct),
}
}
}
impl<'a, 'tcx> Lift<'tcx> for Kind<'a> {
type Lifted = Kind<'tcx>;
fn lift_to_tcx<'cx, 'gcx>(&self, tcx: TyCtxt<'cx, 'gcx, 'tcx>) -> Option<Self::Lifted> {
match self.unpack() {
UnpackedKind::Lifetime(lt) => lt.lift_to_tcx(tcx).map(|lt| lt.into()),
UnpackedKind::Type(ty) => ty.lift_to_tcx(tcx).map(|ty| ty.into()),
UnpackedKind::Const(ct) => ct.lift_to_tcx(tcx).map(|ct| ct.into()),
UnpackedKind::Lifetime(lt) => tcx.lift(&lt).map(|lt| lt.into()),
UnpackedKind::Type(ty) => tcx.lift(&ty).map(|ty| ty.into()),
UnpackedKind::Const(ct) => tcx.lift(&ct).map(|ct| ct.into()),
}
}
}

View file

@ -7,7 +7,7 @@ use crate::hir::{self, Node};
use crate::mir::interpret::{sign_extend, truncate};
use crate::ich::NodeIdHashingMode;
use crate::traits::{self, ObligationCause};
use crate::ty::{self, Ty, TyCtxt, GenericParamDefKind, TypeFoldable};
use crate::ty::{self, DefIdTree, Ty, TyCtxt, GenericParamDefKind, TypeFoldable};
use crate::ty::subst::{Subst, InternalSubsts, SubstsRef, UnpackedKind};
use crate::ty::query::TyCtxtAt;
use crate::ty::TyKind::*;
@ -563,7 +563,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
pub fn closure_base_def_id(self, def_id: DefId) -> DefId {
let mut def_id = def_id;
while self.is_closure(def_id) {
def_id = self.parent_def_id(def_id).unwrap_or_else(|| {
def_id = self.parent(def_id).unwrap_or_else(|| {
bug!("closure {:?} has no parent", def_id);
});
}

File diff suppressed because it is too large Load diff

View file

@ -1406,7 +1406,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
out.push('(');
self.append_loan_path_to_string(&lp_base, out);
out.push_str(DOWNCAST_PRINTED_OPERATOR);
out.push_str(&self.tcx.item_path_str(variant_def_id));
out.push_str(&self.tcx.def_path_str(variant_def_id));
out.push(')');
}
@ -1443,7 +1443,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
out.push('(');
self.append_autoderefd_loan_path_to_string(&lp_base, out);
out.push_str(DOWNCAST_PRINTED_OPERATOR);
out.push_str(&self.tcx.item_path_str(variant_def_id));
out.push_str(&self.tcx.def_path_str(variant_def_id));
out.push(')');
}
@ -1523,7 +1523,7 @@ impl<'tcx> fmt::Debug for LoanPath<'tcx> {
LpDowncast(ref lp, variant_def_id) => {
let variant_str = if variant_def_id.is_local() {
ty::tls::with(|tcx| tcx.item_path_str(variant_def_id))
ty::tls::with(|tcx| tcx.def_path_str(variant_def_id))
} else {
format!("{:?}", variant_def_id)
};
@ -1558,7 +1558,7 @@ impl<'tcx> fmt::Display for LoanPath<'tcx> {
LpDowncast(ref lp, variant_def_id) => {
let variant_str = if variant_def_id.is_local() {
ty::tls::with(|tcx| tcx.item_path_str(variant_def_id))
ty::tls::with(|tcx| tcx.def_path_str(variant_def_id))
} else {
format!("{:?}", variant_def_id)
};

View file

@ -513,8 +513,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
},
"fadd_fast" | "fsub_fast" | "fmul_fast" | "fdiv_fast" | "frem_fast" => {
let sty = &arg_tys[0].sty;
match float_type_width(sty) {
match float_type_width(arg_tys[0]) {
Some(_width) =>
match name {
"fadd_fast" => self.fadd_fast(args[0].immediate(), args[1].immediate()),
@ -528,7 +527,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
span_invalid_monomorphization_error(
tcx.sess, span,
&format!("invalid monomorphization of `{}` intrinsic: \
expected basic float type, found `{}`", name, sty));
expected basic float type, found `{}`", name, arg_tys[0]));
return;
}
}
@ -1473,8 +1472,8 @@ fn generic_simd_intrinsic(
require!(false, "expected element type `{}` of second argument `{}` \
to be a pointer to the element type `{}` of the first \
argument `{}`, found `{}` != `*_ {}`",
arg_tys[1].simd_type(tcx).sty, arg_tys[1], in_elem, in_ty,
arg_tys[1].simd_type(tcx).sty, in_elem);
arg_tys[1].simd_type(tcx), arg_tys[1], in_elem, in_ty,
arg_tys[1].simd_type(tcx), in_elem);
unreachable!();
}
};
@ -1488,7 +1487,7 @@ fn generic_simd_intrinsic(
_ => {
require!(false, "expected element type `{}` of third argument `{}` \
to be a signed integer type",
arg_tys[2].simd_type(tcx).sty, arg_tys[2]);
arg_tys[2].simd_type(tcx), arg_tys[2]);
}
}
@ -1573,8 +1572,8 @@ fn generic_simd_intrinsic(
require!(false, "expected element type `{}` of second argument `{}` \
to be a pointer to the element type `{}` of the first \
argument `{}`, found `{}` != `*mut {}`",
arg_tys[1].simd_type(tcx).sty, arg_tys[1], in_elem, in_ty,
arg_tys[1].simd_type(tcx).sty, in_elem);
arg_tys[1].simd_type(tcx), arg_tys[1], in_elem, in_ty,
arg_tys[1].simd_type(tcx), in_elem);
unreachable!();
}
};
@ -1588,7 +1587,7 @@ fn generic_simd_intrinsic(
_ => {
require!(false, "expected element type `{}` of third argument `{}` \
to be a signed integer type",
arg_tys[2].simd_type(tcx).sty, arg_tys[2]);
arg_tys[2].simd_type(tcx), arg_tys[2]);
}
}
@ -1904,7 +1903,7 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
return_error!(
"expected element type `{}` of vector type `{}` \
to be a signed or unsigned integer type",
arg_tys[0].simd_type(tcx).sty, arg_tys[0]
arg_tys[0].simd_type(tcx), arg_tys[0]
);
}
};
@ -1954,10 +1953,10 @@ fn int_type_width_signed(ty: Ty<'_>, cx: &CodegenCx<'_, '_>) -> Option<(u64, boo
}
}
// Returns the width of a float TypeVariant
// Returns the width of a float Ty
// Returns None if the type is not a float
fn float_type_width<'tcx>(sty: &ty::TyKind<'tcx>) -> Option<u64> {
match *sty {
fn float_type_width(ty: Ty<'_>) -> Option<u64> {
match ty.sty {
ty::Float(t) => Some(t.bit_width() as u64),
_ => None,
}

View file

@ -53,7 +53,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let field_ty = c.ty.builtin_index().unwrap();
let fields = match c.ty.sty {
ty::Array(_, n) => n.unwrap_usize(bx.tcx()),
ref other => bug!("invalid simd shuffle type: {}", other),
_ => bug!("invalid simd shuffle type: {}", c.ty),
};
let values: Vec<_> = (0..fields).map(|field| {
let field = const_field(

View file

@ -148,7 +148,7 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {
match tail.sty {
ty::Foreign(..) => false,
ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
_ => bug!("unexpected unsized tail: {:?}", tail.sty),
_ => bug!("unexpected unsized tail: {:?}", tail),
}
}
}

View file

@ -4,6 +4,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
#![feature(arbitrary_self_types)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(custom_attribute)]

View file

@ -87,14 +87,14 @@
//! virtually impossible. Thus, symbol hash generation exclusively relies on
//! DefPaths which are much more robust in the face of changes to the code base.
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc::hir::Node;
use rustc::hir::CodegenFnAttrFlags;
use rustc::hir::map::definitions::DefPathData;
use rustc::hir::map::{DefPathData, DisambiguatedDefPathData};
use rustc::ich::NodeIdHashingMode;
use rustc::ty::item_path::{self, ItemPathBuffer, RootMode};
use rustc::ty::print::{PrettyPrinter, Printer, Print};
use rustc::ty::query::Providers;
use rustc::ty::subst::SubstsRef;
use rustc::ty::subst::{Kind, SubstsRef, UnpackedKind};
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::util::common::record_time;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@ -105,8 +105,8 @@ use syntax_pos::symbol::Symbol;
use log::debug;
use std::fmt::Write;
use std::mem::discriminant;
use std::fmt::{self, Write};
use std::mem::{self, discriminant};
pub fn provide(providers: &mut Providers<'_>) {
*providers = Providers {
@ -223,11 +223,11 @@ fn get_symbol_hash<'a, 'tcx>(
}
fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName {
let mut buffer = SymbolPathBuffer::new(tcx);
item_path::with_forced_absolute_paths(|| {
tcx.push_item_path(&mut buffer, def_id, false);
});
buffer.into_interned()
SymbolPrinter {
tcx,
path: SymbolPath::new(),
keep_within_component: false,
}.print_def_path(def_id, &[]).unwrap().path.into_interned()
}
fn symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>) -> ty::SymbolName {
@ -319,13 +319,17 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
let hash = get_symbol_hash(tcx, def_id, instance, instance_ty, substs);
let mut buf = SymbolPathBuffer::from_interned(tcx.def_symbol_name(def_id), tcx);
let mut printer = SymbolPrinter {
tcx,
path: SymbolPath::from_interned(tcx.def_symbol_name(def_id)),
keep_within_component: false,
};
if instance.is_vtable_shim() {
buf.push("{{vtable-shim}}");
let _ = printer.write_str("{{vtable-shim}}");
}
buf.finish(hash)
printer.path.finish(hash)
}
// Follow C++ namespace-mangling style, see
@ -342,126 +346,312 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
// To be able to work on all platforms and get *some* reasonable output, we
// use C++ name-mangling.
#[derive(Debug)]
struct SymbolPathBuffer {
struct SymbolPath {
result: String,
temp_buf: String,
strict_naming: bool,
}
impl SymbolPathBuffer {
fn new(tcx: TyCtxt<'_, '_, '_>) -> Self {
let mut result = SymbolPathBuffer {
impl SymbolPath {
fn new() -> Self {
let mut result = SymbolPath {
result: String::with_capacity(64),
temp_buf: String::with_capacity(16),
strict_naming: tcx.has_strict_asm_symbol_naming(),
};
result.result.push_str("_ZN"); // _Z == Begin name-sequence, N == nested
result
}
fn from_interned(symbol: ty::SymbolName, tcx: TyCtxt<'_, '_, '_>) -> Self {
let mut result = SymbolPathBuffer {
fn from_interned(symbol: ty::SymbolName) -> Self {
let mut result = SymbolPath {
result: String::with_capacity(64),
temp_buf: String::with_capacity(16),
strict_naming: tcx.has_strict_asm_symbol_naming(),
};
result.result.push_str(&symbol.as_str());
result
}
fn into_interned(self) -> ty::SymbolName {
fn into_interned(mut self) -> ty::SymbolName {
self.finalize_pending_component();
ty::SymbolName {
name: Symbol::intern(&self.result).as_interned_str(),
}
}
fn finalize_pending_component(&mut self) {
if !self.temp_buf.is_empty() {
let _ = write!(self.result, "{}{}", self.temp_buf.len(), self.temp_buf);
self.temp_buf.clear();
}
}
fn finish(mut self, hash: u64) -> String {
self.finalize_pending_component();
// E = end name-sequence
let _ = write!(self.result, "17h{:016x}E", hash);
self.result
}
}
// Name sanitation. LLVM will happily accept identifiers with weird names, but
// gas doesn't!
// gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $
// NVPTX assembly has more strict naming rules than gas, so additionally, dots
// are replaced with '$' there.
fn sanitize_and_append(&mut self, s: &str) {
self.temp_buf.clear();
struct SymbolPrinter<'a, 'tcx> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
path: SymbolPath,
// When `true`, `finalize_pending_component` isn't used.
// This is needed when recursing into `path_qualified`,
// or `path_generic_args`, as any nested paths are
// logically within one component.
keep_within_component: bool,
}
// HACK(eddyb) this relies on using the `fmt` interface to get
// `PrettyPrinter` aka pretty printing of e.g. types in paths,
// symbol names should have their own printing machinery.
impl Printer<'tcx, 'tcx> for SymbolPrinter<'_, 'tcx> {
type Error = fmt::Error;
type Path = Self;
type Region = Self;
type Type = Self;
type DynExistential = Self;
fn tcx(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
self.tcx
}
fn print_region(
self,
_region: ty::Region<'_>,
) -> Result<Self::Region, Self::Error> {
Ok(self)
}
fn print_type(
self,
ty: Ty<'tcx>,
) -> Result<Self::Type, Self::Error> {
match ty.sty {
// Print all nominal types as paths (unlike `pretty_print_type`).
ty::FnDef(def_id, substs) |
ty::Opaque(def_id, substs) |
ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs }) |
ty::UnnormalizedProjection(ty::ProjectionTy { item_def_id: def_id, substs }) |
ty::Closure(def_id, ty::ClosureSubsts { substs }) |
ty::Generator(def_id, ty::GeneratorSubsts { substs }, _) => {
self.print_def_path(def_id, substs)
}
_ => self.pretty_print_type(ty),
}
}
fn print_dyn_existential(
mut self,
predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
) -> Result<Self::DynExistential, Self::Error> {
let mut first = false;
for p in predicates {
if !first {
write!(self, "+")?;
}
first = false;
self = p.print(self)?;
}
Ok(self)
}
fn path_crate(
mut self,
cnum: CrateNum,
) -> Result<Self::Path, Self::Error> {
self.write_str(&self.tcx.original_crate_name(cnum).as_str())?;
Ok(self)
}
fn path_qualified(
self,
self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> {
// Similar to `pretty_path_qualified`, but for the other
// types that are printed as paths (see `print_type` above).
match self_ty.sty {
ty::FnDef(..) |
ty::Opaque(..) |
ty::Projection(_) |
ty::UnnormalizedProjection(_) |
ty::Closure(..) |
ty::Generator(..)
if trait_ref.is_none() =>
{
self.print_type(self_ty)
}
_ => self.pretty_path_qualified(self_ty, trait_ref)
}
}
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> {
self.pretty_path_append_impl(
|mut cx| {
cx = print_prefix(cx)?;
if cx.keep_within_component {
// HACK(eddyb) print the path similarly to how `FmtPrinter` prints it.
cx.write_str("::")?;
} else {
cx.path.finalize_pending_component();
}
Ok(cx)
},
self_ty,
trait_ref,
)
}
fn path_append(
mut self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
disambiguated_data: &DisambiguatedDefPathData,
) -> Result<Self::Path, Self::Error> {
self = print_prefix(self)?;
// Skip `::{{constructor}}` on tuple/unit structs.
match disambiguated_data.data {
DefPathData::StructCtor => return Ok(self),
_ => {}
}
if self.keep_within_component {
// HACK(eddyb) print the path similarly to how `FmtPrinter` prints it.
self.write_str("::")?;
} else {
self.path.finalize_pending_component();
}
self.write_str(&disambiguated_data.data.as_interned_str().as_str())?;
Ok(self)
}
fn path_generic_args(
mut self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
args: &[Kind<'tcx>],
) -> Result<Self::Path, Self::Error> {
self = print_prefix(self)?;
let args = args.iter().cloned().filter(|arg| {
match arg.unpack() {
UnpackedKind::Lifetime(_) => false,
_ => true,
}
});
if args.clone().next().is_some() {
self.generic_delimiters(|cx| cx.comma_sep(args))
} else {
Ok(self)
}
}
}
impl PrettyPrinter<'tcx, 'tcx> for SymbolPrinter<'_, 'tcx> {
fn region_should_not_be_omitted(
&self,
_region: ty::Region<'_>,
) -> bool {
false
}
fn comma_sep<T>(
mut self,
mut elems: impl Iterator<Item = T>,
) -> Result<Self, Self::Error>
where T: Print<'tcx, 'tcx, Self, Output = Self, Error = Self::Error>
{
if let Some(first) = elems.next() {
self = first.print(self)?;
for elem in elems {
self.write_str(",")?;
self = elem.print(self)?;
}
}
Ok(self)
}
fn generic_delimiters(
mut self,
f: impl FnOnce(Self) -> Result<Self, Self::Error>,
) -> Result<Self, Self::Error> {
write!(self, "<")?;
let kept_within_component =
mem::replace(&mut self.keep_within_component, true);
self = f(self)?;
self.keep_within_component = kept_within_component;
write!(self, ">")?;
Ok(self)
}
}
impl fmt::Write for SymbolPrinter<'_, '_> {
fn write_str(&mut self, s: &str) -> fmt::Result {
// Name sanitation. LLVM will happily accept identifiers with weird names, but
// gas doesn't!
// gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $
// NVPTX assembly has more strict naming rules than gas, so additionally, dots
// are replaced with '$' there.
for c in s.chars() {
if self.path.temp_buf.is_empty() {
match c {
'a'..='z' | 'A'..='Z' | '_' => {}
_ => {
// Underscore-qualify anything that didn't start as an ident.
self.path.temp_buf.push('_');
}
}
}
match c {
// Escape these with $ sequences
'@' => self.temp_buf.push_str("$SP$"),
'*' => self.temp_buf.push_str("$BP$"),
'&' => self.temp_buf.push_str("$RF$"),
'<' => self.temp_buf.push_str("$LT$"),
'>' => self.temp_buf.push_str("$GT$"),
'(' => self.temp_buf.push_str("$LP$"),
')' => self.temp_buf.push_str("$RP$"),
',' => self.temp_buf.push_str("$C$"),
'@' => self.path.temp_buf.push_str("$SP$"),
'*' => self.path.temp_buf.push_str("$BP$"),
'&' => self.path.temp_buf.push_str("$RF$"),
'<' => self.path.temp_buf.push_str("$LT$"),
'>' => self.path.temp_buf.push_str("$GT$"),
'(' => self.path.temp_buf.push_str("$LP$"),
')' => self.path.temp_buf.push_str("$RP$"),
',' => self.path.temp_buf.push_str("$C$"),
'-' | ':' => if self.strict_naming {
'-' | ':' | '.' if self.tcx.has_strict_asm_symbol_naming() => {
// NVPTX doesn't support these characters in symbol names.
self.temp_buf.push('$')
self.path.temp_buf.push('$')
}
else {
// '.' doesn't occur in types and functions, so reuse it
// for ':' and '-'
self.temp_buf.push('.')
},
'.' => if self.strict_naming {
self.temp_buf.push('$')
}
else {
self.temp_buf.push('.')
},
// '.' doesn't occur in types and functions, so reuse it
// for ':' and '-'
'-' | ':' => self.path.temp_buf.push('.'),
// These are legal symbols
'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '$' => self.temp_buf.push(c),
'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '.' | '$' => self.path.temp_buf.push(c),
_ => {
self.temp_buf.push('$');
self.path.temp_buf.push('$');
for c in c.escape_unicode().skip(1) {
match c {
'{' => {}
'}' => self.temp_buf.push('$'),
c => self.temp_buf.push(c),
'}' => self.path.temp_buf.push('$'),
c => self.path.temp_buf.push(c),
}
}
}
}
}
let need_underscore = {
// Underscore-qualify anything that didn't start as an ident.
!self.temp_buf.is_empty()
&& self.temp_buf.as_bytes()[0] != '_' as u8
&& !(self.temp_buf.as_bytes()[0] as char).is_xid_start()
};
let _ = write!(
self.result,
"{}",
self.temp_buf.len() + (need_underscore as usize)
);
if need_underscore {
self.result.push('_');
}
self.result.push_str(&self.temp_buf);
}
}
impl ItemPathBuffer for SymbolPathBuffer {
fn root_mode(&self) -> &RootMode {
const ABSOLUTE: &RootMode = &RootMode::Absolute;
ABSOLUTE
}
fn push(&mut self, text: &str) {
self.sanitize_and_append(text);
Ok(())
}
}

View file

@ -1,7 +1,7 @@
//! Walks the crate looking for items/impl-items/trait-items that have
//! either a `rustc_symbol_name` or `rustc_item_path` attribute and
//! either a `rustc_symbol_name` or `rustc_def_path` attribute and
//! generates an error giving, respectively, the symbol name or
//! item-path. This is used for unit testing the code that generates
//! def-path. This is used for unit testing the code that generates
//! paths etc in all kinds of annoying scenarios.
use rustc::hir;
@ -10,7 +10,7 @@ use rustc::ty::TyCtxt;
use rustc_mir::monomorphize::Instance;
const SYMBOL_NAME: &'static str = "rustc_symbol_name";
const ITEM_PATH: &'static str = "rustc_item_path";
const DEF_PATH: &'static str = "rustc_def_path";
pub fn report_symbol_names<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
// if the `rustc_attrs` feature is not enabled, then the
@ -41,9 +41,9 @@ impl<'a, 'tcx> SymbolNamesTest<'a, 'tcx> {
let instance = Instance::mono(tcx, def_id);
let name = self.tcx.symbol_name(instance);
tcx.sess.span_err(attr.span, &format!("symbol-name({})", name));
} else if attr.check_name(ITEM_PATH) {
let path = tcx.item_path_str(def_id);
tcx.sess.span_err(attr.span, &format!("item-path({})", path));
} else if attr.check_name(DEF_PATH) {
let path = tcx.def_path_str(def_id);
tcx.sess.span_err(attr.span, &format!("def-path({})", path));
}
// (*) The formatting of `tag({})` is chosen so that tests can elect

View file

@ -471,7 +471,7 @@ impl<'b, 'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'b, 'tcx> {
}
fn node_path(&self, id: ast::NodeId) -> Option<String> {
Some(self.tcx.node_path_str(id))
Some(self.tcx.def_path_str(self.tcx.hir().local_def_id(id)))
}
}

View file

@ -206,7 +206,7 @@ fn check_paths<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
tcx.sess.span_err(
target_span,
&format!("no path from `{}` to `{}`",
tcx.item_path_str(source_def_id),
tcx.def_path_str(source_def_id),
target_pass));
} else {
tcx.sess.span_err(

View file

@ -463,7 +463,7 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
if let Some(def_id) = dep_node.extract_def_id(self.tcx) {
format!("{:?}({})",
dep_node.kind,
self.tcx.item_path_str(def_id))
self.tcx.def_path_str(def_id))
} else {
format!("{:?}({:?})", dep_node.kind, dep_node.hash)
}

View file

@ -182,7 +182,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
for attr in cx.tcx.get_attrs(def_id).iter() {
if attr.check_name("must_use") {
let msg = format!("unused {}`{}`{} that must be used",
descr_pre_path, cx.tcx.item_path_str(def_id), descr_post_path);
descr_pre_path, cx.tcx.def_path_str(def_id), descr_post_path);
let mut err = cx.struct_span_lint(UNUSED_MUST_USE, sp, &msg);
// check for #[must_use = "..."]
if let Some(note) = attr.value_str() {

View file

@ -3,6 +3,7 @@ use crate::borrow_check::nll::region_infer::{RegionName, RegionNameSource};
use crate::borrow_check::prefixes::IsPrefixOf;
use crate::borrow_check::WriteKind;
use rustc::hir;
use rustc::hir::def::Namespace;
use rustc::hir::def_id::DefId;
use rustc::middle::region::ScopeTree;
use rustc::mir::{
@ -12,7 +13,7 @@ use rustc::mir::{
TerminatorKind, VarBindingForm,
};
use rustc::ty::{self, DefIdTree};
use rustc::util::ppaux::RegionHighlightMode;
use rustc::ty::print::Print;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::indexed_vec::Idx;
use rustc_data_structures::sync::Lrc;
@ -831,7 +832,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
);
if let Some(annotation) = self.annotate_argument_and_return_for_borrow(borrow) {
let region_name = annotation.emit(&mut err);
let region_name = annotation.emit(self, &mut err);
err.span_label(
borrow_span,
@ -1799,7 +1800,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
// (https://github.com/rust-lang/rfcs/pull/1546)
bug!(
"End-user description not implemented for field access on `{:?}`",
ty.sty
ty
);
}
}
@ -1875,7 +1876,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
fn annotate_argument_and_return_for_borrow(
&self,
borrow: &BorrowData<'tcx>,
) -> Option<AnnotatedBorrowFnSignature<'_>> {
) -> Option<AnnotatedBorrowFnSignature<'tcx>> {
// Define a fallback for when we can't match a closure.
let fallback = || {
let is_closure = self.infcx.tcx.is_closure(self.mir_def_id);
@ -2099,7 +2100,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
&self,
did: DefId,
sig: ty::PolyFnSig<'tcx>,
) -> Option<AnnotatedBorrowFnSignature<'_>> {
) -> Option<AnnotatedBorrowFnSignature<'tcx>> {
debug!("annotate_fn_sig: did={:?} sig={:?}", did, sig);
let is_closure = self.infcx.tcx.is_closure(did);
let fn_hir_id = self.infcx.tcx.hir().as_local_hir_id(did)?;
@ -2245,7 +2246,11 @@ enum AnnotatedBorrowFnSignature<'tcx> {
impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
/// Annotate the provided diagnostic with information about borrow from the fn signature that
/// helps explain.
fn emit(&self, diag: &mut DiagnosticBuilder<'_>) -> String {
fn emit(
&self,
cx: &mut MirBorrowckCtxt<'_, '_, 'tcx>,
diag: &mut DiagnosticBuilder<'_>,
) -> String {
match self {
AnnotatedBorrowFnSignature::Closure {
argument_ty,
@ -2253,10 +2258,10 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
} => {
diag.span_label(
*argument_span,
format!("has type `{}`", self.get_name_for_ty(argument_ty, 0)),
format!("has type `{}`", cx.get_name_for_ty(argument_ty, 0)),
);
self.get_region_name_for_ty(argument_ty, 0)
cx.get_region_name_for_ty(argument_ty, 0)
}
AnnotatedBorrowFnSignature::AnonymousFunction {
argument_ty,
@ -2264,10 +2269,10 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
return_ty,
return_span,
} => {
let argument_ty_name = self.get_name_for_ty(argument_ty, 0);
let argument_ty_name = cx.get_name_for_ty(argument_ty, 0);
diag.span_label(*argument_span, format!("has type `{}`", argument_ty_name));
let return_ty_name = self.get_name_for_ty(return_ty, 0);
let return_ty_name = cx.get_name_for_ty(return_ty, 0);
let types_equal = return_ty_name == argument_ty_name;
diag.span_label(
*return_span,
@ -2286,7 +2291,7 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
lifetime-syntax.html#lifetime-elision>",
);
self.get_region_name_for_ty(return_ty, 0)
cx.get_region_name_for_ty(return_ty, 0)
}
AnnotatedBorrowFnSignature::NamedFunction {
arguments,
@ -2294,7 +2299,7 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
return_span,
} => {
// Region of return type and arguments checked to be the same earlier.
let region_name = self.get_region_name_for_ty(return_ty, 0);
let region_name = cx.get_region_name_for_ty(return_ty, 0);
for (_, argument_span) in arguments {
diag.span_label(*argument_span, format!("has lifetime `{}`", region_name));
}
@ -2314,10 +2319,15 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
}
}
}
}
impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
/// Return the name of the provided `Ty` (that must be a reference) with a synthesized lifetime
/// name where required.
fn get_name_for_ty(&self, ty: ty::Ty<'tcx>, counter: usize) -> String {
let mut s = String::new();
let mut printer = ty::print::FmtPrinter::new(self.infcx.tcx, &mut s, Namespace::TypeNS);
// We need to add synthesized lifetimes where appropriate. We do
// this by hooking into the pretty printer and telling it to label the
// lifetimes without names with the value `'0`.
@ -2327,28 +2337,37 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }),
_,
_,
) => RegionHighlightMode::highlighting_bound_region(*br, counter, || ty.to_string()),
_ => ty.to_string(),
) => printer.region_highlight_mode.highlighting_bound_region(*br, counter),
_ => {}
}
let _ = ty.print(printer);
s
}
/// Returns the name of the provided `Ty` (that must be a reference)'s region with a
/// synthesized lifetime name where required.
fn get_region_name_for_ty(&self, ty: ty::Ty<'tcx>, counter: usize) -> String {
match ty.sty {
ty::TyKind::Ref(region, _, _) => match region {
ty::RegionKind::ReLateBound(_, br)
| ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }) => {
RegionHighlightMode::highlighting_bound_region(
*br,
counter,
|| region.to_string(),
)
let mut s = String::new();
let mut printer = ty::print::FmtPrinter::new(self.infcx.tcx, &mut s, Namespace::TypeNS);
let region = match ty.sty {
ty::TyKind::Ref(region, _, _) => {
match region {
ty::RegionKind::ReLateBound(_, br)
| ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }) => {
printer.region_highlight_mode.highlighting_bound_region(*br, counter)
}
_ => {}
}
_ => region.to_string(),
},
region
}
_ => bug!("ty for annotation of borrow region is not a reference"),
}
};
let _ = region.print(printer);
s
}
}

View file

@ -68,7 +68,7 @@ pub fn provide(providers: &mut Providers<'_>) {
fn mir_borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> BorrowCheckResult<'tcx> {
let input_mir = tcx.mir_validated(def_id);
debug!("run query mir_borrowck: {}", tcx.item_path_str(def_id));
debug!("run query mir_borrowck: {}", tcx.def_path_str(def_id));
let mut return_early;

View file

@ -93,7 +93,7 @@ impl BorrowExplanation {
// simplify output by reporting just the ADT name.
ty::Adt(adt, _substs) if adt.has_dtor(tcx) && !adt.is_box() => (
"`Drop` code",
format!("type `{}`", tcx.item_path_str(adt.did)),
format!("type `{}`", tcx.def_path_str(adt.did)),
),
// Otherwise, just report the whole type (and use

View file

@ -8,7 +8,7 @@ use rustc::infer::InferCtxt;
use rustc::mir::Mir;
use rustc::ty::subst::{SubstsRef, UnpackedKind};
use rustc::ty::{self, RegionKind, RegionVid, Ty, TyCtxt};
use rustc::util::ppaux::RegionHighlightMode;
use rustc::ty::print::RegionHighlightMode;
use rustc_errors::DiagnosticBuilder;
use syntax::ast::Name;
use syntax::symbol::keywords;
@ -396,9 +396,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
argument_ty: Ty<'tcx>,
counter: &mut usize,
) -> Option<RegionName> {
let type_name = RegionHighlightMode::highlighting_region_vid(needle_fr, *counter, || {
infcx.extract_type_name(&argument_ty)
});
let mut highlight = RegionHighlightMode::default();
highlight.highlighting_region_vid(needle_fr, *counter);
let type_name = infcx.extract_type_name(&argument_ty, Some(highlight));
debug!(
"give_name_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}",
@ -680,9 +680,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
return None;
}
let type_name = RegionHighlightMode::highlighting_region_vid(
fr, *counter, || infcx.extract_type_name(&return_ty),
);
let mut highlight = RegionHighlightMode::default();
highlight.highlighting_region_vid(fr, *counter);
let type_name = infcx.extract_type_name(&return_ty, Some(highlight));
let mir_node_id = tcx.hir().as_local_node_id(mir_def_id).expect("non-local mir");

View file

@ -142,7 +142,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
assert!(!layout.is_unsized());
let ret = ecx.allocate(layout, MemoryKind::Stack);
let name = ty::tls::with(|tcx| tcx.item_path_str(cid.instance.def_id()));
let name = ty::tls::with(|tcx| tcx.def_path_str(cid.instance.def_id()));
let prom = cid.promoted.map_or(String::new(), |p| format!("::promoted[{:?}]", p));
trace!("eval_body_using_ecx: pushing stack frame for global: {}{}", name, prom);
assert!(mir.arg_count == 0);
@ -602,14 +602,15 @@ pub fn const_eval_raw_provider<'a, 'tcx>(
other => return other,
}
}
// the first trace is for replicating an ice
// There's no tracking issue, but the next two lines concatenated link to the discussion on
// zulip. It's not really possible to test this, because it doesn't show up in diagnostics
// or MIR.
// https://rust-lang.zulipchat.com/#narrow/stream/146212-t-compiler.2Fconst-eval/
// subject/anon_const_instance_printing/near/135980032
trace!("const eval: {}", key.value.instance);
trace!("const eval: {:?}", key);
if cfg!(debug_assertions) {
// Make sure we format the instance even if we do not print it.
// This serves as a regression test against an ICE on printing.
// The next two lines concatenated contain some discussion:
// https://rust-lang.zulipchat.com/#narrow/stream/146212-t-compiler.2Fconst-eval/
// subject/anon_const_instance_printing/near/135980032
let instance = key.value.instance.to_string();
trace!("const eval: {:?} ({})", key, instance);
}
let cid = key.value;
let def_id = cid.instance.def.def_id();

View file

@ -955,7 +955,8 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
let user_provided_types = cx.tables.user_provided_types();
let user_provided_type = user_provided_types.get(expr.hir_id).map(|u_ty| *u_ty);
debug!("convert_path_expr: user_provided_type={:?}", user_provided_type);
match cx.tables().node_type(expr.hir_id).sty {
let ty = cx.tables().node_type(expr.hir_id);
match ty.sty {
// A unit struct/variant which is used as a value.
// We return a completely different ExprKind here to account for this special case.
ty::Adt(adt_def, substs) => {
@ -968,7 +969,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
base: None,
}
}
ref sty => bug!("unexpected sty: {:?}", sty),
_ => bug!("unexpected ty: {:?}", ty),
}
}

View file

@ -319,7 +319,7 @@ fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pa
if edef.is_enum() && edef.variants.iter().any(|variant| {
variant.ident == ident && variant.ctor_kind == CtorKind::Const
}) {
let ty_path = cx.tcx.item_path_str(edef.did);
let ty_path = cx.tcx.def_path_str(edef.did);
let mut err = struct_span_warn!(cx.tcx.sess, p.span, E0170,
"pattern binding `{}` is named the same as one \
of the variants of the type `{}`",

View file

@ -13,7 +13,7 @@ use crate::hair::constant::*;
use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability};
use rustc::mir::{UserTypeProjection};
use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, sign_extend};
use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, Lift, UserType};
use rustc::ty::{self, DefIdTree, Region, TyCtxt, AdtDef, Ty, Lift, UserType};
use rustc::ty::{CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations};
use rustc::ty::subst::{SubstsRef, Kind};
use rustc::ty::layout::VariantIdx;
@ -529,11 +529,11 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
ty::Error => { // Avoid ICE
return Pattern { span: pat.span, ty, kind: Box::new(PatternKind::Wild) };
}
ref sty =>
_ =>
span_bug!(
pat.span,
"unexpanded type for vector pattern: {:?}",
sty),
ty),
}
}
@ -554,7 +554,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
ty::Error => { // Avoid ICE (#50577)
return Pattern { span: pat.span, ty, kind: Box::new(PatternKind::Wild) };
}
ref sty => span_bug!(pat.span, "unexpected type for tuple pattern: {:?}", sty),
_ => span_bug!(pat.span, "unexpected type for tuple pattern: {:?}", ty),
}
}
@ -608,7 +608,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
}
_ => span_bug!(pat.span,
"tuple struct pattern not applied to an ADT {:?}",
ty.sty),
ty),
};
let variant_def = adt_def.variant_of_def(def);
@ -735,7 +735,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
) -> PatternKind<'tcx> {
let mut kind = match def {
Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => {
let enum_id = self.tcx.parent_def_id(variant_id).unwrap();
let enum_id = self.tcx.parent(variant_id).unwrap();
let adt_def = self.tcx.adt_def(enum_id);
if adt_def.is_enum() {
let substs = match ty.sty {
@ -744,7 +744,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
ty::Error => { // Avoid ICE (#50585)
return PatternKind::Wild;
}
_ => bug!("inappropriate type for def: {:?}", ty.sty),
_ => bug!("inappropriate type for def: {:?}", ty),
};
PatternKind::Variant {
adt_def,
@ -969,8 +969,8 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
ty::Adt(adt_def, _) if !self.tcx.has_attr(adt_def.did, "structural_match") => {
let msg = format!("to use a constant of type `{}` in a pattern, \
`{}` must be annotated with `#[derive(PartialEq, Eq)]`",
self.tcx.item_path_str(adt_def.did),
self.tcx.item_path_str(adt_def.did));
self.tcx.def_path_str(adt_def.did),
self.tcx.def_path_str(adt_def.did));
self.tcx.sess.span_err(span, &msg);
PatternKind::Wild
}

View file

@ -16,7 +16,8 @@ crate trait UserAnnotatedTyHelpers<'gcx: 'tcx, 'tcx> {
let user_provided_types = self.tables().user_provided_types();
let mut user_ty = *user_provided_types.get(hir_id)?;
debug!("user_subts_applied_to_ty_of_hir_id: user_ty={:?}", user_ty);
match &self.tables().node_type(hir_id).sty {
let ty = self.tables().node_type(hir_id);
match ty.sty {
ty::Adt(adt_def, ..) => {
if let UserType::TypeOf(ref mut did, _) = &mut user_ty.value {
*did = adt_def.did;
@ -24,8 +25,11 @@ crate trait UserAnnotatedTyHelpers<'gcx: 'tcx, 'tcx> {
Some(user_ty)
}
ty::FnDef(..) => Some(user_ty),
sty =>
bug!("sty: {:?} should not have user provided type {:?} recorded ", sty, user_ty),
_ => bug!(
"ty: {:?} should not have user provided type {:?} recorded ",
ty,
user_ty
),
}
}
}

View file

@ -90,7 +90,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
let fn_ptr = self.memory.create_fn_alloc(instance?).with_default_tag();
self.write_scalar(Scalar::Ptr(fn_ptr.into()), dest)?;
}
ref other => bug!("reify fn pointer on {:?}", other),
_ => bug!("reify fn pointer on {:?}", src.layout.ty),
}
}
@ -101,7 +101,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
// No change to value
self.write_immediate(*src, dest)?;
}
ref other => bug!("fn to unsafe fn cast on {:?}", other),
_ => bug!("fn to unsafe fn cast on {:?}", dest.layout.ty),
}
}
@ -120,7 +120,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
let val = Immediate::Scalar(Scalar::Ptr(fn_ptr.into()).into());
self.write_immediate(val, dest)?;
}
ref other => bug!("closure fn pointer on {:?}", other),
_ => bug!("closure fn pointer on {:?}", src.layout.ty),
}
}
}

View file

@ -283,7 +283,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
ty::InstanceDef::Item(def_id) => if self.tcx.is_mir_available(did) {
Ok(self.tcx.optimized_mir(did))
} else {
err!(NoMirFor(self.tcx.item_path_str(def_id)))
err!(NoMirFor(self.tcx.def_path_str(def_id)))
},
_ => Ok(self.tcx.instance_mir(instance)),
}
@ -450,7 +450,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
return_place: Option<PlaceTy<'tcx, M::PointerTag>>,
return_to_block: StackPopCleanup,
) -> EvalResult<'tcx> {
if self.stack.len() > 1 { // FIXME should be "> 0", printing topmost frame crashes rustc...
if self.stack.len() > 0 {
info!("PAUSING({}) {}", self.cur_frame(), self.frame().instance);
}
::log_settings::settings().indentation += 1;
@ -525,9 +525,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
self.frame_mut().locals = locals;
}
if self.stack.len() > 1 { // FIXME no check should be needed, but some instances ICE
info!("ENTERING({}) {}", self.cur_frame(), self.frame().instance);
}
info!("ENTERING({}) {}", self.cur_frame(), self.frame().instance);
if self.stack.len() > self.tcx.sess.const_eval_stack_frame_limit {
err!(StackFrameLimitReached)
@ -537,9 +535,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
}
pub(super) fn pop_stack_frame(&mut self) -> EvalResult<'tcx> {
if self.stack.len() > 1 { // FIXME no check should be needed, but some instances ICE
info!("LEAVING({}) {}", self.cur_frame(), self.frame().instance);
}
info!("LEAVING({}) {}", self.cur_frame(), self.frame().instance);
::log_settings::settings().indentation -= 1;
let frame = self.stack.pop().expect(
"tried to pop a stack frame, but there were none",
@ -591,7 +587,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
StackPopCleanup::None { .. } => {}
}
if self.stack.len() > 1 { // FIXME should be "> 0", printing topmost frame crashes rustc...
if self.stack.len() > 0 {
info!("CONTINUING({}) {}", self.cur_frame(), self.frame().instance);
}

View file

@ -336,7 +336,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
let layout = val.layout;
let val = val.to_scalar()?;
trace!("Running unary op {:?}: {:?} ({:?})", un_op, val, layout.ty.sty);
trace!("Running unary op {:?}: {:?} ({:?})", un_op, val, layout.ty);
match layout.ty.sty {
ty::Bool => {

View file

@ -354,7 +354,7 @@ where
ty::Ref(_, _, mutbl) => Some(mutbl),
ty::Adt(def, _) if def.is_box() => Some(hir::MutMutable),
ty::RawPtr(_) => None,
_ => bug!("Unexpected pointer type {}", val.layout.ty.sty),
_ => bug!("Unexpected pointer type {}", val.layout.ty),
};
place.mplace.ptr = M::tag_dereference(self, place, mutbl)?;
Ok(place)

View file

@ -198,6 +198,8 @@ use crate::monomorphize::item::{MonoItemExt, DefPathBasedNames, InstantiationMod
use rustc_data_structures::bit_set::GrowableBitSet;
use rustc_data_structures::sync::{MTRef, MTLock, ParallelIterator, par_iter};
use std::iter;
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
pub enum MonoItemCollectionMode {
Eager,
@ -487,21 +489,33 @@ fn check_type_length_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// We include the const length in the type length, as it's better
// to be overly conservative.
if type_length + const_length > type_length_limit {
// The instance name is already known to be too long for rustc. Use
// `{:.64}` to avoid blasting the user's terminal with thousands of
// lines of type-name.
let instance_name = instance.to_string();
let msg = format!("reached the type-length limit while instantiating `{:.64}...`",
instance_name);
let mut diag = if let Some(hir_id) = tcx.hir().as_local_hir_id(instance.def_id()) {
tcx.sess.struct_span_fatal(tcx.hir().span_by_hir_id(hir_id), &msg)
} else {
tcx.sess.struct_fatal(&msg)
};
// The instance name is already known to be too long for rustc.
// Show only the first and last 32 characters to avoid blasting
// the user's terminal with thousands of lines of type-name.
let shrink = |s: String, before: usize, after: usize| {
// An iterator of all byte positions including the end of the string.
let positions = || s.char_indices().map(|(i, _)| i).chain(iter::once(s.len()));
let shrunk = format!(
"{before}...{after}",
before = &s[..positions().nth(before).unwrap_or(s.len())],
after = &s[positions().rev().nth(after).unwrap_or(0)..],
);
// Only use the shrunk version if it's really shorter.
// This also avoids the case where before and after slices overlap.
if shrunk.len() < s.len() {
shrunk
} else {
s
}
};
let msg = format!("reached the type-length limit while instantiating `{}`",
shrink(instance.to_string(), 32, 32));
let mut diag = tcx.sess.struct_span_fatal(tcx.def_span(instance.def_id()), &msg);
diag.note(&format!(
"consider adding a `#![type_length_limit=\"{}\"]` attribute to your crate",
type_length_limit * 2));
type_length));
diag.emit();
tcx.sess.abort_if_errors();
}
@ -836,7 +850,7 @@ fn find_vtable_types_for_unsizing<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
match tail.sty {
ty::Foreign(..) => false,
ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
_ => bug!("unexpected unsized tail: {:?}", tail.sty),
_ => bug!("unexpected unsized tail: {:?}", tail),
}
};
if type_has_metadata(inner_source) {

View file

@ -216,9 +216,8 @@ impl<'a, 'tcx> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
// These keys are used by the handwritten auto-tests, so they need to be
// predictable and human-readable.
//
// Note: A lot of this could looks very similar to what's already in the
// ppaux module. It would be good to refactor things so we only have one
// parameterizable implementation for printing types.
// Note: A lot of this could looks very similar to what's already in `ty::print`.
// FIXME(eddyb) implement a custom `PrettyPrinter` for this.
/// Same as `unique_type_name()` but with the result pushed onto the given
/// `output` parameter.

View file

@ -104,7 +104,7 @@ use rustc::hir::map::DefPathData;
use rustc::mir::mono::{Linkage, Visibility, CodegenUnitNameBuilder};
use rustc::middle::exported_symbols::SymbolExportLevel;
use rustc::ty::{self, TyCtxt, InstanceDef};
use rustc::ty::item_path::characteristic_def_id_of_type;
use rustc::ty::print::characteristic_def_id_of_type;
use rustc::ty::query::Providers;
use rustc::util::common::time;
use rustc::util::nodemap::{DefIdSet, FxHashMap, FxHashSet};

View file

@ -1253,7 +1253,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
if !self.span.allows_unstable(&feature.as_str()) {
let mut err = self.tcx.sess.struct_span_err(self.span,
&format!("`{}` is not yet stable as a const fn",
self.tcx.item_path_str(def_id)));
self.tcx.def_path_str(def_id)));
if nightly_options::is_nightly_build() {
help!(&mut err,
"add `#![feature({})]` to the \

View file

@ -29,10 +29,10 @@ impl MirPass for SanityCheck {
let def_id = src.def_id();
let id = tcx.hir().as_local_hir_id(def_id).unwrap();
if !tcx.has_attr(def_id, "rustc_mir") {
debug!("skipping rustc_peek::SanityCheck on {}", tcx.item_path_str(def_id));
debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id));
return;
} else {
debug!("running rustc_peek::SanityCheck on {}", tcx.item_path_str(def_id));
debug!("running rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id));
}
let attributes = tcx.get_attrs(def_id);

View file

@ -127,7 +127,7 @@ fn write_graph_label<'a, 'gcx, 'tcx, W: Write>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
mir: &Mir<'_>,
w: &mut W)
-> io::Result<()> {
write!(w, " label=<fn {}(", dot::escape_html(&tcx.item_path_str(def_id)))?;
write!(w, " label=<fn {}(", dot::escape_html(&tcx.def_path_str(def_id)))?;
// fn argument types.
for (i, arg) in mir.args_iter().enumerate() {
@ -141,7 +141,7 @@ fn write_graph_label<'a, 'gcx, 'tcx, W: Write>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
)?;
}
write!(w, ") -&gt; {}", escape(mir.return_ty()))?;
write!(w, ") -&gt; {}", escape(&mir.return_ty()))?;
write!(w, r#"<br align="left"/>"#)?;
for local in mir.vars_and_temps_iter() {

View file

@ -29,7 +29,7 @@ use rustc::mir::visit::{
};
use rustc::mir::Local;
use rustc::mir::*;
use rustc::ty::{item_path, TyCtxt};
use rustc::ty::{self, TyCtxt};
use rustc_data_structures::bit_set::BitSet;
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
use rustc_data_structures::work_queue::WorkQueue;
@ -265,9 +265,9 @@ pub fn dump_mir<'a, 'tcx>(
if !dump_enabled(tcx, pass_name, source) {
return;
}
let node_path = item_path::with_forced_impl_filename_line(|| {
let node_path = ty::print::with_forced_impl_filename_line(|| {
// see notes on #41697 below
tcx.item_path_str(source.def_id())
tcx.def_path_str(source.def_id())
});
dump_matched_mir_node(tcx, pass_name, &node_path, source, mir, result);
}

View file

@ -2,7 +2,6 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE};
use rustc::mir::*;
use rustc::mir::visit::Visitor;
use rustc::ty::{self, TyCtxt};
use rustc::ty::item_path;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_vec::Idx;
use std::fmt::Display;
@ -78,9 +77,9 @@ pub fn dump_mir<'a, 'gcx, 'tcx, F>(
return;
}
let node_path = item_path::with_forced_impl_filename_line(|| {
let node_path = ty::print::with_forced_impl_filename_line(|| {
// see notes on #41697 below
tcx.item_path_str(source.def_id())
tcx.def_path_str(source.def_id())
});
dump_matched_mir_node(
tcx,
@ -103,9 +102,9 @@ pub fn dump_enabled<'a, 'gcx, 'tcx>(
None => return false,
Some(ref filters) => filters,
};
let node_path = item_path::with_forced_impl_filename_line(|| {
let node_path = ty::print::with_forced_impl_filename_line(|| {
// see notes on #41697 below
tcx.item_path_str(source.def_id())
tcx.def_path_str(source.def_id())
});
filters.split('|').any(|or_filter| {
or_filter.split('&').all(|and_filter| {
@ -115,7 +114,7 @@ pub fn dump_enabled<'a, 'gcx, 'tcx>(
}
// #41697 -- we use `with_forced_impl_filename_line()` because
// `item_path_str()` would otherwise trigger `type_of`, and this can
// `def_path_str()` would otherwise trigger `type_of`, and this can
// run while we are already attempting to evaluate `type_of`.
fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>(
@ -612,9 +611,9 @@ fn write_mir_sig(
_ => bug!("Unexpected def description {:?}", descr),
}
item_path::with_forced_impl_filename_line(|| {
ty::print::with_forced_impl_filename_line(|| {
// see notes on #41697 elsewhere
write!(w, "{}", tcx.item_path_str(src.def_id()))
write!(w, " {}", tcx.def_path_str(src.def_id()))
})?;
if src.promoted.is_none() && is_function {

View file

@ -134,7 +134,7 @@ impl<'a, 'tcx, V> TypeVisitor<'tcx> for DefIdVisitorSkeleton<'_, 'a, 'tcx, V>
ty::FnDef(def_id, ..) |
ty::Closure(def_id, ..) |
ty::Generator(def_id, ..) => {
if self.def_id_visitor.visit_def_id(def_id, "type", ty) {
if self.def_id_visitor.visit_def_id(def_id, "type", &ty) {
return true;
}
if self.def_id_visitor.shallow() {
@ -816,7 +816,7 @@ impl<'a, 'tcx> NamePrivacyVisitor<'a, 'tcx> {
let def_id = self.tcx.adjust_ident(ident, def.did, current_hir).1;
if !def.is_enum() && !field.vis.is_accessible_from(def_id, self.tcx) {
struct_span_err!(self.tcx.sess, span, E0451, "field `{}` of {} `{}` is private",
field.ident, def.variant_descr(), self.tcx.item_path_str(def.did))
field.ident, def.variant_descr(), self.tcx.def_path_str(def.did))
.span_label(span, format!("field `{}` is private", field.ident))
.emit();
}

View file

@ -17,7 +17,7 @@ use rustc::hir::def::Def as HirDef;
use rustc::hir::def_id::DefId;
use rustc::session::config::Input;
use rustc::span_bug;
use rustc::ty::{self, TyCtxt};
use rustc::ty::{self, DefIdTree, TyCtxt};
use rustc_data_structures::fx::FxHashSet;
use std::path::Path;
@ -429,7 +429,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
vis: ast::Visibility,
attrs: &'l [Attribute],
) {
let qualname = format!("::{}", self.tcx.node_path_str(id));
let qualname = format!("::{}",
self.tcx.def_path_str(self.tcx.hir().local_def_id(id)));
if !self.span.filter_generated(ident.span) {
let sig = sig::assoc_const_signature(id, ident.name, typ, expr, &self.save_ctxt);
@ -470,7 +471,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
) {
debug!("process_struct {:?} {:?}", item, item.span);
let name = item.ident.to_string();
let qualname = format!("::{}", self.tcx.node_path_str(item.id));
let qualname = format!("::{}",
self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
let kind = match item.node {
ast::ItemKind::Struct(_, _) => DefKind::Struct,
@ -682,7 +684,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
methods: &'l [ast::TraitItem],
) {
let name = item.ident.to_string();
let qualname = format!("::{}", self.tcx.node_path_str(item.id));
let qualname = format!("::{}",
self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
let mut val = name.clone();
if !generics.params.is_empty() {
val.push_str(&generic_params_to_string(&generics.params));
@ -1093,7 +1096,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
ast::TraitItemKind::Type(ref bounds, ref default_ty) => {
// FIXME do something with _bounds (for type refs)
let name = trait_item.ident.name.to_string();
let qualname = format!("::{}", self.tcx.node_path_str(trait_item.id));
let qualname = format!("::{}",
self.tcx.def_path_str(self.tcx.hir().local_def_id(trait_item.id)));
if !self.span.filter_generated(trait_item.ident.span) {
let span = self.span_from_span(trait_item.ident.span);
@ -1201,7 +1205,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
// The parent def id of a given use tree is always the enclosing item.
let parent = self.save_ctxt.tcx.hir().opt_local_def_id(id)
.and_then(|id| self.save_ctxt.tcx.parent_def_id(id))
.and_then(|id| self.save_ctxt.tcx.parent(id))
.map(id_from_def_id);
match use_tree.kind {
@ -1300,7 +1304,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
// only get called for the root module of a crate.
assert_eq!(id, ast::CRATE_NODE_ID);
let qualname = format!("::{}", self.tcx.node_path_str(id));
let qualname = format!("::{}",
self.tcx.def_path_str(self.tcx.hir().local_def_id(id)));
let cm = self.tcx.sess.source_map();
let filename = cm.span_to_filename(span);
@ -1350,7 +1355,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
if !self.span.filter_generated(name_span) {
let span = self.span_from_span(name_span);
let parent = self.save_ctxt.tcx.hir().opt_local_def_id(item.id)
.and_then(|id| self.save_ctxt.tcx.parent_def_id(id))
.and_then(|id| self.save_ctxt.tcx.parent(id))
.map(id_from_def_id);
self.dumper.import(
&Access {
@ -1389,7 +1394,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
self.nest_scope(item.id, |v| visit::walk_mod(v, m));
}
Ty(ref ty, ref ty_params) => {
let qualname = format!("::{}", self.tcx.node_path_str(item.id));
let qualname = format!("::{}",
self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
let value = ty_to_string(&ty);
if !self.span.filter_generated(item.ident.span) {
let span = self.span_from_span(item.ident.span);
@ -1418,7 +1424,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
self.process_generic_params(ty_params, &qualname, item.id);
}
Existential(ref _bounds, ref ty_params) => {
let qualname = format!("::{}", self.tcx.node_path_str(item.id));
let qualname = format!("::{}",
self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
// FIXME do something with _bounds
let value = String::new();
if !self.span.filter_generated(item.ident.span) {

View file

@ -20,7 +20,7 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE};
use rustc::middle::privacy::AccessLevels;
use rustc::middle::cstore::ExternCrate;
use rustc::session::config::{CrateType, Input, OutputType};
use rustc::ty::{self, TyCtxt};
use rustc::ty::{self, DefIdTree, TyCtxt};
use rustc::{bug, span_bug};
use rustc_typeck::hir_ty_to_ty;
use rustc_codegen_utils::link::{filename_for_metadata, out_filename};
@ -134,7 +134,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
}
pub fn get_extern_item_data(&self, item: &ast::ForeignItem) -> Option<Data> {
let qualname = format!("::{}", self.tcx.node_path_str(item.id));
let qualname = format!("::{}",
self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
match item.node {
ast::ForeignItemKind::Fn(ref decl, ref generics) => {
filter!(self.span_utils, item.ident.span);
@ -184,7 +185,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
match item.node {
ast::ItemKind::Fn(ref decl, .., ref generics, _) => {
let qualname = format!("::{}", self.tcx.node_path_str(item.id));
let qualname = format!("::{}",
self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
filter!(self.span_utils, item.ident.span);
Some(Data::DefData(Def {
kind: DefKind::Function,
@ -202,7 +204,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
}))
}
ast::ItemKind::Static(ref typ, ..) => {
let qualname = format!("::{}", self.tcx.node_path_str(item.id));
let qualname = format!("::{}",
self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
filter!(self.span_utils, item.ident.span);
@ -225,7 +228,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
}))
}
ast::ItemKind::Const(ref typ, _) => {
let qualname = format!("::{}", self.tcx.node_path_str(item.id));
let qualname = format!("::{}",
self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
filter!(self.span_utils, item.ident.span);
let id = id_from_node_id(item.id, self);
@ -247,7 +251,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
}))
}
ast::ItemKind::Mod(ref m) => {
let qualname = format!("::{}", self.tcx.node_path_str(item.id));
let qualname = format!("::{}",
self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
let cm = self.tcx.sess.source_map();
let filename = cm.span_to_filename(m.inner);
@ -274,7 +279,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
}
ast::ItemKind::Enum(ref def, _) => {
let name = item.ident.to_string();
let qualname = format!("::{}", self.tcx.node_path_str(item.id));
let qualname = format!("::{}",
self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
filter!(self.span_utils, item.ident.span);
let variants_str = def.variants
.iter()
@ -358,7 +364,9 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
pub fn get_field_data(&self, field: &ast::StructField, scope: NodeId) -> Option<Def> {
if let Some(ident) = field.ident {
let name = ident.to_string();
let qualname = format!("::{}::{}", self.tcx.node_path_str(scope), ident);
let qualname = format!("::{}::{}",
self.tcx.def_path_str(self.tcx.hir().local_def_id(scope)),
ident);
filter!(self.span_utils, ident.span);
let def_id = self.tcx.hir().local_def_id(field.id);
let typ = self.tcx.type_of(def_id).to_string();
@ -411,7 +419,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
if let Some(def_id) = trait_id {
// A method in a trait impl.
qualname.push_str(" as ");
qualname.push_str(&self.tcx.item_path_str(def_id));
qualname.push_str(&self.tcx.def_path_str(def_id));
self.tcx
.associated_items(def_id)
.find(|item| item.ident.name == ident.name)
@ -451,7 +459,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
}
(
format!("::{}", self.tcx.item_path_str(def_id)),
format!("::{}", self.tcx.def_path_str(def_id)),
Some(def_id),
None,
docs,
@ -763,7 +771,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
// This is a reference to a tuple struct where the def_id points
// to an invisible constructor function. That is not a very useful
// def, so adjust to point to the tuple struct itself.
let parent_def_id = self.tcx.parent_def_id(def_id).unwrap();
let parent_def_id = self.tcx.parent(def_id).unwrap();
Some(Ref {
kind: RefKind::Type,
span,

View file

@ -12,7 +12,7 @@ use crate::middle::resolve_lifetime as rl;
use crate::namespace::Namespace;
use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
use rustc::traits;
use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
use rustc::ty::{self, DefIdTree, Ty, TyCtxt, ToPredicate, TypeFoldable};
use rustc::ty::{GenericParamDef, GenericParamDefKind};
use rustc::ty::subst::{Kind, Subst, InternalSubsts, SubstsRef};
use rustc::ty::wf::object_region_bounds;
@ -922,7 +922,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
"the value of the associated type `{}` (from the trait `{}`) \
is already specified",
binding.item_name,
tcx.item_path_str(assoc_ty.container.id()))
tcx.def_path_str(assoc_ty.container.id()))
.span_label(binding.span, "re-bound here")
.span_label(*prev_span, format!("`{}` bound here first", binding.item_name))
.emit();
@ -959,7 +959,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
/// removing the dummy `Self` type (`TRAIT_OBJECT_DUMMY_SELF`).
fn trait_ref_to_existential(&self, trait_ref: ty::TraitRef<'tcx>)
-> ty::ExistentialTraitRef<'tcx> {
assert_eq!(trait_ref.self_ty().sty, TRAIT_OBJECT_DUMMY_SELF);
if trait_ref.self_ty().sty != TRAIT_OBJECT_DUMMY_SELF {
bug!("trait_ref_to_existential called on {:?} with non-dummy Self", trait_ref);
}
ty::ExistentialTraitRef::erase_self_ty(self.tcx(), trait_ref)
}
@ -1069,7 +1071,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
format!(
"`{}` (from the trait `{}`)",
assoc_item.ident,
tcx.item_path_str(trait_def_id),
tcx.def_path_str(trait_def_id),
)
}).collect::<Vec<_>>().join(", ");
let mut err = struct_span_err!(
@ -1450,14 +1452,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
-> Ty<'tcx>
{
let tcx = self.tcx();
let trait_def_id = tcx.parent_def_id(item_def_id).unwrap();
let trait_def_id = tcx.parent(item_def_id).unwrap();
self.prohibit_generics(slice::from_ref(item_segment));
let self_ty = if let Some(ty) = opt_self_ty {
ty
} else {
let path_str = tcx.item_path_str(trait_def_id);
let path_str = tcx.def_path_str(trait_def_id);
self.report_ambiguous_associated_type(span,
"Type",
&path_str,
@ -1619,7 +1621,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
} else if last >= 1 && segments[last - 1].args.is_some() {
// Everything but the penultimate segment should have no
// parameters at all.
let enum_def_id = tcx.parent_def_id(def_id).unwrap();
let enum_def_id = tcx.parent(def_id).unwrap();
(enum_def_id, last - 1)
} else {
// FIXME: lint here recommending `Enum::<...>::Variant` form

View file

@ -88,7 +88,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// See the examples in `run-pass/match-defbm*.rs`.
let mut pat_adjustments = vec![];
while let ty::Ref(_, inner_ty, inner_mutability) = exp_ty.sty {
debug!("inspecting {:?} with type {:?}", exp_ty, exp_ty.sty);
debug!("inspecting {:?}", exp_ty);
debug!("current discriminant is Ref, inserting implicit deref");
// Preserve the reference type. We'll need it later during HAIR lowering.
@ -894,7 +894,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
subpats.len() < variant.fields.len() && ddpos.is_some() {
let substs = match pat_ty.sty {
ty::Adt(_, substs) => substs,
ref ty => bug!("unexpected pattern type {:?}", ty),
_ => bug!("unexpected pattern type {:?}", pat_ty),
};
for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs);
@ -1001,13 +1001,13 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
E0026,
"{} `{}` does not have {}",
kind_name,
tcx.item_path_str(variant.did),
tcx.def_path_str(variant.did),
field_names);
if let Some((span, ident)) = inexistent_fields.last() {
err.span_label(*span,
format!("{} `{}` does not have {} field{}",
kind_name,
tcx.item_path_str(variant.did),
tcx.def_path_str(variant.did),
t,
plural));
if plural == "" {

View file

@ -719,7 +719,7 @@ fn compare_number_of_method_arguments<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
trait `{}` has {}",
trait_m.ident,
potentially_plural_count(impl_number_args, "parameter"),
tcx.item_path_str(trait_m.def_id),
tcx.def_path_str(trait_m.def_id),
trait_number_args);
if let Some(trait_span) = trait_span {
err.span_label(trait_span, format!("trait requires {}",

View file

@ -130,7 +130,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let sole_field = &variant.fields[0];
let sole_field_ty = sole_field.ty(self.tcx, substs);
if self.can_coerce(expr_ty, sole_field_ty) {
let variant_path = self.tcx.item_path_str(variant.did);
let variant_path = self.tcx.def_path_str(variant.did);
// FIXME #56861: DRYer prelude filtering
Some(variant_path.trim_start_matches("std::prelude::v1::").to_string())
} else {

View file

@ -1195,7 +1195,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
// `report_method_error()`.
diag.help(&format!(
"call with fully qualified syntax `{}(...)` to keep using the current method",
self.tcx.item_path_str(stable_pick.item.def_id),
self.tcx.def_path_str(stable_pick.item.def_id),
));
if nightly_options::is_nightly_build() {
@ -1203,7 +1203,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
diag.help(&format!(
"add #![feature({})] to the crate attributes to enable `{}`",
feature,
self.tcx.item_path_str(candidate.item.def_id),
self.tcx.def_path_str(candidate.item.def_id),
));
}
}

View file

@ -15,7 +15,7 @@ use rustc::hir::print;
use rustc::infer::type_variable::TypeVariableOrigin;
use rustc::traits::Obligation;
use rustc::ty::{self, Adt, Ty, TyCtxt, ToPolyTraitRef, ToPredicate, TypeFoldable};
use rustc::ty::item_path::with_crate_prefix;
use rustc::ty::print::with_crate_prefix;
use syntax_pos::{Span, FileName};
use syntax::ast;
use syntax::util::lev_distance::find_best_match_for_name;
@ -102,7 +102,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
None => String::new(),
Some(trait_ref) => {
format!(" of the trait `{}`",
self.tcx.item_path_str(trait_ref.def_id))
self.tcx.def_path_str(trait_ref.def_id))
}
};
@ -135,16 +135,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
item_span,
"candidate #{} is defined in the trait `{}`",
idx + 1,
self.tcx.item_path_str(trait_did));
self.tcx.def_path_str(trait_did));
} else {
span_note!(err,
item_span,
"the candidate is defined in the trait `{}`",
self.tcx.item_path_str(trait_did));
self.tcx.def_path_str(trait_did));
}
err.help(&format!("to disambiguate the method call, write `{}::{}({}{})` \
instead",
self.tcx.item_path_str(trait_did),
self.tcx.def_path_str(trait_did),
item_name,
if rcvr_ty.is_region_ptr() && args.is_some() {
if rcvr_ty.is_mutable_pointer() {
@ -516,7 +516,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
};
format!(
"use {};\n{}",
with_crate_prefix(|| self.tcx.item_path_str(*did)),
with_crate_prefix(|| self.tcx.def_path_str(*did)),
additional_newline
)
});
@ -530,14 +530,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
&format!(
"\ncandidate #{}: `use {};`",
i + 1,
with_crate_prefix(|| self.tcx.item_path_str(*trait_did))
with_crate_prefix(|| self.tcx.def_path_str(*trait_did))
)
);
} else {
msg.push_str(
&format!(
"\n`use {};`",
with_crate_prefix(|| self.tcx.item_path_str(*trait_did))
with_crate_prefix(|| self.tcx.def_path_str(*trait_did))
)
);
}
@ -638,7 +638,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
for (i, trait_info) in candidates.iter().enumerate() {
msg.push_str(&format!("\ncandidate #{}: `{}`",
i + 1,
self.tcx.item_path_str(trait_info.def_id)));
self.tcx.def_path_str(trait_info.def_id)));
}
err.note(&msg[..]);
}

View file

@ -1328,7 +1328,7 @@ pub fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Ite
debug!(
"check_item_type(it.hir_id={}, it.name={})",
it.hir_id,
tcx.item_path_str(tcx.hir().local_def_id_from_hir_id(it.hir_id))
tcx.def_path_str(tcx.hir().local_def_id_from_hir_id(it.hir_id))
);
let _indenter = indenter();
match it.node {
@ -3534,7 +3534,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
autoderef.unambiguous_final_ty(self);
if let Some((did, field_ty)) = private_candidate {
let struct_path = self.tcx().item_path_str(did);
let struct_path = self.tcx().def_path_str(did);
let mut err = struct_span_err!(self.tcx().sess, expr.span, E0616,
"field `{}` of struct `{}` is private",
field, struct_path);
@ -3885,7 +3885,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
ty::Adt(adt, substs) => {
Some((adt.variant_of_def(def), adt.did, substs))
}
_ => bug!("unexpected type: {:?}", ty.sty)
_ => bug!("unexpected type: {:?}", ty)
}
}
Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) |
@ -5226,8 +5226,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.node);
let sp = ty.span;
let ty = AstConv::ast_ty_to_ty(self, ty);
debug!("suggest_missing_return_type: return type sty {:?}", ty.sty);
debug!("suggest_missing_return_type: expected type sty {:?}", ty.sty);
debug!("suggest_missing_return_type: return type {:?}", ty);
debug!("suggest_missing_return_type: expected type {:?}", ty);
if ty.sty == expected.sty {
err.span_label(sp, format!("expected `{}` because of return type",
expected));

View file

@ -93,19 +93,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
);
// Extract the type of the closure.
let (closure_def_id, substs) = match self.node_ty(closure_hir_id).sty {
let ty = self.node_ty(closure_hir_id);
let (closure_def_id, substs) = match ty.sty {
ty::Closure(def_id, substs) => (def_id, UpvarSubsts::Closure(substs)),
ty::Generator(def_id, substs, _) => (def_id, UpvarSubsts::Generator(substs)),
ty::Error => {
// #51714: skip analysis when we have already encountered type errors
return;
}
ref t => {
_ => {
span_bug!(
span,
"type of closure expr {:?} is not a closure {:?}",
closure_hir_id,
t
ty
);
}
};

View file

@ -68,7 +68,7 @@ pub fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: Def
debug!("check_item_well_formed(it.hir_id={:?}, it.name={})",
item.hir_id,
tcx.item_path_str(def_id));
tcx.def_path_str(def_id));
match item.node {
// Right now we check that every default trait implementation
@ -618,7 +618,7 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>(
span: Span,
ty: Ty<'tcx>,
) -> Vec<ty::Predicate<'tcx>> {
trace!("check_existential_types: {:?}, {:?}", ty, ty.sty);
trace!("check_existential_types: {:?}", ty);
let mut substituted_predicates = Vec::new();
ty.fold_with(&mut ty::fold::BottomUpFolder {
tcx: fcx.tcx,
@ -976,7 +976,7 @@ fn report_bivariance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
if let Some(def_id) = suggested_marker_id {
err.help(&format!("consider removing `{}` or using a marker such as `{}`",
param_name,
tcx.item_path_str(def_id)));
tcx.def_path_str(def_id)));
}
err.emit();
}

View file

@ -472,7 +472,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
instantiated_ty.fold_with(&mut BottomUpFolder {
tcx: self.tcx().global_tcx(),
fldop: |ty| {
trace!("checking type {:?}: {:#?}", ty, ty.sty);
trace!("checking type {:?}", ty);
// find a type parameter
if let ty::Param(..) = ty.sty {
// look it up in the substitution list

View file

@ -198,8 +198,8 @@ fn visit_implementation_of_dispatch_from_dyn<'a, 'tcx>(
if def_a.is_struct() && def_b.is_struct() =>
{
if def_a != def_b {
let source_path = tcx.item_path_str(def_a.did);
let target_path = tcx.item_path_str(def_b.did);
let source_path = tcx.def_path_str(def_a.did);
let target_path = tcx.def_path_str(def_b.did);
create_err(
&format!(
@ -388,8 +388,8 @@ pub fn coerce_unsized_info<'a, 'gcx>(gcx: TyCtxt<'a, 'gcx, 'gcx>,
(&ty::Adt(def_a, substs_a), &ty::Adt(def_b, substs_b)) if def_a.is_struct() &&
def_b.is_struct() => {
if def_a != def_b {
let source_path = gcx.item_path_str(def_a.did);
let target_path = gcx.item_path_str(def_b.did);
let source_path = gcx.def_path_str(def_a.did);
let target_path = gcx.def_path_str(def_b.did);
span_err!(gcx.sess,
span,
E0377,

View file

@ -28,7 +28,7 @@ fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) {
if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) {
debug!("(checking implementation) adding impl for trait '{:?}', item '{}'",
trait_ref,
tcx.item_path_str(impl_def_id));
tcx.def_path_str(impl_def_id));
// Skip impls where one of the self type is an error type.
// This occurs with e.g., resolve failures (#30589).
@ -204,10 +204,10 @@ fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeI
E0371,
"the object type `{}` automatically implements the trait `{}`",
trait_ref.self_ty(),
tcx.item_path_str(trait_def_id))
tcx.def_path_str(trait_def_id))
.span_label(sp, format!("`{}` automatically implements trait `{}`",
trait_ref.self_ty(),
tcx.item_path_str(trait_def_id)))
tcx.def_path_str(trait_def_id)))
.emit();
}
}

View file

@ -121,7 +121,7 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> {
format!("cross-crate traits with a default impl, like `{}`, \
can only be implemented for a struct/enum type \
defined in the current crate",
self.tcx.item_path_str(trait_def_id)),
self.tcx.def_path_str(trait_def_id)),
"can't implement cross-crate trait for type in another crate"
))
}
@ -129,7 +129,7 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> {
_ => {
Some((format!("cross-crate traits with a default impl, like `{}`, can \
only be implemented for a struct/enum type, not `{}`",
self.tcx.item_path_str(trait_def_id),
self.tcx.def_path_str(trait_def_id),
self_ty),
"can't implement cross-crate trait with a default impl for \
non-struct/enum type"))

View file

@ -131,7 +131,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
fn build_constraints_for_item(&mut self, def_id: DefId) {
let tcx = self.tcx();
debug!("build_constraints_for_item({})", tcx.item_path_str(def_id));
debug!("build_constraints_for_item({})", tcx.def_path_str(def_id));
// Skip items with no generics - there's nothing to infer in them.
if tcx.generics_of(def_id).count() == 0 {

View file

@ -20,8 +20,9 @@ use rustc::mir::interpret::GlobalId;
use rustc::hir::{self, GenericArg, HirVec};
use rustc::hir::def::{self, Def, CtorKind};
use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc::ty::subst::{InternalSubsts, SubstsRef};
use rustc::ty::{self, TyCtxt, Region, RegionVid, Ty, AdtKind};
use rustc::hir::map::DisambiguatedDefPathData;
use rustc::ty::subst::{Kind, InternalSubsts, SubstsRef};
use rustc::ty::{self, DefIdTree, TyCtxt, Region, RegionVid, Ty, AdtKind};
use rustc::ty::fold::TypeFolder;
use rustc::ty::layout::VariantIdx;
use rustc::util::nodemap::{FxHashMap, FxHashSet};
@ -3971,7 +3972,7 @@ pub fn register_def(cx: &DocContext<'_>, def: Def) -> DefId {
Def::ForeignTy(i) => (i, TypeKind::Foreign),
Def::Const(i) => (i, TypeKind::Const),
Def::Static(i, _) => (i, TypeKind::Static),
Def::Variant(i) => (cx.tcx.parent_def_id(i).expect("cannot get parent def id"),
Def::Variant(i) => (cx.tcx.parent(i).expect("cannot get parent def id"),
TypeKind::Enum),
Def::Macro(i, mac_kind) => match mac_kind {
MacroKind::Bang => (i, TypeKind::Macro),
@ -4223,32 +4224,113 @@ pub fn path_to_def(tcx: &TyCtxt<'_, '_, '_>, path: &[&str]) -> Option<DefId> {
}
}
pub fn get_path_for_type<F>(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, def_ctor: F) -> hir::Path
where F: Fn(DefId) -> Def {
#[derive(Debug)]
struct AbsolutePathBuffer {
names: Vec<String>,
pub fn get_path_for_type(
tcx: TyCtxt<'_, '_, '_>,
def_id: DefId,
def_ctor: impl Fn(DefId) -> Def,
) -> hir::Path {
use rustc::ty::print::Printer;
struct AbsolutePathPrinter<'a, 'tcx> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
impl ty::item_path::ItemPathBuffer for AbsolutePathBuffer {
fn root_mode(&self) -> &ty::item_path::RootMode {
const ABSOLUTE: &'static ty::item_path::RootMode = &ty::item_path::RootMode::Absolute;
ABSOLUTE
impl Printer<'tcx, 'tcx> for AbsolutePathPrinter<'_, 'tcx> {
type Error = !;
type Path = Vec<String>;
type Region = ();
type Type = ();
type DynExistential = ();
fn tcx(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
self.tcx
}
fn push(&mut self, text: &str) {
self.names.push(text.to_owned());
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).to_string()])
}
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) => format!("{:?}", trait_ref),
None => format!("<{}>", self_ty),
}])
}
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) => {
format!("<impl {} for {}>", trait_ref, self_ty)
}
None => format!("<impl {}>", self_ty),
});
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().to_string());
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 mut apb = AbsolutePathBuffer { names: vec![] };
tcx.push_item_path(&mut apb, def_id, false);
let names = AbsolutePathPrinter { tcx: tcx.global_tcx() }
.print_def_path(def_id, &[])
.unwrap();
hir::Path {
span: DUMMY_SP,
def: def_ctor(def_id),
segments: hir::HirVec::from_vec(apb.names.iter().map(|s| hir::PathSegment {
segments: hir::HirVec::from_vec(names.iter().map(|s| hir::PathSegment {
ident: ast::Ident::from_str(&s),
hir_id: None,
def: None,

View file

@ -5,8 +5,10 @@
#![feature(bind_by_move_pattern_guards)]
#![feature(rustc_private)]
#![feature(arbitrary_self_types)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(in_band_lifetimes)]
#![feature(nll)]
#![feature(set_stdio)]
#![feature(test)]
@ -16,6 +18,7 @@
#![feature(const_fn)]
#![feature(drain_filter)]
#![feature(inner_deref)]
#![feature(never_type)]
#![recursion_limit="256"]

View file

@ -1042,7 +1042,7 @@ pub const BUILTIN_ATTRIBUTES: &[(&str, AttributeType, AttributeTemplate, Attribu
"rustc_attrs",
"internal rustc attributes will never be stable",
cfg_fn!(rustc_attrs))),
("rustc_item_path", Whitelisted, template!(Word), Gated(Stability::Unstable,
("rustc_def_path", Whitelisted, template!(Word), Gated(Stability::Unstable,
"rustc_attrs",
"internal rustc attributes will never be stable",
cfg_fn!(rustc_attrs))),

View file

@ -35,7 +35,7 @@ fn main() {
// _2 = move _3;
// StorageDead(_3);
// StorageLive(_4);
// _4 = std::option::Option<std::boxed::Box<u32>>::None;
// _4 = std::option::Option::<std::boxed::Box<u32>>::None;
// FakeRead(ForLet, _4);
// AscribeUserType(_4, o, UserTypeProjection { base: UserType(1), projs: [] });
// StorageLive(_5);

View file

@ -1,7 +1,7 @@
// Regression test for #41697. Using dump-mir was triggering
// artificial cycles: during type-checking, we had to get the MIR for
// the constant expressions in `[u8; 2]`, which in turn would trigger
// an attempt to get the item-path, which in turn would request the
// an attempt to get the def-path, which in turn would request the
// types of the impl, which would trigger a cycle. We suppressed this
// cycle now by forcing mir-dump to avoid asking for types of an impl.

View file

@ -42,7 +42,7 @@ fn main() {
// START rustc.full_tested_match.QualifyAndPromoteConstants.after.mir
// bb0: {
// ...
// _2 = std::option::Option<i32>::Some(const 42i32,);
// _2 = std::option::Option::<i32>::Some(const 42i32,);
// FakeRead(ForMatchedPlace, _2);
// _3 = discriminant(_2);
// switchInt(move _3) -> [0isize: bb4, 1isize: bb2, otherwise: bb7];
@ -111,7 +111,7 @@ fn main() {
// START rustc.full_tested_match2.QualifyAndPromoteConstants.before.mir
// bb0: {
// ...
// _2 = std::option::Option<i32>::Some(const 42i32,);
// _2 = std::option::Option::<i32>::Some(const 42i32,);
// FakeRead(ForMatchedPlace, _2);
// _3 = discriminant(_2);
// switchInt(move _3) -> [0isize: bb3, 1isize: bb2, otherwise: bb7];
@ -180,7 +180,7 @@ fn main() {
// START rustc.main.QualifyAndPromoteConstants.before.mir
// bb0: {
// ...
// _2 = std::option::Option<i32>::Some(const 1i32,);
// _2 = std::option::Option::<i32>::Some(const 1i32,);
// FakeRead(ForMatchedPlace, _2);
// _3 = discriminant(_2);
// switchInt(move _3) -> [1isize: bb2, otherwise: bb3];

View file

@ -98,7 +98,7 @@ fn main() {
// }
// END rustc.main.EraseRegions.after.mir
// START rustc.main-{{closure}}.EraseRegions.after.mir
// fn main::{{closure}}(_1: &[closure@HirId { owner: DefIndex(0:7), local_id: 70 }], _2: &i32) -> &i32 {
// fn main::{{closure}}#0(_1: &[closure@HirId { owner: DefIndex(0:7), local_id: 70 }], _2: &i32) -> &i32 {
// ...
// bb0: {
// Retag([fn entry] _1);

View file

@ -18,7 +18,7 @@ fn main() {
// StorageLive(_4);
// StorageLive(_5);
// _5 = _1;
// _4 = std::option::Option<i32>::Some(move _5,);
// _4 = std::option::Option::<i32>::Some(move _5,);
// StorageDead(_5);
// _3 = &_4;
// FakeRead(ForLet, _3);

View file

@ -32,27 +32,27 @@ pub fn bar() ({
(($crate::fmt::format as
for<'r> fn(std::fmt::Arguments<'r>) -> std::string::String {std::fmt::format})(((<$crate::fmt::Arguments>::new_v1
as
fn(&[&str], &[std::fmt::ArgumentV1<'_>]) -> std::fmt::Arguments<'_> {std::fmt::Arguments<'_>::new_v1})((&([("test"
fn(&[&str], &[std::fmt::ArgumentV1<'_>]) -> std::fmt::Arguments<'_> {std::fmt::Arguments::<'_>::new_v1})((&([("test"
as
&'static str)]
as
&'static str)]
[&str; 1])
as
[&str; 1])
as
&[&str; 1]),
(&(match (()
&[&str; 1]),
(&(match (()
as
())
{
()
=>
([]
as
())
{
()
=>
([]
as
[std::fmt::ArgumentV1<'_>; 0]),
}
[std::fmt::ArgumentV1<'_>; 0]),
}
as
[std::fmt::ArgumentV1<'_>; 0])
as
[std::fmt::ArgumentV1<'_>; 0])
as
&[std::fmt::ArgumentV1<'_>; 0]))
&[std::fmt::ArgumentV1<'_>; 0]))
as
std::fmt::Arguments<'_>))
as std::string::String);

View file

@ -29,7 +29,7 @@ LL | baz(&a);
|
= note: expected type `usize`
found type `Bar`
= note: required for the cast to the object type `dyn Foo<A=Bar>`
= note: required for the cast to the object type `dyn Foo<A = Bar>`
error: aborting due to 3 previous errors

View file

@ -6,7 +6,7 @@ LL | let _: &I32Iterator<Item = u32> = &vec![42].into_iter();
|
= note: expected type `u32`
found type `i32`
= note: required for the cast to the object type `dyn I32Iterator<Item=u32, Item=i32>`
= note: required for the cast to the object type `dyn I32Iterator<Item = u32, Item = i32>`
error: aborting due to previous error

View file

@ -22,7 +22,7 @@ LL | let x: Vec<Trait + Sized> = Vec::new();
|
= help: the trait `std::marker::Sized` is not implemented for `dyn Trait`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required by `<std::vec::Vec<T>>::new`
= note: required by `std::vec::Vec::<T>::new`
error: aborting due to 3 previous errors

Some files were not shown because too many files have changed in this diff Show more