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:
commit
ad8a3eb039
143 changed files with 3405 additions and 2931 deletions
|
@ -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 \
|
||||
|
|
|
@ -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 });
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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(" ");
|
||||
}
|
||||
|
|
|
@ -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![(
|
||||
|
|
|
@ -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
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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('>');
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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(_) => {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
327
src/librustc/ty/print/mod.rs
Normal file
327
src/librustc/ty/print/mod.rs
Normal 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)
|
||||
}
|
||||
}
|
1621
src/librustc/ty/print/pretty.rs
Normal file
1621
src/librustc/ty/print/pretty.rs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(_)) =>
|
||||
{
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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(<).map(|lt| lt.into()),
|
||||
UnpackedKind::Type(ty) => tcx.lift(&ty).map(|ty| ty.into()),
|
||||
UnpackedKind::Const(ct) => tcx.lift(&ct).map(|ct| ct.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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)
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 `{}`",
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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, ") -> {}", escape(mir.return_ty()))?;
|
||||
write!(w, ") -> {}", escape(&mir.return_ty()))?;
|
||||
write!(w, r#"<br align="left"/>"#)?;
|
||||
|
||||
for local in mir.vars_and_temps_iter() {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 == "" {
|
||||
|
|
|
@ -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 {}",
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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[..]);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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"]
|
||||
|
||||
|
|
|
@ -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))),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue