Merge from rustc
This commit is contained in:
commit
036929d86d
433 changed files with 3551 additions and 2190 deletions
19
Cargo.lock
19
Cargo.lock
|
|
@ -782,7 +782,7 @@ dependencies = [
|
|||
"declare_clippy_lint",
|
||||
"if_chain",
|
||||
"itertools",
|
||||
"pulldown-cmark 0.9.2",
|
||||
"pulldown-cmark",
|
||||
"quine-mc_cluskey",
|
||||
"regex-syntax",
|
||||
"rustc-semver",
|
||||
|
|
@ -2555,7 +2555,7 @@ dependencies = [
|
|||
"memchr",
|
||||
"once_cell",
|
||||
"opener",
|
||||
"pulldown-cmark 0.9.2",
|
||||
"pulldown-cmark",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
|
@ -2572,7 +2572,7 @@ dependencies = [
|
|||
"anyhow",
|
||||
"handlebars 3.5.5",
|
||||
"pretty_assertions",
|
||||
"pulldown-cmark 0.7.2",
|
||||
"pulldown-cmark",
|
||||
"same-file",
|
||||
"serde_json",
|
||||
"url",
|
||||
|
|
@ -3269,17 +3269,6 @@ dependencies = [
|
|||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pulldown-cmark"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca36dea94d187597e104a5c8e4b07576a8a45aa5db48a65e12940d3eb7461f55"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"memchr",
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pulldown-cmark"
|
||||
version = "0.9.2"
|
||||
|
|
@ -4583,7 +4572,7 @@ name = "rustc_resolve"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"pulldown-cmark 0.9.2",
|
||||
"pulldown-cmark",
|
||||
"rustc_arena",
|
||||
"rustc_ast",
|
||||
"rustc_ast_pretty",
|
||||
|
|
|
|||
|
|
@ -171,7 +171,9 @@ pub struct TargetDataLayout {
|
|||
|
||||
pub instruction_address_space: AddressSpace,
|
||||
|
||||
/// Minimum size of #[repr(C)] enums (default I32 bits)
|
||||
/// Minimum size of #[repr(C)] enums (default c_int::BITS, usually 32)
|
||||
/// Note: This isn't in LLVM's data layout string, it is `short_enum`
|
||||
/// so the only valid spec for LLVM is c_int::BITS or 8
|
||||
pub c_enum_min_size: Integer,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ impl<'a> AstValidator<'a> {
|
|||
|
||||
self.session.emit_err(InvalidVisibility {
|
||||
span: vis.span,
|
||||
implied: if vis.kind.is_pub() { Some(vis.span) } else { None },
|
||||
implied: vis.kind.is_pub().then_some(vis.span),
|
||||
note,
|
||||
});
|
||||
}
|
||||
|
|
@ -294,27 +294,6 @@ impl<'a> AstValidator<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_late_bound_lifetime_defs(&self, params: &[GenericParam]) {
|
||||
// Check only lifetime parameters are present and that the lifetime
|
||||
// parameters that are present have no bounds.
|
||||
let non_lt_param_spans: Vec<_> = params
|
||||
.iter()
|
||||
.filter_map(|param| match param.kind {
|
||||
GenericParamKind::Lifetime { .. } => {
|
||||
if !param.bounds.is_empty() {
|
||||
let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect();
|
||||
self.session.emit_err(ForbiddenLifetimeBound { spans });
|
||||
}
|
||||
None
|
||||
}
|
||||
_ => Some(param.ident.span),
|
||||
})
|
||||
.collect();
|
||||
if !non_lt_param_spans.is_empty() {
|
||||
self.session.emit_err(ForbiddenNonLifetimeParam { spans: non_lt_param_spans });
|
||||
}
|
||||
}
|
||||
|
||||
fn check_fn_decl(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) {
|
||||
self.check_decl_num_args(fn_decl);
|
||||
self.check_decl_cvaradic_pos(fn_decl);
|
||||
|
|
@ -745,7 +724,6 @@ impl<'a> AstValidator<'a> {
|
|||
)
|
||||
.emit();
|
||||
});
|
||||
self.check_late_bound_lifetime_defs(&bfty.generic_params);
|
||||
if let Extern::Implicit(_) = bfty.ext {
|
||||
let sig_span = self.session.source_map().next_point(ty.span.shrink_to_lo());
|
||||
self.maybe_lint_missing_abi(sig_span, ty.id);
|
||||
|
|
@ -1318,9 +1296,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
for predicate in &generics.where_clause.predicates {
|
||||
match predicate {
|
||||
WherePredicate::BoundPredicate(bound_pred) => {
|
||||
// A type binding, eg `for<'c> Foo: Send+Clone+'c`
|
||||
self.check_late_bound_lifetime_defs(&bound_pred.bound_generic_params);
|
||||
|
||||
// This is slightly complicated. Our representation for poly-trait-refs contains a single
|
||||
// binder and thus we only allow a single level of quantification. However,
|
||||
// the syntax of Rust permits quantification in two places in where clauses,
|
||||
|
|
@ -1396,11 +1371,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
visit::walk_param_bound(self, bound)
|
||||
}
|
||||
|
||||
fn visit_poly_trait_ref(&mut self, t: &'a PolyTraitRef) {
|
||||
self.check_late_bound_lifetime_defs(&t.bound_generic_params);
|
||||
visit::walk_poly_trait_ref(self, t);
|
||||
}
|
||||
|
||||
fn visit_variant_data(&mut self, s: &'a VariantData) {
|
||||
self.with_banned_assoc_ty_bound(|this| visit::walk_struct_def(this, s))
|
||||
}
|
||||
|
|
@ -1437,10 +1407,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
.emit();
|
||||
}
|
||||
|
||||
if let FnKind::Closure(ClosureBinder::For { generic_params, .. }, ..) = fk {
|
||||
self.check_late_bound_lifetime_defs(generic_params);
|
||||
}
|
||||
|
||||
if let FnKind::Fn(
|
||||
_,
|
||||
_,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ use rustc_span::symbol::sym;
|
|||
use rustc_span::Span;
|
||||
use rustc_target::spec::abi;
|
||||
|
||||
use crate::errors::ForbiddenLifetimeBound;
|
||||
|
||||
macro_rules! gate_feature_fn {
|
||||
($visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $help: expr) => {{
|
||||
let (visitor, has_feature, span, name, explain, help) =
|
||||
|
|
@ -136,6 +138,34 @@ impl<'a> PostExpansionVisitor<'a> {
|
|||
}
|
||||
ImplTraitVisitor { vis: self }.visit_ty(ty);
|
||||
}
|
||||
|
||||
fn check_late_bound_lifetime_defs(&self, params: &[ast::GenericParam]) {
|
||||
// Check only lifetime parameters are present and that the lifetime
|
||||
// parameters that are present have no bounds.
|
||||
let non_lt_param_spans: Vec<_> = params
|
||||
.iter()
|
||||
.filter_map(|param| match param.kind {
|
||||
ast::GenericParamKind::Lifetime { .. } => None,
|
||||
_ => Some(param.ident.span),
|
||||
})
|
||||
.collect();
|
||||
// FIXME: gate_feature_post doesn't really handle multispans...
|
||||
if !non_lt_param_spans.is_empty() && !self.features.non_lifetime_binders {
|
||||
feature_err(
|
||||
&self.sess.parse_sess,
|
||||
sym::non_lifetime_binders,
|
||||
non_lt_param_spans,
|
||||
rustc_errors::fluent::ast_passes_forbidden_non_lifetime_param,
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
for param in params {
|
||||
if !param.bounds.is_empty() {
|
||||
let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect();
|
||||
self.sess.emit_err(ForbiddenLifetimeBound { spans });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
|
|
@ -147,7 +177,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
|||
..
|
||||
}) = attr_info
|
||||
{
|
||||
gate_feature_fn!(self, has_feature, attr.span, *name, descr);
|
||||
gate_feature_fn!(self, has_feature, attr.span, *name, *descr);
|
||||
}
|
||||
// Check unstable flavors of the `#[doc]` attribute.
|
||||
if attr.has_name(sym::doc) {
|
||||
|
|
@ -306,6 +336,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
|||
ast::TyKind::BareFn(bare_fn_ty) => {
|
||||
// Function pointers cannot be `const`
|
||||
self.check_extern(bare_fn_ty.ext, ast::Const::No);
|
||||
self.check_late_bound_lifetime_defs(&bare_fn_ty.generic_params);
|
||||
}
|
||||
ast::TyKind::Never => {
|
||||
gate_feature_post!(&self, never_type, ty.span, "the `!` type is experimental");
|
||||
|
|
@ -318,6 +349,19 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
|||
visit::walk_ty(self, ty)
|
||||
}
|
||||
|
||||
fn visit_generics(&mut self, g: &'a ast::Generics) {
|
||||
for predicate in &g.where_clause.predicates {
|
||||
match predicate {
|
||||
ast::WherePredicate::BoundPredicate(bound_pred) => {
|
||||
// A type binding, eg `for<'c> Foo: Send+Clone+'c`
|
||||
self.check_late_bound_lifetime_defs(&bound_pred.bound_generic_params);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
visit::walk_generics(self, g);
|
||||
}
|
||||
|
||||
fn visit_fn_ret_ty(&mut self, ret_ty: &'a ast::FnRetTy) {
|
||||
if let ast::FnRetTy::Ty(output_ty) = ret_ty {
|
||||
if let ast::TyKind::Never = output_ty.kind {
|
||||
|
|
@ -437,12 +481,21 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
|||
visit::walk_pat(self, pattern)
|
||||
}
|
||||
|
||||
fn visit_poly_trait_ref(&mut self, t: &'a ast::PolyTraitRef) {
|
||||
self.check_late_bound_lifetime_defs(&t.bound_generic_params);
|
||||
visit::walk_poly_trait_ref(self, t);
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) {
|
||||
if let Some(header) = fn_kind.header() {
|
||||
// Stability of const fn methods are covered in `visit_assoc_item` below.
|
||||
self.check_extern(header.ext, header.constness);
|
||||
}
|
||||
|
||||
if let FnKind::Closure(ast::ClosureBinder::For { generic_params, .. }, ..) = fn_kind {
|
||||
self.check_late_bound_lifetime_defs(generic_params);
|
||||
}
|
||||
|
||||
if fn_kind.ctxt() != Some(FnCtxt::Foreign) && fn_kind.decl().c_variadic() {
|
||||
gate_feature_post!(&self, c_variadic, span, "C-variadic functions are unstable");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -731,7 +731,7 @@ pub fn eval_condition(
|
|||
sess,
|
||||
sym::cfg_target_compact,
|
||||
cfg.span,
|
||||
&"compact `cfg(target(..))` is experimental and subject to change"
|
||||
"compact `cfg(target(..))` is experimental and subject to change"
|
||||
).emit();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -180,20 +180,20 @@ trait TypeOpInfo<'tcx> {
|
|||
return;
|
||||
};
|
||||
|
||||
let placeholder_region = tcx.mk_region(ty::RePlaceholder(ty::Placeholder {
|
||||
let placeholder_region = tcx.mk_re_placeholder(ty::Placeholder {
|
||||
name: placeholder.name,
|
||||
universe: adjusted_universe.into(),
|
||||
}));
|
||||
});
|
||||
|
||||
let error_region =
|
||||
if let RegionElement::PlaceholderRegion(error_placeholder) = error_element {
|
||||
let adjusted_universe =
|
||||
error_placeholder.universe.as_u32().checked_sub(base_universe.as_u32());
|
||||
adjusted_universe.map(|adjusted| {
|
||||
tcx.mk_region(ty::RePlaceholder(ty::Placeholder {
|
||||
tcx.mk_re_placeholder(ty::Placeholder {
|
||||
name: error_placeholder.name,
|
||||
universe: adjusted.into(),
|
||||
}))
|
||||
})
|
||||
})
|
||||
} else {
|
||||
None
|
||||
|
|
@ -390,7 +390,7 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
|
|||
error_region,
|
||||
®ion_constraints,
|
||||
|vid| ocx.infcx.region_var_origin(vid),
|
||||
|vid| ocx.infcx.universe_of_region(ocx.infcx.tcx.mk_region(ty::ReVar(vid))),
|
||||
|vid| ocx.infcx.universe_of_region(ocx.infcx.tcx.mk_re_var(vid)),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -411,7 +411,7 @@ fn try_extract_error_from_region_constraints<'tcx>(
|
|||
}
|
||||
// FIXME: Should this check the universe of the var?
|
||||
Constraint::VarSubReg(vid, sup) if sup == placeholder_region => {
|
||||
Some((infcx.tcx.mk_region(ty::ReVar(vid)), cause.clone()))
|
||||
Some((infcx.tcx.mk_re_var(vid), cause.clone()))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1186,11 +1186,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
return None;
|
||||
};
|
||||
debug!("checking call args for uses of inner_param: {:?}", args);
|
||||
if args.contains(&Operand::Move(inner_param)) {
|
||||
Some((loc, term))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
args.contains(&Operand::Move(inner_param)).then_some((loc, term))
|
||||
}) else {
|
||||
debug!("no uses of inner_param found as a by-move call arg");
|
||||
return;
|
||||
|
|
@ -2596,7 +2592,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
if is_closure {
|
||||
None
|
||||
} else {
|
||||
let ty = self.infcx.tcx.type_of(self.mir_def_id());
|
||||
let ty = self.infcx.tcx.type_of(self.mir_def_id()).subst_identity();
|
||||
match ty.kind() {
|
||||
ty::FnDef(_, _) | ty::FnPtr(_) => self.annotate_fn_sig(
|
||||
self.mir_def_id(),
|
||||
|
|
|
|||
|
|
@ -1185,7 +1185,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
let parent_self_ty =
|
||||
matches!(tcx.def_kind(parent_did), rustc_hir::def::DefKind::Impl { .. })
|
||||
.then_some(parent_did)
|
||||
.and_then(|did| match tcx.type_of(did).kind() {
|
||||
.and_then(|did| match tcx.type_of(did).subst_identity().kind() {
|
||||
ty::Adt(def, ..) => Some(def.did()),
|
||||
_ => None,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -575,7 +575,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
|
||||
let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty;
|
||||
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *output_ty.kind() {
|
||||
output_ty = self.infcx.tcx.type_of(def_id)
|
||||
output_ty = self.infcx.tcx.type_of(def_id).subst_identity()
|
||||
};
|
||||
|
||||
debug!("report_fnmut_error: output_ty={:?}", output_ty);
|
||||
|
|
@ -896,7 +896,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
debug!(?fn_did, ?substs);
|
||||
|
||||
// Only suggest this on function calls, not closures
|
||||
let ty = tcx.type_of(fn_did);
|
||||
let ty = tcx.type_of(fn_did).subst_identity();
|
||||
debug!("ty: {:?}, ty.kind: {:?}", ty, ty.kind());
|
||||
if let ty::Closure(_, _) = ty.kind() {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -280,17 +280,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
|||
|
||||
debug!("give_region_a_name: error_region = {:?}", error_region);
|
||||
match *error_region {
|
||||
ty::ReEarlyBound(ebr) => {
|
||||
if ebr.has_name() {
|
||||
let span = tcx.hir().span_if_local(ebr.def_id).unwrap_or(DUMMY_SP);
|
||||
Some(RegionName {
|
||||
name: ebr.name,
|
||||
source: RegionNameSource::NamedEarlyBoundRegion(span),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
ty::ReEarlyBound(ebr) => ebr.has_name().then(|| {
|
||||
let span = tcx.hir().span_if_local(ebr.def_id).unwrap_or(DUMMY_SP);
|
||||
RegionName { name: ebr.name, source: RegionNameSource::NamedEarlyBoundRegion(span) }
|
||||
}),
|
||||
|
||||
ty::ReStatic => {
|
||||
Some(RegionName { name: kw::StaticLifetime, source: RegionNameSource::Static })
|
||||
|
|
@ -856,8 +849,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
|||
return None;
|
||||
};
|
||||
|
||||
let found = tcx
|
||||
.any_free_region_meets(&tcx.type_of(region_parent), |r| *r == ty::ReEarlyBound(region));
|
||||
let found = tcx.any_free_region_meets(&tcx.type_of(region_parent).subst_identity(), |r| {
|
||||
*r == ty::ReEarlyBound(region)
|
||||
});
|
||||
|
||||
Some(RegionName {
|
||||
name: self.synthesize_region_name(),
|
||||
|
|
|
|||
|
|
@ -1297,7 +1297,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
let vid = self.to_region_vid(r);
|
||||
let scc = self.constraint_sccs.scc(vid);
|
||||
let repr = self.scc_representatives[scc];
|
||||
tcx.mk_region(ty::ReVar(repr))
|
||||
tcx.mk_re_var(repr)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -1719,7 +1719,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
}
|
||||
|
||||
// If not, report an error.
|
||||
let member_region = infcx.tcx.mk_region(ty::ReVar(member_region_vid));
|
||||
let member_region = infcx.tcx.mk_re_var(member_region_vid);
|
||||
errors_buffer.push(RegionErrorKind::UnexpectedHiddenRegion {
|
||||
span: m_c.definition_span,
|
||||
hidden_ty: m_c.hidden_ty,
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
}
|
||||
None => {
|
||||
subst_regions.push(vid);
|
||||
infcx.tcx.re_error_with_message(
|
||||
infcx.tcx.mk_re_error_with_message(
|
||||
concrete_type.span,
|
||||
"opaque type with non-universal region substs",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -50,13 +50,11 @@ pub(super) fn generate<'mir, 'tcx>(
|
|||
compute_relevant_live_locals(typeck.tcx(), &free_regions, &body);
|
||||
let facts_enabled = use_polonius || AllFacts::enabled(typeck.tcx());
|
||||
|
||||
let polonius_drop_used = if facts_enabled {
|
||||
let polonius_drop_used = facts_enabled.then(|| {
|
||||
let mut drop_used = Vec::new();
|
||||
polonius::populate_access_facts(typeck, body, location_table, move_data, &mut drop_used);
|
||||
Some(drop_used)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
drop_used
|
||||
});
|
||||
|
||||
trace::trace(
|
||||
typeck,
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
|||
upvars: &[Upvar<'tcx>],
|
||||
use_polonius: bool,
|
||||
) -> MirTypeckResults<'tcx> {
|
||||
let implicit_region_bound = infcx.tcx.mk_region(ty::ReVar(universal_regions.fr_fn_body));
|
||||
let implicit_region_bound = infcx.tcx.mk_re_var(universal_regions.fr_fn_body);
|
||||
let mut constraints = MirTypeckRegionConstraints {
|
||||
placeholder_indices: PlaceholderIndices::default(),
|
||||
placeholder_index_to_region: IndexVec::default(),
|
||||
|
|
@ -402,7 +402,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
|||
);
|
||||
}
|
||||
} else if let Some(static_def_id) = constant.check_static_ptr(tcx) {
|
||||
let unnormalized_ty = tcx.type_of(static_def_id);
|
||||
let unnormalized_ty = tcx.type_of(static_def_id).subst_identity();
|
||||
let normalized_ty = self.cx.normalize(unnormalized_ty, locations);
|
||||
let literal_ty = constant.literal.ty().builtin_deref(true).unwrap().ty;
|
||||
|
||||
|
|
@ -2589,7 +2589,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
DefKind::InlineConst => substs.as_inline_const().parent_substs(),
|
||||
other => bug!("unexpected item {:?}", other),
|
||||
};
|
||||
let parent_substs = tcx.mk_substs(parent_substs.iter());
|
||||
let parent_substs = tcx.intern_substs(parent_substs);
|
||||
|
||||
assert_eq!(typeck_root_substs.len(), parent_substs.len());
|
||||
if let Err(_) = self.eq_substs(
|
||||
|
|
|
|||
|
|
@ -480,15 +480,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
|||
LangItem::VaList,
|
||||
Some(self.infcx.tcx.def_span(self.mir_def.did)),
|
||||
);
|
||||
let region = self
|
||||
.infcx
|
||||
.tcx
|
||||
.mk_region(ty::ReVar(self.infcx.next_nll_region_var(FR).to_region_vid()));
|
||||
let va_list_ty = self
|
||||
.infcx
|
||||
.tcx
|
||||
.bound_type_of(va_list_did)
|
||||
.subst(self.infcx.tcx, &[region.into()]);
|
||||
let region =
|
||||
self.infcx.tcx.mk_re_var(self.infcx.next_nll_region_var(FR).to_region_vid());
|
||||
let va_list_ty =
|
||||
self.infcx.tcx.type_of(va_list_did).subst(self.infcx.tcx, &[region.into()]);
|
||||
|
||||
unnormalized_input_tys = self.infcx.tcx.mk_type_list(
|
||||
unnormalized_input_tys.iter().copied().chain(iter::once(va_list_ty)),
|
||||
|
|
@ -531,7 +526,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
|||
match tcx.hir().body_owner_kind(self.mir_def.did) {
|
||||
BodyOwnerKind::Closure | BodyOwnerKind::Fn => {
|
||||
let defining_ty = if self.mir_def.did.to_def_id() == typeck_root_def_id {
|
||||
tcx.type_of(typeck_root_def_id)
|
||||
tcx.type_of(typeck_root_def_id).subst_identity()
|
||||
} else {
|
||||
let tables = tcx.typeck(self.mir_def.did);
|
||||
tables.node_type(self.mir_hir_id)
|
||||
|
|
@ -636,7 +631,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
|||
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
|
||||
kind: ty::BrEnv,
|
||||
};
|
||||
let env_region = ty::ReLateBound(ty::INNERMOST, br);
|
||||
let env_region = tcx.mk_re_late_bound(ty::INNERMOST, br);
|
||||
let closure_ty = tcx.closure_env_ty(def_id, substs, env_region).unwrap();
|
||||
|
||||
// The "inputs" of the closure in the
|
||||
|
|
@ -677,7 +672,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
|||
// For a constant body, there are no inputs, and one
|
||||
// "output" (the type of the constant).
|
||||
assert_eq!(self.mir_def.did.to_def_id(), def_id);
|
||||
let ty = tcx.type_of(self.mir_def.def_id_for_type_of());
|
||||
let ty = tcx.type_of(self.mir_def.def_id_for_type_of()).subst_identity();
|
||||
let ty = indices.fold_to_region_vids(tcx, ty);
|
||||
ty::Binder::dummy(tcx.intern_type_list(&[ty]))
|
||||
}
|
||||
|
|
@ -748,10 +743,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
|||
{
|
||||
let (value, _map) = self.tcx.replace_late_bound_regions(value, |br| {
|
||||
debug!(?br);
|
||||
let liberated_region = self.tcx.mk_region(ty::ReFree(ty::FreeRegion {
|
||||
scope: all_outlive_scope.to_def_id(),
|
||||
bound_region: br.kind,
|
||||
}));
|
||||
let liberated_region = self.tcx.mk_re_free(all_outlive_scope.to_def_id(), br.kind);
|
||||
let region_vid = self.next_nll_region_var(origin);
|
||||
indices.insert_late_bound_region(liberated_region, region_vid.to_region_vid());
|
||||
debug!(?liberated_region, ?region_vid);
|
||||
|
|
@ -843,7 +835,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
|
|||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
tcx.fold_regions(value, |region, _| tcx.mk_region(ty::ReVar(self.to_region_vid(region))))
|
||||
tcx.fold_regions(value, |region, _| tcx.mk_re_var(self.to_region_vid(region)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -883,8 +875,7 @@ fn for_each_late_bound_region_in_item<'tcx>(
|
|||
|
||||
for bound_var in tcx.late_bound_vars(tcx.hir().local_def_id_to_hir_id(mir_def_id)) {
|
||||
let ty::BoundVariableKind::Region(bound_region) = bound_var else { continue; };
|
||||
let liberated_region = tcx
|
||||
.mk_region(ty::ReFree(ty::FreeRegion { scope: mir_def_id.to_def_id(), bound_region }));
|
||||
let liberated_region = tcx.mk_re_free(mir_def_id.to_def_id(), bound_region);
|
||||
f(liberated_region);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -135,19 +135,17 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
|
|||
}
|
||||
|
||||
// `let names: &'static _ = &["field1", "field2"];`
|
||||
let names_let = if is_struct {
|
||||
let names_let = is_struct.then(|| {
|
||||
let lt_static = Some(cx.lifetime_static(span));
|
||||
let ty_static_ref = cx.ty_ref(span, cx.ty_infer(span), lt_static, ast::Mutability::Not);
|
||||
Some(cx.stmt_let_ty(
|
||||
cx.stmt_let_ty(
|
||||
span,
|
||||
false,
|
||||
Ident::new(sym::names, span),
|
||||
Some(ty_static_ref),
|
||||
cx.expr_array_ref(span, name_exprs),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
)
|
||||
});
|
||||
|
||||
// `let values: &[&dyn Debug] = &[&&self.field1, &&self.field2];`
|
||||
let path_debug = cx.path_global(span, cx.std_path(&[sym::fmt, sym::Debug]));
|
||||
|
|
|
|||
|
|
@ -941,13 +941,11 @@ impl<'a> MethodDef<'a> {
|
|||
let mut nonself_arg_tys = Vec::new();
|
||||
let span = trait_.span;
|
||||
|
||||
let explicit_self = if self.explicit_self {
|
||||
let explicit_self = self.explicit_self.then(|| {
|
||||
let (self_expr, explicit_self) = ty::get_explicit_self(cx, span);
|
||||
selflike_args.push(self_expr);
|
||||
Some(explicit_self)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
explicit_self
|
||||
});
|
||||
|
||||
for (ty, name) in self.nonself_args.iter() {
|
||||
let ast_ty = ty.to_ty(cx, span, type_ident, generics);
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ pub fn inject(
|
|||
// the one with the prelude.
|
||||
let name = names[0];
|
||||
|
||||
let root = (edition == Edition2015).then(|| kw::PathRoot);
|
||||
let root = (edition == Edition2015).then_some(kw::PathRoot);
|
||||
|
||||
let import_path = root
|
||||
.iter()
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ pub(crate) fn maybe_codegen<'tcx>(
|
|||
Some(fx.easy_call("__multi3", &[lhs, rhs], val_ty))
|
||||
}
|
||||
} else {
|
||||
let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter());
|
||||
let out_ty = fx.tcx.intern_tup(&[lhs.layout().ty, fx.tcx.types.bool]);
|
||||
let oflow = CPlace::new_stack_slot(fx, fx.layout_of(fx.tcx.types.i32));
|
||||
let lhs = lhs.load_scalar(fx);
|
||||
let rhs = rhs.load_scalar(fx);
|
||||
|
|
@ -78,7 +78,7 @@ pub(crate) fn maybe_codegen<'tcx>(
|
|||
}
|
||||
BinOp::Add | BinOp::Sub | BinOp::Mul => {
|
||||
assert!(checked);
|
||||
let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter());
|
||||
let out_ty = fx.tcx.intern_tup(&[lhs.layout().ty, fx.tcx.types.bool]);
|
||||
let out_place = CPlace::new_stack_slot(fx, fx.layout_of(out_ty));
|
||||
let (param_types, args) = if fx.tcx.sess.target.is_like_windows {
|
||||
let (lhs_ptr, lhs_extra) = lhs.force_stack(fx);
|
||||
|
|
|
|||
|
|
@ -248,17 +248,13 @@ fn reuse_workproduct_for_cgu(
|
|||
dwarf_object: None,
|
||||
bytecode: None,
|
||||
},
|
||||
module_global_asm: if has_global_asm {
|
||||
Some(CompiledModule {
|
||||
name: cgu.name().to_string(),
|
||||
kind: ModuleKind::Regular,
|
||||
object: Some(obj_out_global_asm),
|
||||
dwarf_object: None,
|
||||
bytecode: None,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
},
|
||||
module_global_asm: has_global_asm.then(|| CompiledModule {
|
||||
name: cgu.name().to_string(),
|
||||
kind: ModuleKind::Regular,
|
||||
object: Some(obj_out_global_asm),
|
||||
dwarf_object: None,
|
||||
bytecode: None,
|
||||
}),
|
||||
existing_work_product: Some((cgu.work_product_id(), work_product)),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ fn llvm_add_sub<'tcx>(
|
|||
// carry0 | carry1 -> carry or borrow respectively
|
||||
let cb_out = fx.bcx.ins().bor(cb0, cb1);
|
||||
|
||||
let layout = fx.layout_of(fx.tcx.mk_tup([fx.tcx.types.u8, fx.tcx.types.u64].iter()));
|
||||
let layout = fx.layout_of(fx.tcx.intern_tup(&[fx.tcx.types.u8, fx.tcx.types.u64]));
|
||||
let val = CValue::by_val_pair(cb_out, c, layout);
|
||||
ret.write_cvalue(fx, val);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ pub(crate) fn maybe_create_entry_wrapper(
|
|||
tcx,
|
||||
ParamEnv::reveal_all(),
|
||||
report.def_id,
|
||||
tcx.mk_substs([GenericArg::from(main_ret_ty)].iter()),
|
||||
tcx.intern_substs(&[GenericArg::from(main_ret_ty)]),
|
||||
)
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
|
|
|
|||
|
|
@ -289,7 +289,7 @@ pub(crate) fn codegen_checked_int_binop<'tcx>(
|
|||
_ => bug!("binop {:?} on checked int/uint lhs: {:?} rhs: {:?}", bin_op, in_lhs, in_rhs),
|
||||
};
|
||||
|
||||
let out_layout = fx.layout_of(fx.tcx.mk_tup([in_lhs.layout().ty, fx.tcx.types.bool].iter()));
|
||||
let out_layout = fx.layout_of(fx.tcx.intern_tup(&[in_lhs.layout().ty, fx.tcx.types.bool]));
|
||||
CValue::by_val_pair(res, has_overflow, out_layout)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ pub fn sanitize_attrs<'ll>(
|
|||
) -> SmallVec<[&'ll Attribute; 4]> {
|
||||
let mut attrs = SmallVec::new();
|
||||
let enabled = cx.tcx.sess.opts.unstable_opts.sanitizer - no_sanitize;
|
||||
if enabled.contains(SanitizerSet::ADDRESS) {
|
||||
if enabled.contains(SanitizerSet::ADDRESS) || enabled.contains(SanitizerSet::KERNELADDRESS) {
|
||||
attrs.push(llvm::AttributeKind::SanitizeAddress.create_attr(cx.llcx));
|
||||
}
|
||||
if enabled.contains(SanitizerSet::MEMORY) {
|
||||
|
|
|
|||
|
|
@ -412,11 +412,7 @@ fn get_pgo_sample_use_path(config: &ModuleConfig) -> Option<CString> {
|
|||
}
|
||||
|
||||
fn get_instr_profile_output_path(config: &ModuleConfig) -> Option<CString> {
|
||||
if config.instrument_coverage {
|
||||
Some(CString::new("default_%m_%p.profraw").unwrap())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
config.instrument_coverage.then(|| CString::new("default_%m_%p.profraw").unwrap())
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn llvm_optimize(
|
||||
|
|
@ -446,16 +442,19 @@ pub(crate) unsafe fn llvm_optimize(
|
|||
sanitize_thread: config.sanitizer.contains(SanitizerSet::THREAD),
|
||||
sanitize_hwaddress: config.sanitizer.contains(SanitizerSet::HWADDRESS),
|
||||
sanitize_hwaddress_recover: config.sanitizer_recover.contains(SanitizerSet::HWADDRESS),
|
||||
sanitize_kernel_address: config.sanitizer.contains(SanitizerSet::KERNELADDRESS),
|
||||
sanitize_kernel_address_recover: config
|
||||
.sanitizer_recover
|
||||
.contains(SanitizerSet::KERNELADDRESS),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let mut llvm_profiler = if cgcx.prof.llvm_recording_enabled() {
|
||||
Some(LlvmSelfProfiler::new(cgcx.prof.get_self_profiler().unwrap()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let mut llvm_profiler = cgcx
|
||||
.prof
|
||||
.llvm_recording_enabled()
|
||||
.then(|| LlvmSelfProfiler::new(cgcx.prof.get_self_profiler().unwrap()));
|
||||
|
||||
let llvm_selfprofiler =
|
||||
llvm_profiler.as_mut().map(|s| s as *mut _ as *mut c_void).unwrap_or(std::ptr::null_mut());
|
||||
|
|
|
|||
|
|
@ -521,7 +521,7 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
|
|||
|
||||
// The semantics of #[used] in Rust only require the symbol to make it into the
|
||||
// object file. It is explicitly allowed for the linker to strip the symbol if it
|
||||
// is dead, which means we are allowed use `llvm.compiler.used` instead of
|
||||
// is dead, which means we are allowed to use `llvm.compiler.used` instead of
|
||||
// `llvm.used` here.
|
||||
//
|
||||
// Additionally, https://reviews.llvm.org/D97448 in LLVM 13 started emitting unique
|
||||
|
|
@ -532,7 +532,7 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
|
|||
// That said, we only ever emit these when compiling for ELF targets, unless
|
||||
// `#[used(compiler)]` is explicitly requested. This is to avoid similar breakage
|
||||
// on other targets, in particular MachO targets have *their* static constructor
|
||||
// lists broken if `llvm.compiler.used` is emitted rather than llvm.used. However,
|
||||
// lists broken if `llvm.compiler.used` is emitted rather than `llvm.used`. However,
|
||||
// that check happens when assigning the `CodegenFnAttrFlags` in `rustc_hir_analysis`,
|
||||
// so we don't need to take care of it here.
|
||||
self.add_compiler_used_global(g);
|
||||
|
|
|
|||
|
|
@ -145,8 +145,13 @@ pub unsafe fn create_module<'ll>(
|
|||
let llvm_version = llvm_util::get_version();
|
||||
if llvm_version < (16, 0, 0) {
|
||||
if sess.target.arch == "s390x" {
|
||||
// LLVM 16 data layout changed to always set 64-bit vector alignment,
|
||||
// which is conditional in earlier LLVM versions.
|
||||
// https://reviews.llvm.org/D131158 for the discussion.
|
||||
target_data_layout = target_data_layout.replace("-v128:64", "");
|
||||
} else if sess.target.arch == "riscv64" {
|
||||
// LLVM 16 introduced this change so as to produce more efficient code.
|
||||
// See https://reviews.llvm.org/D116735 for the discussion.
|
||||
target_data_layout = target_data_layout.replace("-n32:64-", "-n64-");
|
||||
}
|
||||
}
|
||||
|
|
@ -402,12 +407,8 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
|
|||
|
||||
let (llcx, llmod) = (&*llvm_module.llcx, llvm_module.llmod());
|
||||
|
||||
let coverage_cx = if tcx.sess.instrument_coverage() {
|
||||
let covctx = coverageinfo::CrateCoverageContext::new();
|
||||
Some(covctx)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let coverage_cx =
|
||||
tcx.sess.instrument_coverage().then(coverageinfo::CrateCoverageContext::new);
|
||||
|
||||
let dbg_cx = if tcx.sess.opts.debuginfo != DebugInfo::None {
|
||||
let dctx = debuginfo::CodegenUnitDebugContext::new(llmod);
|
||||
|
|
|
|||
|
|
@ -27,8 +27,6 @@ use rustc_middle::ty::Instance;
|
|||
use std::cell::RefCell;
|
||||
use std::ffi::CString;
|
||||
|
||||
use std::iter;
|
||||
|
||||
pub mod mapgen;
|
||||
|
||||
const UNUSED_FUNCTION_COUNTER_ID: CounterValueReference = CounterValueReference::START;
|
||||
|
|
@ -201,7 +199,7 @@ fn declare_unused_fn<'tcx>(cx: &CodegenCx<'_, 'tcx>, def_id: DefId) -> Instance<
|
|||
tcx.symbol_name(instance).name,
|
||||
cx.fn_abi_of_fn_ptr(
|
||||
ty::Binder::dummy(tcx.mk_fn_sig(
|
||||
iter::once(tcx.mk_unit()),
|
||||
[tcx.mk_unit()],
|
||||
tcx.mk_unit(),
|
||||
false,
|
||||
hir::Unsafety::Unsafe,
|
||||
|
|
|
|||
|
|
@ -508,7 +508,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||
let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions(
|
||||
instance.substs,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
cx.tcx.type_of(impl_def_id),
|
||||
cx.tcx.type_of(impl_def_id).skip_binder(),
|
||||
);
|
||||
|
||||
// Only "class" methods are generally understood by LLVM,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ use rustc_target::abi::{self, Align, HasDataLayout, Primitive};
|
|||
use rustc_target::spec::{HasTargetSpec, PanicStrategy};
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::iter;
|
||||
|
||||
fn get_simple_intrinsic<'ll>(
|
||||
cx: &CodegenCx<'ll, '_>,
|
||||
|
|
@ -798,7 +797,7 @@ fn get_rust_try_fn<'ll, 'tcx>(
|
|||
let i8p = tcx.mk_mut_ptr(tcx.types.i8);
|
||||
// `unsafe fn(*mut i8) -> ()`
|
||||
let try_fn_ty = tcx.mk_fn_ptr(ty::Binder::dummy(tcx.mk_fn_sig(
|
||||
iter::once(i8p),
|
||||
[i8p],
|
||||
tcx.mk_unit(),
|
||||
false,
|
||||
hir::Unsafety::Unsafe,
|
||||
|
|
@ -806,7 +805,7 @@ fn get_rust_try_fn<'ll, 'tcx>(
|
|||
)));
|
||||
// `unsafe fn(*mut i8, *mut i8) -> ()`
|
||||
let catch_fn_ty = tcx.mk_fn_ptr(ty::Binder::dummy(tcx.mk_fn_sig(
|
||||
[i8p, i8p].iter().cloned(),
|
||||
[i8p, i8p],
|
||||
tcx.mk_unit(),
|
||||
false,
|
||||
hir::Unsafety::Unsafe,
|
||||
|
|
@ -814,7 +813,7 @@ fn get_rust_try_fn<'ll, 'tcx>(
|
|||
)));
|
||||
// `unsafe fn(unsafe fn(*mut i8) -> (), *mut i8, unsafe fn(*mut i8, *mut i8) -> ()) -> i32`
|
||||
let rust_fn_sig = ty::Binder::dummy(cx.tcx.mk_fn_sig(
|
||||
[try_fn_ty, i8p, catch_fn_ty].into_iter(),
|
||||
[try_fn_ty, i8p, catch_fn_ty],
|
||||
tcx.types.i32,
|
||||
false,
|
||||
hir::Unsafety::Unsafe,
|
||||
|
|
|
|||
|
|
@ -482,6 +482,8 @@ pub struct SanitizerOptions {
|
|||
pub sanitize_thread: bool,
|
||||
pub sanitize_hwaddress: bool,
|
||||
pub sanitize_hwaddress_recover: bool,
|
||||
pub sanitize_kernel_address: bool,
|
||||
pub sanitize_kernel_address_recover: bool,
|
||||
}
|
||||
|
||||
/// LLVMRelocMode
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ fn struct_llfields<'a, 'tcx>(
|
|||
} else {
|
||||
debug!("struct_llfields: offset: {:?} stride: {:?}", offset, layout.size);
|
||||
}
|
||||
let field_remapping = if padding_used { Some(field_remapping) } else { None };
|
||||
let field_remapping = padding_used.then_some(field_remapping);
|
||||
(result, packed, field_remapping)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2024,7 +2024,7 @@ fn linker_with_args<'a>(
|
|||
.native_libraries
|
||||
.iter()
|
||||
.filter_map(|(cnum, libraries)| {
|
||||
(dependency_linkage[cnum.as_usize() - 1] != Linkage::Static).then(|| libraries)
|
||||
(dependency_linkage[cnum.as_usize() - 1] != Linkage::Static).then_some(libraries)
|
||||
})
|
||||
.flatten();
|
||||
for (raw_dylib_name, raw_dylib_imports) in
|
||||
|
|
|
|||
|
|
@ -579,7 +579,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
|
|||
}
|
||||
}
|
||||
|
||||
let metadata_module = if need_metadata_module {
|
||||
let metadata_module = need_metadata_module.then(|| {
|
||||
// Emit compressed metadata object.
|
||||
let metadata_cgu_name =
|
||||
cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("metadata")).to_string();
|
||||
|
|
@ -594,17 +594,15 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
|
|||
if let Err(error) = std::fs::write(&file_name, data) {
|
||||
tcx.sess.emit_fatal(errors::MetadataObjectFileWrite { error });
|
||||
}
|
||||
Some(CompiledModule {
|
||||
CompiledModule {
|
||||
name: metadata_cgu_name,
|
||||
kind: ModuleKind::Metadata,
|
||||
object: Some(file_name),
|
||||
dwarf_object: None,
|
||||
bytecode: None,
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
});
|
||||
|
||||
let ongoing_codegen = start_async_codegen(
|
||||
backend.clone(),
|
||||
|
|
|
|||
|
|
@ -295,7 +295,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
|
|||
if let Some(list) = attr.meta_item_list() {
|
||||
for item in list.iter() {
|
||||
if item.has_name(sym::address) {
|
||||
codegen_fn_attrs.no_sanitize |= SanitizerSet::ADDRESS;
|
||||
codegen_fn_attrs.no_sanitize |=
|
||||
SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS;
|
||||
} else if item.has_name(sym::cfi) {
|
||||
codegen_fn_attrs.no_sanitize |= SanitizerSet::CFI;
|
||||
} else if item.has_name(sym::kcfi) {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
//! This crate contains codegen code that is used by all codegen backends (LLVM and others).
|
||||
//! The backend-agnostic functions of this crate use functions defined in various traits that
|
||||
//! have to be implemented by each backends.
|
||||
//! have to be implemented by each backend.
|
||||
|
||||
#[macro_use]
|
||||
extern crate rustc_macros;
|
||||
|
|
|
|||
|
|
@ -167,8 +167,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||
start_bx.set_personality_fn(cx.eh_personality());
|
||||
}
|
||||
|
||||
let cleanup_kinds =
|
||||
if base::wants_msvc_seh(cx.tcx().sess) { Some(analyze::cleanup_kinds(&mir)) } else { None };
|
||||
let cleanup_kinds = base::wants_msvc_seh(cx.tcx().sess).then(|| analyze::cleanup_kinds(&mir));
|
||||
|
||||
let cached_llbbs: IndexVec<mir::BasicBlock, CachedLlbb<Bx::BasicBlock>> =
|
||||
mir.basic_blocks
|
||||
|
|
|
|||
|
|
@ -286,6 +286,7 @@ const WASM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
|
|||
("mutable-globals", Some(sym::wasm_target_feature)),
|
||||
("nontrapping-fptoint", Some(sym::wasm_target_feature)),
|
||||
("reference-types", Some(sym::wasm_target_feature)),
|
||||
("relaxed-simd", Some(sym::wasm_target_feature)),
|
||||
("sign-ext", Some(sym::wasm_target_feature)),
|
||||
("simd128", None),
|
||||
// tidy-alphabetical-end
|
||||
|
|
|
|||
|
|
@ -95,8 +95,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
// Allocate memory for `CallerLocation` struct.
|
||||
let loc_ty = self
|
||||
.tcx
|
||||
.bound_type_of(self.tcx.require_lang_item(LangItem::PanicLocation, None))
|
||||
.subst(*self.tcx, self.tcx.mk_substs([self.tcx.lifetimes.re_erased.into()].iter()));
|
||||
.type_of(self.tcx.require_lang_item(LangItem::PanicLocation, None))
|
||||
.subst(*self.tcx, self.tcx.intern_substs(&[self.tcx.lifetimes.re_erased.into()]));
|
||||
let loc_layout = self.layout_of(loc_ty).unwrap();
|
||||
let location = self.allocate(loc_layout, MemoryKind::CallerLocation).unwrap();
|
||||
|
||||
|
|
|
|||
|
|
@ -690,7 +690,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
assert!(self.tcx.is_static(def_id));
|
||||
assert!(!self.tcx.is_thread_local_static(def_id));
|
||||
// Use size and align of the type.
|
||||
let ty = self.tcx.type_of(def_id);
|
||||
let ty = self
|
||||
.tcx
|
||||
.type_of(def_id)
|
||||
.no_bound_vars()
|
||||
.expect("statics should not have generic parameters");
|
||||
let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap();
|
||||
assert!(layout.is_sized());
|
||||
(layout.size, layout.align.abi, AllocKind::LiveData)
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> {
|
|||
pub fn fn_sig(&self) -> PolyFnSig<'tcx> {
|
||||
let did = self.def_id().to_def_id();
|
||||
if self.tcx.is_closure(did) {
|
||||
let ty = self.tcx.type_of(did);
|
||||
let ty = self.tcx.type_of(did).subst_identity();
|
||||
let ty::Closure(_, substs) = ty.kind() else { bug!("type_of closure not ty::Closure") };
|
||||
substs.as_closure().sig()
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -898,7 +898,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
|||
assert_eq!(self.new_block(), START_BLOCK);
|
||||
self.visit_rvalue(
|
||||
&mut rvalue,
|
||||
Location { block: BasicBlock::new(0), statement_index: usize::MAX },
|
||||
Location { block: START_BLOCK, statement_index: usize::MAX },
|
||||
);
|
||||
|
||||
let span = self.promoted.span;
|
||||
|
|
|
|||
|
|
@ -334,7 +334,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
|
||||
let kind = match parent_ty.ty.kind() {
|
||||
&ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
|
||||
self.tcx.bound_type_of(def_id).subst(self.tcx, substs).kind()
|
||||
self.tcx.type_of(def_id).subst(self.tcx, substs).kind()
|
||||
}
|
||||
kind => kind,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -207,8 +207,7 @@ impl SelfProfilerRef {
|
|||
/// a measureme event, "verbose" generic activities also print a timing entry to
|
||||
/// stderr if the compiler is invoked with -Ztime-passes.
|
||||
pub fn verbose_generic_activity(&self, event_label: &'static str) -> VerboseTimingGuard<'_> {
|
||||
let message =
|
||||
if self.print_verbose_generic_activities { Some(event_label.to_owned()) } else { None };
|
||||
let message = self.print_verbose_generic_activities.then(|| event_label.to_owned());
|
||||
|
||||
VerboseTimingGuard::start(message, self.generic_activity(event_label))
|
||||
}
|
||||
|
|
@ -222,11 +221,9 @@ impl SelfProfilerRef {
|
|||
where
|
||||
A: Borrow<str> + Into<String>,
|
||||
{
|
||||
let message = if self.print_verbose_generic_activities {
|
||||
Some(format!("{}({})", event_label, event_arg.borrow()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let message = self
|
||||
.print_verbose_generic_activities
|
||||
.then(|| format!("{}({})", event_label, event_arg.borrow()));
|
||||
|
||||
VerboseTimingGuard::start(message, self.generic_activity_with_arg(event_label, event_arg))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1768,7 +1768,7 @@ impl EmitterWriter {
|
|||
|
||||
// Render the replacements for each suggestion
|
||||
let suggestions = suggestion.splice_lines(sm);
|
||||
debug!("emit_suggestion_default: suggestions={:?}", suggestions);
|
||||
debug!(?suggestions);
|
||||
|
||||
if suggestions.is_empty() {
|
||||
// Suggestions coming from macros can have malformed spans. This is a heavy handed
|
||||
|
|
@ -1797,6 +1797,7 @@ impl EmitterWriter {
|
|||
for (complete, parts, highlights, only_capitalization) in
|
||||
suggestions.iter().take(MAX_SUGGESTIONS)
|
||||
{
|
||||
debug!(?complete, ?parts, ?highlights);
|
||||
notice_capitalization |= only_capitalization;
|
||||
|
||||
let has_deletion = parts.iter().any(|p| p.is_deletion(sm));
|
||||
|
|
|
|||
|
|
@ -471,6 +471,8 @@ pub enum StashKey {
|
|||
/// When an invalid lifetime e.g. `'2` should be reinterpreted
|
||||
/// as a char literal in the parser
|
||||
LifetimeIsChar,
|
||||
/// When an invalid lifetime e.g. `'🐱` contains emoji.
|
||||
LifetimeContainsEmoji,
|
||||
/// Maybe there was a typo where a comma was forgotten before
|
||||
/// FRU syntax
|
||||
MaybeFruTypo,
|
||||
|
|
@ -1066,29 +1068,26 @@ impl Handler {
|
|||
}
|
||||
|
||||
pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
|
||||
if self.inner.borrow().has_errors() { Some(ErrorGuaranteed(())) } else { None }
|
||||
self.inner.borrow().has_errors().then(ErrorGuaranteed::unchecked_claim_error_was_emitted)
|
||||
}
|
||||
|
||||
pub fn has_errors_or_lint_errors(&self) -> Option<ErrorGuaranteed> {
|
||||
if self.inner.borrow().has_errors_or_lint_errors() {
|
||||
Some(ErrorGuaranteed::unchecked_claim_error_was_emitted())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
self.inner
|
||||
.borrow()
|
||||
.has_errors_or_lint_errors()
|
||||
.then(ErrorGuaranteed::unchecked_claim_error_was_emitted)
|
||||
}
|
||||
pub fn has_errors_or_delayed_span_bugs(&self) -> Option<ErrorGuaranteed> {
|
||||
if self.inner.borrow().has_errors_or_delayed_span_bugs() {
|
||||
Some(ErrorGuaranteed::unchecked_claim_error_was_emitted())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
self.inner
|
||||
.borrow()
|
||||
.has_errors_or_delayed_span_bugs()
|
||||
.then(ErrorGuaranteed::unchecked_claim_error_was_emitted)
|
||||
}
|
||||
pub fn is_compilation_going_to_fail(&self) -> Option<ErrorGuaranteed> {
|
||||
if self.inner.borrow().is_compilation_going_to_fail() {
|
||||
Some(ErrorGuaranteed::unchecked_claim_error_was_emitted())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
self.inner
|
||||
.borrow()
|
||||
.is_compilation_going_to_fail()
|
||||
.then(ErrorGuaranteed::unchecked_claim_error_was_emitted)
|
||||
}
|
||||
|
||||
pub fn print_error_count(&self, registry: &Registry) {
|
||||
|
|
|
|||
|
|
@ -238,12 +238,10 @@ macro_rules! configure {
|
|||
impl<'a> StripUnconfigured<'a> {
|
||||
pub fn configure<T: HasAttrs + HasTokens>(&self, mut node: T) -> Option<T> {
|
||||
self.process_cfg_attrs(&mut node);
|
||||
if self.in_cfg(node.attrs()) {
|
||||
self.in_cfg(node.attrs()).then(|| {
|
||||
self.try_configure_tokens(&mut node);
|
||||
Some(node)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
node
|
||||
})
|
||||
}
|
||||
|
||||
fn try_configure_tokens<T: HasTokens>(&self, node: &mut T) {
|
||||
|
|
@ -257,7 +255,7 @@ impl<'a> StripUnconfigured<'a> {
|
|||
|
||||
fn configure_krate_attrs(&self, mut attrs: ast::AttrVec) -> Option<ast::AttrVec> {
|
||||
attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr));
|
||||
if self.in_cfg(&attrs) { Some(attrs) } else { None }
|
||||
self.in_cfg(&attrs).then_some(attrs)
|
||||
}
|
||||
|
||||
/// Performs cfg-expansion on `stream`, producing a new `AttrTokenStream`.
|
||||
|
|
|
|||
|
|
@ -164,8 +164,6 @@ declare_features! (
|
|||
(active, multiple_supertrait_upcastable, "CURRENT_RUSTC_VERSION", None, None),
|
||||
/// Allows using `#[omit_gdb_pretty_printer_section]`.
|
||||
(active, omit_gdb_pretty_printer_section, "1.5.0", None, None),
|
||||
/// Allows using `+bundled,+whole-archive` native libs.
|
||||
(active, packed_bundled_libs, "1.67.0", None, None),
|
||||
/// Allows using `#[prelude_import]` on glob `use` items.
|
||||
(active, prelude_import, "1.2.0", None, None),
|
||||
/// Used to identify crates that contain the profiler runtime.
|
||||
|
|
@ -217,6 +215,8 @@ declare_features! (
|
|||
(active, linkage, "1.0.0", Some(29603), None),
|
||||
/// Allows declaring with `#![needs_panic_runtime]` that a panic runtime is needed.
|
||||
(active, needs_panic_runtime, "1.10.0", Some(32837), None),
|
||||
/// Allows using `+bundled,+whole-archive` native libs.
|
||||
(active, packed_bundled_libs, "CURRENT_RUSTC_VERSION", Some(108081), None),
|
||||
/// Allows using the `#![panic_runtime]` attribute.
|
||||
(active, panic_runtime, "1.10.0", Some(32837), None),
|
||||
/// Allows using `#[rustc_allow_const_fn_unstable]`.
|
||||
|
|
@ -473,6 +473,8 @@ declare_features! (
|
|||
(active, no_sanitize, "1.42.0", Some(39699), None),
|
||||
/// Allows using the `non_exhaustive_omitted_patterns` lint.
|
||||
(active, non_exhaustive_omitted_patterns_lint, "1.57.0", Some(89554), None),
|
||||
/// Allows `for<T>` binders in where-clauses
|
||||
(incomplete, non_lifetime_binders, "CURRENT_RUSTC_VERSION", Some(108185), None),
|
||||
/// Allows making `dyn Trait` well-formed even if `Trait` is not object safe.
|
||||
/// In that case, `dyn Trait: Trait` does not hold. Moreover, coercions and
|
||||
/// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden.
|
||||
|
|
|
|||
|
|
@ -574,14 +574,11 @@ impl<'hir> Generics<'hir> {
|
|||
|
||||
/// If there are generic parameters, return where to introduce a new one.
|
||||
pub fn span_for_param_suggestion(&self) -> Option<Span> {
|
||||
if self.params.iter().any(|p| self.span.contains(p.span)) {
|
||||
self.params.iter().any(|p| self.span.contains(p.span)).then(|| {
|
||||
// `fn foo<A>(t: impl Trait)`
|
||||
// ^ suggest `, T: Trait` here
|
||||
let span = self.span.with_lo(self.span.hi() - BytePos(1)).shrink_to_lo();
|
||||
Some(span)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
self.span.with_lo(self.span.hi() - BytePos(1)).shrink_to_lo()
|
||||
})
|
||||
}
|
||||
|
||||
/// `Span` where further predicates would be suggested, accounting for trailing commas, like
|
||||
|
|
@ -639,7 +636,7 @@ impl<'hir> Generics<'hir> {
|
|||
// We include bounds that come from a `#[derive(_)]` but point at the user's code,
|
||||
// as we use this method to get a span appropriate for suggestions.
|
||||
let bs = bound.span();
|
||||
if bs.can_be_used_for_suggestions() { Some(bs.shrink_to_hi()) } else { None }
|
||||
bs.can_be_used_for_suggestions().then(|| bs.shrink_to_hi())
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ fn generic_arg_mismatch_err(
|
|||
Res::Def(DefKind::TyParam, src_def_id) => {
|
||||
if let Some(param_local_id) = param.def_id.as_local() {
|
||||
let param_name = tcx.hir().ty_param_name(param_local_id);
|
||||
let param_type = tcx.type_of(param.def_id);
|
||||
let param_type = tcx.type_of(param.def_id).subst_identity();
|
||||
if param_type.is_suggestable(tcx, false) {
|
||||
err.span_suggestion(
|
||||
tcx.def_span(src_def_id),
|
||||
|
|
@ -97,7 +97,7 @@ fn generic_arg_mismatch_err(
|
|||
(
|
||||
GenericArg::Type(hir::Ty { kind: hir::TyKind::Array(_, len), .. }),
|
||||
GenericParamDefKind::Const { .. },
|
||||
) if tcx.type_of(param.def_id) == tcx.types.usize => {
|
||||
) if tcx.type_of(param.def_id).skip_binder() == tcx.types.usize => {
|
||||
let snippet = sess.source_map().span_to_snippet(tcx.hir().span(len.hir_id()));
|
||||
if let Ok(snippet) = snippet {
|
||||
err.span_suggestion(
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use crate::errors::{
|
|||
AmbiguousLifetimeBound, MultipleRelaxedDefaultBounds, TraitObjectDeclaredWithNoTraits,
|
||||
TypeofReservedKeywordUsed, ValueOfAssociatedStructAlreadySpecified,
|
||||
};
|
||||
use crate::middle::resolve_lifetime as rl;
|
||||
use crate::middle::resolve_bound_vars as rbv;
|
||||
use crate::require_c_abi_if_c_variadic;
|
||||
use rustc_ast::TraitObjectSyntax;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
|
|
@ -30,9 +30,9 @@ use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
|
|||
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
||||
use rustc_middle::middle::stability::AllowUnstable;
|
||||
use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef};
|
||||
use rustc_middle::ty::DynKind;
|
||||
use rustc_middle::ty::GenericParamDefKind;
|
||||
use rustc_middle::ty::{self, Const, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeVisitable};
|
||||
use rustc_middle::ty::{DynKind, EarlyBinder};
|
||||
use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECTS};
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::lev_distance::find_best_match_for_name;
|
||||
|
|
@ -225,36 +225,37 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
let tcx = self.tcx();
|
||||
let lifetime_name = |def_id| tcx.hir().name(tcx.hir().local_def_id_to_hir_id(def_id));
|
||||
|
||||
match tcx.named_region(lifetime.hir_id) {
|
||||
Some(rl::Region::Static) => tcx.lifetimes.re_static,
|
||||
match tcx.named_bound_var(lifetime.hir_id) {
|
||||
Some(rbv::ResolvedArg::StaticLifetime) => tcx.lifetimes.re_static,
|
||||
|
||||
Some(rl::Region::LateBound(debruijn, index, def_id)) => {
|
||||
Some(rbv::ResolvedArg::LateBound(debruijn, index, def_id)) => {
|
||||
let name = lifetime_name(def_id.expect_local());
|
||||
let br = ty::BoundRegion {
|
||||
var: ty::BoundVar::from_u32(index),
|
||||
kind: ty::BrNamed(def_id, name),
|
||||
};
|
||||
tcx.mk_region(ty::ReLateBound(debruijn, br))
|
||||
tcx.mk_re_late_bound(debruijn, br)
|
||||
}
|
||||
|
||||
Some(rl::Region::EarlyBound(def_id)) => {
|
||||
Some(rbv::ResolvedArg::EarlyBound(def_id)) => {
|
||||
let name = tcx.hir().ty_param_name(def_id.expect_local());
|
||||
let item_def_id = tcx.hir().ty_param_owner(def_id.expect_local());
|
||||
let generics = tcx.generics_of(item_def_id);
|
||||
let index = generics.param_def_id_to_index[&def_id];
|
||||
tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name }))
|
||||
tcx.mk_re_early_bound(ty::EarlyBoundRegion { def_id, index, name })
|
||||
}
|
||||
|
||||
Some(rl::Region::Free(scope, id)) => {
|
||||
Some(rbv::ResolvedArg::Free(scope, id)) => {
|
||||
let name = lifetime_name(id.expect_local());
|
||||
tcx.mk_region(ty::ReFree(ty::FreeRegion {
|
||||
scope,
|
||||
bound_region: ty::BrNamed(id, name),
|
||||
}))
|
||||
tcx.mk_re_free(scope, ty::BrNamed(id, name))
|
||||
|
||||
// (*) -- not late-bound, won't change
|
||||
}
|
||||
|
||||
Some(rbv::ResolvedArg::Error(_)) => {
|
||||
bug!("only ty/ct should resolve as ResolvedArg::Error")
|
||||
}
|
||||
|
||||
None => {
|
||||
self.re_infer(def, lifetime.ident.span).unwrap_or_else(|| {
|
||||
debug!(?lifetime, "unelided lifetime in signature");
|
||||
|
|
@ -263,7 +264,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
// elision. `resolve_lifetime` should have
|
||||
// reported an error in this case -- but if
|
||||
// not, let's error out.
|
||||
tcx.re_error_with_message(lifetime.ident.span, "unelided lifetime in signature")
|
||||
tcx.mk_re_error_with_message(
|
||||
lifetime.ident.span,
|
||||
"unelided lifetime in signature",
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -450,7 +454,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
.into()
|
||||
}
|
||||
(&GenericParamDefKind::Const { .. }, hir::GenericArg::Infer(inf)) => {
|
||||
let ty = tcx.at(self.span).type_of(param.def_id);
|
||||
let ty = tcx
|
||||
.at(self.span)
|
||||
.type_of(param.def_id)
|
||||
.no_bound_vars()
|
||||
.expect("const parameter types cannot be generic");
|
||||
if self.astconv.allow_ty_infer() {
|
||||
self.astconv.ct_infer(ty, Some(param), inf.span).into()
|
||||
} else {
|
||||
|
|
@ -477,7 +485,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
debug!(?param, "unelided lifetime in signature");
|
||||
|
||||
// This indicates an illegal lifetime in a non-assoc-trait position
|
||||
tcx.re_error_with_message(self.span, "unelided lifetime in signature")
|
||||
tcx.mk_re_error_with_message(
|
||||
self.span,
|
||||
"unelided lifetime in signature",
|
||||
)
|
||||
})
|
||||
.into(),
|
||||
GenericParamDefKind::Type { has_default, .. } => {
|
||||
|
|
@ -491,7 +502,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
// Avoid ICE #86756 when type error recovery goes awry.
|
||||
return tcx.ty_error().into();
|
||||
}
|
||||
tcx.at(self.span).bound_type_of(param.def_id).subst(tcx, substs).into()
|
||||
tcx.at(self.span).type_of(param.def_id).subst(tcx, substs).into()
|
||||
} else if infer_args {
|
||||
self.astconv.ty_infer(Some(param), self.span).into()
|
||||
} else {
|
||||
|
|
@ -500,7 +511,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
}
|
||||
}
|
||||
GenericParamDefKind::Const { has_default } => {
|
||||
let ty = tcx.at(self.span).type_of(param.def_id);
|
||||
let ty = tcx
|
||||
.at(self.span)
|
||||
.type_of(param.def_id)
|
||||
.no_bound_vars()
|
||||
.expect("const parameter types cannot be generic");
|
||||
if ty.references_error() {
|
||||
return tcx.const_error(ty).into();
|
||||
}
|
||||
|
|
@ -1227,7 +1242,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
}
|
||||
hir::def::DefKind::AssocConst => tcx
|
||||
.const_error_with_guaranteed(
|
||||
tcx.bound_type_of(assoc_item_def_id)
|
||||
tcx.type_of(assoc_item_def_id)
|
||||
.subst(tcx, projection_ty.skip_binder().substs),
|
||||
reported,
|
||||
)
|
||||
|
|
@ -1264,7 +1279,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
item_segment: &hir::PathSegment<'_>,
|
||||
) -> Ty<'tcx> {
|
||||
let substs = self.ast_path_substs_for_ty(span, did, item_segment);
|
||||
self.tcx().at(span).bound_type_of(did).subst(self.tcx(), substs)
|
||||
self.tcx().at(span).type_of(did).subst(self.tcx(), substs)
|
||||
}
|
||||
|
||||
fn conv_object_ty_poly_trait_ref(
|
||||
|
|
@ -1317,7 +1332,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
ty::Clause::TypeOutlives(_) => {
|
||||
// Do nothing, we deal with regions separately
|
||||
}
|
||||
ty::Clause::RegionOutlives(_) => bug!(),
|
||||
ty::Clause::RegionOutlives(_) | ty::Clause::ConstArgHasType(..) => bug!(),
|
||||
},
|
||||
ty::PredicateKind::WellFormed(_)
|
||||
| ty::PredicateKind::AliasEq(..)
|
||||
|
|
@ -1597,14 +1612,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
.collect::<SmallVec<[_; 8]>>();
|
||||
v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
|
||||
v.dedup();
|
||||
let existential_predicates = tcx.mk_poly_existential_predicates(v.into_iter());
|
||||
let existential_predicates = tcx.intern_poly_existential_predicates(&v);
|
||||
|
||||
// Use explicitly-specified region bound.
|
||||
let region_bound = if !lifetime.is_elided() {
|
||||
self.ast_region_to_region(lifetime, None)
|
||||
} else {
|
||||
self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| {
|
||||
if tcx.named_region(lifetime.hir_id).is_some() {
|
||||
if tcx.named_bound_var(lifetime.hir_id).is_some() {
|
||||
self.ast_region_to_region(lifetime, None)
|
||||
} else {
|
||||
self.re_infer(None, span).unwrap_or_else(|| {
|
||||
|
|
@ -1622,7 +1637,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
} else {
|
||||
err.emit()
|
||||
};
|
||||
tcx.re_error(e)
|
||||
tcx.mk_re_error(e)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
|
@ -2043,7 +2058,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
assoc_segment,
|
||||
adt_substs,
|
||||
);
|
||||
let ty = tcx.bound_type_of(assoc_ty_did).subst(tcx, item_substs);
|
||||
let ty = tcx.type_of(assoc_ty_did).subst(tcx, item_substs);
|
||||
return Ok((ty, DefKind::AssocTy, assoc_ty_did));
|
||||
}
|
||||
}
|
||||
|
|
@ -2597,6 +2612,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
&self,
|
||||
opt_self_ty: Option<Ty<'tcx>>,
|
||||
path: &hir::Path<'_>,
|
||||
hir_id: hir::HirId,
|
||||
permit_variants: bool,
|
||||
) -> Ty<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
|
|
@ -2660,11 +2676,26 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
}
|
||||
});
|
||||
|
||||
let def_id = def_id.expect_local();
|
||||
let item_def_id = tcx.hir().ty_param_owner(def_id);
|
||||
let generics = tcx.generics_of(item_def_id);
|
||||
let index = generics.param_def_id_to_index[&def_id.to_def_id()];
|
||||
tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id))
|
||||
match tcx.named_bound_var(hir_id) {
|
||||
Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => {
|
||||
let name =
|
||||
tcx.hir().name(tcx.hir().local_def_id_to_hir_id(def_id.expect_local()));
|
||||
let br = ty::BoundTy {
|
||||
var: ty::BoundVar::from_u32(index),
|
||||
kind: ty::BoundTyKind::Param(def_id, name),
|
||||
};
|
||||
tcx.mk_ty(ty::Bound(debruijn, br))
|
||||
}
|
||||
Some(rbv::ResolvedArg::EarlyBound(_)) => {
|
||||
let def_id = def_id.expect_local();
|
||||
let item_def_id = tcx.hir().ty_param_owner(def_id);
|
||||
let generics = tcx.generics_of(item_def_id);
|
||||
let index = generics.param_def_id_to_index[&def_id.to_def_id()];
|
||||
tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id))
|
||||
}
|
||||
Some(rbv::ResolvedArg::Error(guar)) => tcx.ty_error_with_guaranteed(guar),
|
||||
arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"),
|
||||
}
|
||||
}
|
||||
Res::SelfTyParam { .. } => {
|
||||
// `Self` in trait or type alias.
|
||||
|
|
@ -2685,7 +2716,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
// `Self` in impl (we know the concrete type).
|
||||
assert_eq!(opt_self_ty, None);
|
||||
// Try to evaluate any array length constants.
|
||||
let ty = tcx.at(span).type_of(def_id);
|
||||
let ty = tcx.at(span).type_of(def_id).subst_identity();
|
||||
let span_of_impl = tcx.span_of_impl(def_id);
|
||||
self.prohibit_generics(path.segments.iter(), |err| {
|
||||
let def_id = match *ty.kind() {
|
||||
|
|
@ -2882,12 +2913,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn,
|
||||
TraitObjectSyntax::DynStar => ty::DynStar,
|
||||
};
|
||||
|
||||
self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime, borrowed, repr)
|
||||
}
|
||||
hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
|
||||
debug!(?maybe_qself, ?path);
|
||||
let opt_self_ty = maybe_qself.as_ref().map(|qself| self.ast_ty_to_ty(qself));
|
||||
self.res_to_ty(opt_self_ty, path, false)
|
||||
self.res_to_ty(opt_self_ty, path, ast_ty.hir_id, false)
|
||||
}
|
||||
&hir::TyKind::OpaqueDef(item_id, lifetimes, in_trait) => {
|
||||
let opaque_ty = tcx.hir().item(item_id);
|
||||
|
|
@ -2919,7 +2951,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
None,
|
||||
ty::BoundConstness::NotConst,
|
||||
);
|
||||
EarlyBinder(tcx.at(span).type_of(def_id)).subst(tcx, substs)
|
||||
tcx.at(span).type_of(def_id).subst(tcx, substs)
|
||||
}
|
||||
hir::TyKind::Array(ty, length) => {
|
||||
let length = match length {
|
||||
|
|
@ -2932,7 +2964,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
tcx.mk_array_with_const_len(self.ast_ty_to_ty(ty), length)
|
||||
}
|
||||
hir::TyKind::Typeof(e) => {
|
||||
let ty_erased = tcx.type_of(e.def_id);
|
||||
let ty_erased = tcx.type_of(e.def_id).subst_identity();
|
||||
let ty = tcx.fold_regions(ty_erased, |r, _| {
|
||||
if r.is_erased() { tcx.lifetimes.re_static } else { r }
|
||||
});
|
||||
|
|
@ -3060,7 +3092,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
|
||||
debug!(?output_ty);
|
||||
|
||||
let fn_ty = tcx.mk_fn_sig(input_tys.into_iter(), output_ty, decl.c_variadic, unsafety, abi);
|
||||
let fn_ty = tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, unsafety, abi);
|
||||
let bare_fn_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars);
|
||||
|
||||
if !self.allow_ty_infer() && !(visitor.0.is_empty() && infer_replacements.is_empty()) {
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||
|
||||
/// Check that the fields of the `union` do not need dropping.
|
||||
fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool {
|
||||
let item_type = tcx.type_of(item_def_id);
|
||||
let item_type = tcx.type_of(item_def_id).subst_identity();
|
||||
if let ty::Adt(def, substs) = item_type.kind() {
|
||||
assert!(def.is_union());
|
||||
|
||||
|
|
@ -170,7 +170,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||
// would be enough to check this for `extern` statics, as statics with an initializer will
|
||||
// have UB during initialization if they are uninhabited, but there also seems to be no good
|
||||
// reason to allow any statics to be uninhabited.
|
||||
let ty = tcx.type_of(def_id);
|
||||
let ty = tcx.type_of(def_id).subst_identity();
|
||||
let span = tcx.def_span(def_id);
|
||||
let layout = match tcx.layout_of(ParamEnv::reveal_all().and(ty)) {
|
||||
Ok(l) => l,
|
||||
|
|
@ -227,7 +227,7 @@ fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) {
|
|||
if !tcx.features().impl_trait_projections {
|
||||
check_opaque_for_inheriting_lifetimes(tcx, item.owner_id.def_id, span);
|
||||
}
|
||||
if tcx.type_of(item.owner_id.def_id).references_error() {
|
||||
if tcx.type_of(item.owner_id.def_id).subst_identity().references_error() {
|
||||
return;
|
||||
}
|
||||
if check_opaque_for_cycles(tcx, item.owner_id.def_id, substs, span, &origin).is_err() {
|
||||
|
|
@ -425,7 +425,7 @@ fn check_opaque_meets_bounds<'tcx>(
|
|||
//
|
||||
// FIXME: Consider wrapping the hidden type in an existential `Binder` and instantiating it
|
||||
// here rather than using ReErased.
|
||||
let hidden_ty = tcx.bound_type_of(def_id.to_def_id()).subst(tcx, substs);
|
||||
let hidden_ty = tcx.type_of(def_id.to_def_id()).subst(tcx, substs);
|
||||
let hidden_ty = tcx.fold_regions(hidden_ty, |re, _dbi| match re.kind() {
|
||||
ty::ReErased => infcx.next_region_var(RegionVariableOrigin::MiscVariable(span)),
|
||||
_ => re,
|
||||
|
|
@ -492,7 +492,7 @@ fn is_enum_of_nonnullable_ptr<'tcx>(
|
|||
|
||||
fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||
if tcx.codegen_fn_attrs(def_id).import_linkage.is_some() {
|
||||
if match tcx.type_of(def_id).kind() {
|
||||
if match tcx.type_of(def_id).subst_identity().kind() {
|
||||
ty::RawPtr(_) => false,
|
||||
ty::Adt(adt_def, substs) => !is_enum_of_nonnullable_ptr(tcx, *adt_def, *substs),
|
||||
_ => true,
|
||||
|
|
@ -537,7 +537,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
|
|||
let assoc_items = tcx.associated_items(id.owner_id);
|
||||
check_on_unimplemented(tcx, id);
|
||||
|
||||
for assoc_item in assoc_items.in_definition_order() {
|
||||
for &assoc_item in assoc_items.in_definition_order() {
|
||||
match assoc_item.kind {
|
||||
ty::AssocKind::Fn => {
|
||||
let abi = tcx.fn_sig(assoc_item.def_id).skip_binder().abi();
|
||||
|
|
@ -578,7 +578,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
|
|||
}
|
||||
}
|
||||
DefKind::TyAlias => {
|
||||
let pty_ty = tcx.type_of(id.owner_id);
|
||||
let pty_ty = tcx.type_of(id.owner_id).subst_identity();
|
||||
let generics = tcx.generics_of(id.owner_id);
|
||||
check_type_params_are_used(tcx, &generics, pty_ty);
|
||||
}
|
||||
|
|
@ -670,7 +670,7 @@ pub(super) fn check_on_unimplemented(tcx: TyCtxt<'_>, item: hir::ItemId) {
|
|||
pub(super) fn check_specialization_validity<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_def: &ty::TraitDef,
|
||||
trait_item: &ty::AssocItem,
|
||||
trait_item: ty::AssocItem,
|
||||
impl_id: DefId,
|
||||
impl_item: DefId,
|
||||
) {
|
||||
|
|
@ -767,17 +767,17 @@ fn check_impl_items_against_trait<'tcx>(
|
|||
));
|
||||
}
|
||||
ty::AssocKind::Fn => {
|
||||
compare_impl_method(tcx, &ty_impl_item, &ty_trait_item, impl_trait_ref);
|
||||
compare_impl_method(tcx, ty_impl_item, ty_trait_item, impl_trait_ref);
|
||||
}
|
||||
ty::AssocKind::Type => {
|
||||
compare_impl_ty(tcx, &ty_impl_item, &ty_trait_item, impl_trait_ref);
|
||||
compare_impl_ty(tcx, ty_impl_item, ty_trait_item, impl_trait_ref);
|
||||
}
|
||||
}
|
||||
|
||||
check_specialization_validity(
|
||||
tcx,
|
||||
trait_def,
|
||||
&ty_trait_item,
|
||||
ty_trait_item,
|
||||
impl_id.to_def_id(),
|
||||
impl_item,
|
||||
);
|
||||
|
|
@ -854,7 +854,7 @@ fn check_impl_items_against_trait<'tcx>(
|
|||
}
|
||||
|
||||
pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
|
||||
let t = tcx.type_of(def_id);
|
||||
let t = tcx.type_of(def_id).subst_identity();
|
||||
if let ty::Adt(def, substs) = t.kind()
|
||||
&& def.is_struct()
|
||||
{
|
||||
|
|
@ -974,7 +974,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) {
|
|||
&if first {
|
||||
format!(
|
||||
"`{}` contains a field of type `{}`",
|
||||
tcx.type_of(def.did()),
|
||||
tcx.type_of(def.did()).subst_identity(),
|
||||
ident
|
||||
)
|
||||
} else {
|
||||
|
|
@ -996,7 +996,7 @@ pub(super) fn check_packed_inner(
|
|||
def_id: DefId,
|
||||
stack: &mut Vec<DefId>,
|
||||
) -> Option<Vec<(DefId, Span)>> {
|
||||
if let ty::Adt(def, substs) = tcx.type_of(def_id).kind() {
|
||||
if let ty::Adt(def, substs) = tcx.type_of(def_id).subst_identity().kind() {
|
||||
if def.is_struct() || def.is_union() {
|
||||
if def.repr().align.is_some() {
|
||||
return Some(vec![(def.did(), DUMMY_SP)]);
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ use std::iter;
|
|||
/// - `impl_trait_ref`: the TraitRef corresponding to the trait implementation
|
||||
pub(super) fn compare_impl_method<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl_m: &ty::AssocItem,
|
||||
trait_m: &ty::AssocItem,
|
||||
impl_m: ty::AssocItem,
|
||||
trait_m: ty::AssocItem,
|
||||
impl_trait_ref: ty::TraitRef<'tcx>,
|
||||
) {
|
||||
debug!("compare_impl_method(impl_trait_ref={:?})", impl_trait_ref);
|
||||
|
|
@ -129,8 +129,8 @@ pub(super) fn compare_impl_method<'tcx>(
|
|||
#[instrument(level = "debug", skip(tcx, impl_trait_ref))]
|
||||
fn compare_method_predicate_entailment<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl_m: &ty::AssocItem,
|
||||
trait_m: &ty::AssocItem,
|
||||
impl_m: ty::AssocItem,
|
||||
trait_m: ty::AssocItem,
|
||||
impl_trait_ref: ty::TraitRef<'tcx>,
|
||||
check_implied_wf: CheckImpliedWfMode,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
|
|
@ -381,8 +381,8 @@ fn compare_method_predicate_entailment<'tcx>(
|
|||
fn extract_bad_args_for_implies_lint<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
errors: &[infer::RegionResolutionError<'tcx>],
|
||||
(trait_m, trait_sig): (&ty::AssocItem, ty::FnSig<'tcx>),
|
||||
(impl_m, impl_sig): (&ty::AssocItem, ty::FnSig<'tcx>),
|
||||
(trait_m, trait_sig): (ty::AssocItem, ty::FnSig<'tcx>),
|
||||
(impl_m, impl_sig): (ty::AssocItem, ty::FnSig<'tcx>),
|
||||
hir_id: hir::HirId,
|
||||
) -> Vec<(Span, Option<String>)> {
|
||||
let mut blame_generics = vec![];
|
||||
|
|
@ -464,14 +464,10 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateBound<'_, 'tcx> {
|
|||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
if let ty::ReFree(fr) = *r {
|
||||
self.tcx.mk_region(ty::ReFree(ty::FreeRegion {
|
||||
bound_region: self
|
||||
.mapping
|
||||
.get(&fr.bound_region)
|
||||
.copied()
|
||||
.unwrap_or(fr.bound_region),
|
||||
..fr
|
||||
}))
|
||||
self.tcx.mk_re_free(
|
||||
fr.scope,
|
||||
self.mapping.get(&fr.bound_region).copied().unwrap_or(fr.bound_region),
|
||||
)
|
||||
} else {
|
||||
r
|
||||
}
|
||||
|
|
@ -480,7 +476,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateBound<'_, 'tcx> {
|
|||
|
||||
fn emit_implied_wf_lint<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl_m: &ty::AssocItem,
|
||||
impl_m: ty::AssocItem,
|
||||
hir_id: hir::HirId,
|
||||
bad_args: Vec<(Span, Option<String>)>,
|
||||
) {
|
||||
|
|
@ -527,8 +523,8 @@ enum CheckImpliedWfMode {
|
|||
|
||||
fn compare_asyncness<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl_m: &ty::AssocItem,
|
||||
trait_m: &ty::AssocItem,
|
||||
impl_m: ty::AssocItem,
|
||||
trait_m: ty::AssocItem,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
if tcx.asyncness(trait_m.def_id) == hir::IsAsync::Async {
|
||||
match tcx.fn_sig(impl_m.def_id).skip_binder().skip_binder().output().kind() {
|
||||
|
|
@ -777,13 +773,13 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
|||
}
|
||||
let Some(ty::ReEarlyBound(e)) = map.get(®ion.into()).map(|r| r.expect_region().kind())
|
||||
else {
|
||||
return tcx.re_error_with_message(return_span, "expected ReFree to map to ReEarlyBound")
|
||||
return tcx.mk_re_error_with_message(return_span, "expected ReFree to map to ReEarlyBound")
|
||||
};
|
||||
tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
|
||||
tcx.mk_re_early_bound(ty::EarlyBoundRegion {
|
||||
def_id: e.def_id,
|
||||
name: e.name,
|
||||
index: (e.index as usize - num_trait_substs + num_impl_substs) as u32,
|
||||
}))
|
||||
})
|
||||
});
|
||||
debug!(%ty);
|
||||
collected_tys.insert(def_id, ty);
|
||||
|
|
@ -873,8 +869,8 @@ fn report_trait_method_mismatch<'tcx>(
|
|||
infcx: &InferCtxt<'tcx>,
|
||||
mut cause: ObligationCause<'tcx>,
|
||||
terr: TypeError<'tcx>,
|
||||
(trait_m, trait_sig): (&ty::AssocItem, ty::FnSig<'tcx>),
|
||||
(impl_m, impl_sig): (&ty::AssocItem, ty::FnSig<'tcx>),
|
||||
(trait_m, trait_sig): (ty::AssocItem, ty::FnSig<'tcx>),
|
||||
(impl_m, impl_sig): (ty::AssocItem, ty::FnSig<'tcx>),
|
||||
impl_trait_ref: ty::TraitRef<'tcx>,
|
||||
) -> ErrorGuaranteed {
|
||||
let tcx = infcx.tcx;
|
||||
|
|
@ -967,8 +963,8 @@ fn report_trait_method_mismatch<'tcx>(
|
|||
|
||||
fn check_region_bounds_on_impl_item<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl_m: &ty::AssocItem,
|
||||
trait_m: &ty::AssocItem,
|
||||
impl_m: ty::AssocItem,
|
||||
trait_m: ty::AssocItem,
|
||||
delay: bool,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
let impl_generics = tcx.generics_of(impl_m.def_id);
|
||||
|
|
@ -1042,7 +1038,7 @@ fn check_region_bounds_on_impl_item<'tcx>(
|
|||
.sess
|
||||
.create_err(LifetimesOrBoundsMismatchOnTrait {
|
||||
span,
|
||||
item_kind: assoc_item_kind_str(impl_m),
|
||||
item_kind: assoc_item_kind_str(&impl_m),
|
||||
ident: impl_m.ident(tcx),
|
||||
generics_span,
|
||||
bounds_span,
|
||||
|
|
@ -1060,8 +1056,8 @@ fn extract_spans_for_error_reporting<'tcx>(
|
|||
infcx: &infer::InferCtxt<'tcx>,
|
||||
terr: TypeError<'_>,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
impl_m: &ty::AssocItem,
|
||||
trait_m: &ty::AssocItem,
|
||||
impl_m: ty::AssocItem,
|
||||
trait_m: ty::AssocItem,
|
||||
) -> (Span, Option<Span>) {
|
||||
let tcx = infcx.tcx;
|
||||
let mut impl_args = {
|
||||
|
|
@ -1084,8 +1080,8 @@ fn extract_spans_for_error_reporting<'tcx>(
|
|||
|
||||
fn compare_self_type<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl_m: &ty::AssocItem,
|
||||
trait_m: &ty::AssocItem,
|
||||
impl_m: ty::AssocItem,
|
||||
trait_m: ty::AssocItem,
|
||||
impl_trait_ref: ty::TraitRef<'tcx>,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
// Try to give more informative error messages about self typing
|
||||
|
|
@ -1096,7 +1092,7 @@ fn compare_self_type<'tcx>(
|
|||
// inscrutable, particularly for cases where one method has no
|
||||
// self.
|
||||
|
||||
let self_string = |method: &ty::AssocItem| {
|
||||
let self_string = |method: ty::AssocItem| {
|
||||
let untransformed_self_ty = match method.container {
|
||||
ty::ImplContainer => impl_trait_ref.self_ty(),
|
||||
ty::TraitContainer => tcx.types.self_param,
|
||||
|
|
@ -1186,8 +1182,8 @@ fn compare_self_type<'tcx>(
|
|||
/// [`compare_generic_param_kinds`]. This function also does not handle lifetime parameters
|
||||
fn compare_number_of_generics<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl_: &ty::AssocItem,
|
||||
trait_: &ty::AssocItem,
|
||||
impl_: ty::AssocItem,
|
||||
trait_: ty::AssocItem,
|
||||
delay: bool,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
let trait_own_counts = tcx.generics_of(trait_.def_id).own_counts();
|
||||
|
|
@ -1207,7 +1203,7 @@ fn compare_number_of_generics<'tcx>(
|
|||
("const", trait_own_counts.consts, impl_own_counts.consts),
|
||||
];
|
||||
|
||||
let item_kind = assoc_item_kind_str(impl_);
|
||||
let item_kind = assoc_item_kind_str(&impl_);
|
||||
|
||||
let mut err_occurred = None;
|
||||
for (kind, trait_count, impl_count) in matchings {
|
||||
|
|
@ -1329,8 +1325,8 @@ fn compare_number_of_generics<'tcx>(
|
|||
|
||||
fn compare_number_of_method_arguments<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl_m: &ty::AssocItem,
|
||||
trait_m: &ty::AssocItem,
|
||||
impl_m: ty::AssocItem,
|
||||
trait_m: ty::AssocItem,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
let impl_m_fty = tcx.fn_sig(impl_m.def_id);
|
||||
let trait_m_fty = tcx.fn_sig(trait_m.def_id);
|
||||
|
|
@ -1409,8 +1405,8 @@ fn compare_number_of_method_arguments<'tcx>(
|
|||
|
||||
fn compare_synthetic_generics<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl_m: &ty::AssocItem,
|
||||
trait_m: &ty::AssocItem,
|
||||
impl_m: ty::AssocItem,
|
||||
trait_m: ty::AssocItem,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
// FIXME(chrisvittal) Clean up this function, list of FIXME items:
|
||||
// 1. Better messages for the span labels
|
||||
|
|
@ -1563,8 +1559,8 @@ fn compare_synthetic_generics<'tcx>(
|
|||
/// This function does not handle lifetime parameters
|
||||
fn compare_generic_param_kinds<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl_item: &ty::AssocItem,
|
||||
trait_item: &ty::AssocItem,
|
||||
impl_item: ty::AssocItem,
|
||||
trait_item: ty::AssocItem,
|
||||
delay: bool,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
assert_eq!(impl_item.kind, trait_item.kind);
|
||||
|
|
@ -1609,7 +1605,11 @@ fn compare_generic_param_kinds<'tcx>(
|
|||
|
||||
let make_param_message = |prefix: &str, param: &ty::GenericParamDef| match param.kind {
|
||||
Const { .. } => {
|
||||
format!("{} const parameter of type `{}`", prefix, tcx.type_of(param.def_id))
|
||||
format!(
|
||||
"{} const parameter of type `{}`",
|
||||
prefix,
|
||||
tcx.type_of(param.def_id).subst_identity()
|
||||
)
|
||||
}
|
||||
Type { .. } => format!("{} type parameter", prefix),
|
||||
Lifetime { .. } => unreachable!(),
|
||||
|
|
@ -1658,8 +1658,8 @@ pub(super) fn compare_impl_const_raw(
|
|||
// Create a parameter environment that represents the implementation's
|
||||
// method.
|
||||
// Compute placeholder form of impl and trait const tys.
|
||||
let impl_ty = tcx.type_of(impl_const_item_def.to_def_id());
|
||||
let trait_ty = tcx.bound_type_of(trait_const_item_def).subst(tcx, trait_to_impl_substs);
|
||||
let impl_ty = tcx.type_of(impl_const_item_def.to_def_id()).subst_identity();
|
||||
let trait_ty = tcx.type_of(trait_const_item_def).subst(tcx, trait_to_impl_substs);
|
||||
let mut cause = ObligationCause::new(
|
||||
impl_c_span,
|
||||
impl_const_item_def,
|
||||
|
|
@ -1736,8 +1736,8 @@ pub(super) fn compare_impl_const_raw(
|
|||
|
||||
pub(super) fn compare_impl_ty<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl_ty: &ty::AssocItem,
|
||||
trait_ty: &ty::AssocItem,
|
||||
impl_ty: ty::AssocItem,
|
||||
trait_ty: ty::AssocItem,
|
||||
impl_trait_ref: ty::TraitRef<'tcx>,
|
||||
) {
|
||||
debug!("compare_impl_type(impl_trait_ref={:?})", impl_trait_ref);
|
||||
|
|
@ -1754,8 +1754,8 @@ pub(super) fn compare_impl_ty<'tcx>(
|
|||
/// instead of associated functions.
|
||||
fn compare_type_predicate_entailment<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl_ty: &ty::AssocItem,
|
||||
trait_ty: &ty::AssocItem,
|
||||
impl_ty: ty::AssocItem,
|
||||
trait_ty: ty::AssocItem,
|
||||
impl_trait_ref: ty::TraitRef<'tcx>,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
let impl_substs = InternalSubsts::identity_for_item(tcx, impl_ty.def_id);
|
||||
|
|
@ -1855,8 +1855,8 @@ fn compare_type_predicate_entailment<'tcx>(
|
|||
#[instrument(level = "debug", skip(tcx))]
|
||||
pub(super) fn check_type_bounds<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_ty: &ty::AssocItem,
|
||||
impl_ty: &ty::AssocItem,
|
||||
trait_ty: ty::AssocItem,
|
||||
impl_ty: ty::AssocItem,
|
||||
impl_trait_ref: ty::TraitRef<'tcx>,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
// Given
|
||||
|
|
@ -1920,10 +1920,10 @@ pub(super) fn check_type_bounds<'tcx>(
|
|||
let kind = ty::BoundRegionKind::BrNamed(param.def_id, param.name);
|
||||
let bound_var = ty::BoundVariableKind::Region(kind);
|
||||
bound_vars.push(bound_var);
|
||||
tcx.mk_region(ty::ReLateBound(
|
||||
tcx.mk_re_late_bound(
|
||||
ty::INNERMOST,
|
||||
ty::BoundRegion { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind },
|
||||
))
|
||||
)
|
||||
.into()
|
||||
}
|
||||
GenericParamDefKind::Const { .. } => {
|
||||
|
|
@ -1931,17 +1931,17 @@ pub(super) fn check_type_bounds<'tcx>(
|
|||
bound_vars.push(bound_var);
|
||||
tcx.mk_const(
|
||||
ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_usize(bound_vars.len() - 1)),
|
||||
tcx.type_of(param.def_id),
|
||||
tcx.type_of(param.def_id).subst_identity(),
|
||||
)
|
||||
.into()
|
||||
}
|
||||
});
|
||||
let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter());
|
||||
let bound_vars = tcx.intern_bound_variable_kinds(&bound_vars);
|
||||
let impl_ty_substs = tcx.intern_substs(&substs);
|
||||
let container_id = impl_ty.container_id(tcx);
|
||||
|
||||
let rebased_substs = impl_ty_substs.rebase_onto(tcx, container_id, impl_trait_ref.substs);
|
||||
let impl_ty_value = tcx.type_of(impl_ty.def_id);
|
||||
let impl_ty_value = tcx.type_of(impl_ty.def_id).subst_identity();
|
||||
|
||||
let param_env = tcx.param_env(impl_ty.def_id);
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ use rustc_middle::ty::{self, Predicate, Ty, TyCtxt};
|
|||
/// cannot do `struct S<T>; impl<T:Clone> Drop for S<T> { ... }`).
|
||||
///
|
||||
pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), ErrorGuaranteed> {
|
||||
let dtor_self_type = tcx.type_of(drop_impl_did);
|
||||
let dtor_self_type = tcx.type_of(drop_impl_did).subst_identity();
|
||||
let dtor_predicates = tcx.predicates_of(drop_impl_did);
|
||||
match dtor_self_type.kind() {
|
||||
ty::Adt(adt_def, self_to_impl_substs) => {
|
||||
|
|
|
|||
|
|
@ -15,8 +15,6 @@ use rustc_middle::ty::{self, TyCtxt};
|
|||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
use std::iter;
|
||||
|
||||
fn equate_intrinsic_type<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
it: &hir::ForeignItem<'_>,
|
||||
|
|
@ -139,25 +137,21 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
|
|||
let intrinsic_name = tcx.item_name(intrinsic_id);
|
||||
let name_str = intrinsic_name.as_str();
|
||||
|
||||
let bound_vars = tcx.mk_bound_variable_kinds(
|
||||
[
|
||||
ty::BoundVariableKind::Region(ty::BrAnon(0, None)),
|
||||
ty::BoundVariableKind::Region(ty::BrEnv),
|
||||
]
|
||||
.iter()
|
||||
.copied(),
|
||||
);
|
||||
let bound_vars = tcx.intern_bound_variable_kinds(&[
|
||||
ty::BoundVariableKind::Region(ty::BrAnon(0, None)),
|
||||
ty::BoundVariableKind::Region(ty::BrEnv),
|
||||
]);
|
||||
let mk_va_list_ty = |mutbl| {
|
||||
tcx.lang_items().va_list().map(|did| {
|
||||
let region = tcx.mk_region(ty::ReLateBound(
|
||||
let region = tcx.mk_re_late_bound(
|
||||
ty::INNERMOST,
|
||||
ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(0, None) },
|
||||
));
|
||||
let env_region = tcx.mk_region(ty::ReLateBound(
|
||||
);
|
||||
let env_region = tcx.mk_re_late_bound(
|
||||
ty::INNERMOST,
|
||||
ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrEnv },
|
||||
));
|
||||
let va_list_ty = tcx.bound_type_of(did).subst(tcx, &[region.into()]);
|
||||
);
|
||||
let va_list_ty = tcx.type_of(did).subst(tcx, &[region.into()]);
|
||||
(tcx.mk_ref(env_region, ty::TypeAndMut { ty: va_list_ty, mutbl }), va_list_ty)
|
||||
})
|
||||
};
|
||||
|
|
@ -377,24 +371,22 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
|
|||
ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(0, None) };
|
||||
(
|
||||
1,
|
||||
vec![
|
||||
tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)), param(0)),
|
||||
],
|
||||
tcx.mk_projection(discriminant_def_id, tcx.mk_substs([param(0).into()].iter())),
|
||||
vec![tcx.mk_imm_ref(tcx.mk_re_late_bound(ty::INNERMOST, br), param(0))],
|
||||
tcx.mk_projection(discriminant_def_id, tcx.intern_substs(&[param(0).into()])),
|
||||
)
|
||||
}
|
||||
|
||||
kw::Try => {
|
||||
let mut_u8 = tcx.mk_mut_ptr(tcx.types.u8);
|
||||
let try_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig(
|
||||
iter::once(mut_u8),
|
||||
[mut_u8],
|
||||
tcx.mk_unit(),
|
||||
false,
|
||||
hir::Unsafety::Normal,
|
||||
Abi::Rust,
|
||||
));
|
||||
let catch_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig(
|
||||
[mut_u8, mut_u8].iter().cloned(),
|
||||
[mut_u8, mut_u8],
|
||||
tcx.mk_unit(),
|
||||
false,
|
||||
hir::Unsafety::Normal,
|
||||
|
|
@ -430,8 +422,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
|
|||
sym::raw_eq => {
|
||||
let br =
|
||||
ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(0, None) };
|
||||
let param_ty =
|
||||
tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)), param(0));
|
||||
let param_ty = tcx.mk_imm_ref(tcx.mk_re_late_bound(ty::INNERMOST, br), param(0));
|
||||
(1, vec![param_ty; 2], tcx.types.bool)
|
||||
}
|
||||
|
||||
|
|
@ -450,7 +441,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
|
|||
};
|
||||
(n_tps, 0, inputs, output, unsafety)
|
||||
};
|
||||
let sig = tcx.mk_fn_sig(inputs.into_iter(), output, false, unsafety, Abi::RustIntrinsic);
|
||||
let sig = tcx.mk_fn_sig(inputs, output, false, unsafety, Abi::RustIntrinsic);
|
||||
let sig = ty::Binder::bind_with_vars(sig, bound_vars);
|
||||
equate_intrinsic_type(tcx, it, n_tps, n_lts, sig)
|
||||
}
|
||||
|
|
@ -548,13 +539,7 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
|
|||
}
|
||||
};
|
||||
|
||||
let sig = tcx.mk_fn_sig(
|
||||
inputs.into_iter(),
|
||||
output,
|
||||
false,
|
||||
hir::Unsafety::Unsafe,
|
||||
Abi::PlatformIntrinsic,
|
||||
);
|
||||
let sig = tcx.mk_fn_sig(inputs, output, false, hir::Unsafety::Unsafe, Abi::PlatformIntrinsic);
|
||||
let sig = ty::Binder::dummy(sig);
|
||||
equate_intrinsic_type(tcx, it, n_tps, 0, sig)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -414,7 +414,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
|||
// Check that sym actually points to a function. Later passes
|
||||
// depend on this.
|
||||
hir::InlineAsmOperand::SymFn { anon_const } => {
|
||||
let ty = self.tcx.type_of(anon_const.def_id);
|
||||
let ty = self.tcx.type_of(anon_const.def_id).subst_identity();
|
||||
match ty.kind() {
|
||||
ty::Never | ty::Error(_) => {}
|
||||
ty::FnDef(..) => {}
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ fn report_forbidden_specialization(tcx: TyCtxt<'_>, impl_item: DefId, parent_imp
|
|||
fn missing_items_err(
|
||||
tcx: TyCtxt<'_>,
|
||||
impl_span: Span,
|
||||
missing_items: &[&ty::AssocItem],
|
||||
missing_items: &[ty::AssocItem],
|
||||
full_impl_span: Span,
|
||||
) {
|
||||
let missing_items_msg = missing_items
|
||||
|
|
@ -225,7 +225,7 @@ fn missing_items_err(
|
|||
let padding =
|
||||
tcx.sess.source_map().indentation_before(sugg_sp).unwrap_or_else(|| String::new());
|
||||
|
||||
for trait_item in missing_items {
|
||||
for &trait_item in missing_items {
|
||||
let snippet = suggestion_signature(trait_item, tcx);
|
||||
let code = format!("{}{}\n{}", padding, snippet, padding);
|
||||
let msg = format!("implement the missing item: `{snippet}`");
|
||||
|
|
@ -272,7 +272,7 @@ fn default_body_is_unstable(
|
|||
reason: Option<Symbol>,
|
||||
issue: Option<NonZeroU32>,
|
||||
) {
|
||||
let missing_item_name = &tcx.associated_item(item_did).name;
|
||||
let missing_item_name = tcx.associated_item(item_did).name;
|
||||
let use_of_unstable_library_feature_note = match reason {
|
||||
Some(r) => format!("use of unstable library feature '{feature}': {r}"),
|
||||
None => format!("use of unstable library feature '{feature}'"),
|
||||
|
|
@ -365,7 +365,7 @@ fn fn_sig_suggestion<'tcx>(
|
|||
sig: ty::FnSig<'tcx>,
|
||||
ident: Ident,
|
||||
predicates: ty::GenericPredicates<'tcx>,
|
||||
assoc: &ty::AssocItem,
|
||||
assoc: ty::AssocItem,
|
||||
) -> String {
|
||||
let args = sig
|
||||
.inputs()
|
||||
|
|
@ -433,7 +433,7 @@ pub fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> {
|
|||
/// Return placeholder code for the given associated item.
|
||||
/// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
|
||||
/// structured suggestion.
|
||||
fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
|
||||
fn suggestion_signature(assoc: ty::AssocItem, tcx: TyCtxt<'_>) -> String {
|
||||
match assoc.kind {
|
||||
ty::AssocKind::Fn => {
|
||||
// We skip the binder here because the binder would deanonymize all
|
||||
|
|
@ -450,7 +450,7 @@ fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
|
|||
}
|
||||
ty::AssocKind::Type => format!("type {} = Type;", assoc.name),
|
||||
ty::AssocKind::Const => {
|
||||
let ty = tcx.type_of(assoc.def_id);
|
||||
let ty = tcx.type_of(assoc.def_id).subst_identity();
|
||||
let val = ty_kind_suggestion(ty).unwrap_or("value");
|
||||
format!("const {}: {} = {};", assoc.name, ty, val)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -607,12 +607,11 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<'tcx>>(
|
|||
// Same for the region. In our example, 'a corresponds
|
||||
// to the 'me parameter.
|
||||
let region_param = gat_generics.param_at(*region_a_idx, tcx);
|
||||
let region_param =
|
||||
tcx.mk_region(ty::RegionKind::ReEarlyBound(ty::EarlyBoundRegion {
|
||||
def_id: region_param.def_id,
|
||||
index: region_param.index,
|
||||
name: region_param.name,
|
||||
}));
|
||||
let region_param = tcx.mk_re_early_bound(ty::EarlyBoundRegion {
|
||||
def_id: region_param.def_id,
|
||||
index: region_param.index,
|
||||
name: region_param.name,
|
||||
});
|
||||
// The predicate we expect to see. (In our example,
|
||||
// `Self: 'me`.)
|
||||
let clause = ty::PredicateKind::Clause(ty::Clause::TypeOutlives(
|
||||
|
|
@ -645,20 +644,18 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<'tcx>>(
|
|||
debug!("required clause: {region_a} must outlive {region_b}");
|
||||
// Translate into the generic parameters of the GAT.
|
||||
let region_a_param = gat_generics.param_at(*region_a_idx, tcx);
|
||||
let region_a_param =
|
||||
tcx.mk_region(ty::RegionKind::ReEarlyBound(ty::EarlyBoundRegion {
|
||||
def_id: region_a_param.def_id,
|
||||
index: region_a_param.index,
|
||||
name: region_a_param.name,
|
||||
}));
|
||||
let region_a_param = tcx.mk_re_early_bound(ty::EarlyBoundRegion {
|
||||
def_id: region_a_param.def_id,
|
||||
index: region_a_param.index,
|
||||
name: region_a_param.name,
|
||||
});
|
||||
// Same for the region.
|
||||
let region_b_param = gat_generics.param_at(*region_b_idx, tcx);
|
||||
let region_b_param =
|
||||
tcx.mk_region(ty::RegionKind::ReEarlyBound(ty::EarlyBoundRegion {
|
||||
def_id: region_b_param.def_id,
|
||||
index: region_b_param.index,
|
||||
name: region_b_param.name,
|
||||
}));
|
||||
let region_b_param = tcx.mk_re_early_bound(ty::EarlyBoundRegion {
|
||||
def_id: region_b_param.def_id,
|
||||
index: region_b_param.index,
|
||||
name: region_b_param.name,
|
||||
});
|
||||
// The predicate we expect to see.
|
||||
let clause = ty::PredicateKind::Clause(ty::Clause::RegionOutlives(
|
||||
ty::OutlivesPredicate(region_a_param, region_b_param),
|
||||
|
|
@ -877,7 +874,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
|
|||
|
||||
// Const parameters are well formed if their type is structural match.
|
||||
hir::GenericParamKind::Const { ty: hir_ty, default: _ } => {
|
||||
let ty = tcx.type_of(param.def_id);
|
||||
let ty = tcx.type_of(param.def_id).subst_identity();
|
||||
|
||||
if tcx.features().adt_const_params {
|
||||
if let Some(non_structural_match_ty) =
|
||||
|
|
@ -1014,12 +1011,12 @@ fn check_associated_item(
|
|||
|
||||
let self_ty = match item.container {
|
||||
ty::TraitContainer => tcx.types.self_param,
|
||||
ty::ImplContainer => tcx.type_of(item.container_id(tcx)),
|
||||
ty::ImplContainer => tcx.type_of(item.container_id(tcx)).subst_identity(),
|
||||
};
|
||||
|
||||
match item.kind {
|
||||
ty::AssocKind::Const => {
|
||||
let ty = tcx.type_of(item.def_id);
|
||||
let ty = tcx.type_of(item.def_id).subst_identity();
|
||||
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
|
||||
wfcx.register_wf_obligation(span, loc, ty.into());
|
||||
}
|
||||
|
|
@ -1040,7 +1037,7 @@ fn check_associated_item(
|
|||
check_associated_type_bounds(wfcx, item, span)
|
||||
}
|
||||
if item.defaultness(tcx).has_value() {
|
||||
let ty = tcx.type_of(item.def_id);
|
||||
let ty = tcx.type_of(item.def_id).subst_identity();
|
||||
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
|
||||
wfcx.register_wf_obligation(span, loc, ty.into());
|
||||
}
|
||||
|
|
@ -1073,7 +1070,7 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b
|
|||
let field_id = field.did.expect_local();
|
||||
let hir::FieldDef { ty: hir_ty, .. } =
|
||||
tcx.hir().get_by_def_id(field_id).expect_field();
|
||||
let ty = wfcx.normalize(hir_ty.span, None, tcx.type_of(field.did));
|
||||
let ty = wfcx.normalize(hir_ty.span, None, tcx.type_of(field.did).subst_identity());
|
||||
wfcx.register_wf_obligation(
|
||||
hir_ty.span,
|
||||
Some(WellFormedLoc::Ty(field_id)),
|
||||
|
|
@ -1085,7 +1082,7 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b
|
|||
// intermediate types must be sized.
|
||||
let needs_drop_copy = || {
|
||||
packed && {
|
||||
let ty = tcx.type_of(variant.fields.last().unwrap().did);
|
||||
let ty = tcx.type_of(variant.fields.last().unwrap().did).subst_identity();
|
||||
let ty = tcx.erase_regions(ty);
|
||||
if ty.needs_infer() {
|
||||
tcx.sess
|
||||
|
|
@ -1107,7 +1104,7 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b
|
|||
let field_id = field.did.expect_local();
|
||||
let hir::FieldDef { ty: hir_ty, .. } =
|
||||
tcx.hir().get_by_def_id(field_id).expect_field();
|
||||
let ty = wfcx.normalize(hir_ty.span, None, tcx.type_of(field.did));
|
||||
let ty = wfcx.normalize(hir_ty.span, None, tcx.type_of(field.did).subst_identity());
|
||||
wfcx.register_bound(
|
||||
traits::ObligationCause::new(
|
||||
hir_ty.span,
|
||||
|
|
@ -1183,7 +1180,7 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {
|
|||
///
|
||||
/// Assuming the defaults are used, check that all predicates (bounds on the
|
||||
/// assoc type and where clauses on the trait) hold.
|
||||
fn check_associated_type_bounds(wfcx: &WfCheckingCtxt<'_, '_>, item: &ty::AssocItem, span: Span) {
|
||||
fn check_associated_type_bounds(wfcx: &WfCheckingCtxt<'_, '_>, item: ty::AssocItem, span: Span) {
|
||||
let bounds = wfcx.tcx().explicit_item_bounds(item.def_id);
|
||||
|
||||
debug!("check_associated_type_bounds: bounds={:?}", bounds);
|
||||
|
|
@ -1218,7 +1215,7 @@ fn check_item_type(tcx: TyCtxt<'_>, item_id: LocalDefId, ty_span: Span, allow_fo
|
|||
debug!("check_item_type: {:?}", item_id);
|
||||
|
||||
enter_wf_checking_ctxt(tcx, ty_span, item_id, |wfcx| {
|
||||
let ty = tcx.type_of(item_id);
|
||||
let ty = tcx.type_of(item_id).subst_identity();
|
||||
let item_ty = wfcx.normalize(ty_span, Some(WellFormedLoc::Ty(item_id)), ty);
|
||||
|
||||
let mut forbid_unsized = true;
|
||||
|
|
@ -1303,7 +1300,7 @@ fn check_impl<'tcx>(
|
|||
wfcx.register_obligations(obligations);
|
||||
}
|
||||
None => {
|
||||
let self_ty = tcx.type_of(item.owner_id);
|
||||
let self_ty = tcx.type_of(item.owner_id).subst_identity();
|
||||
let self_ty = wfcx.normalize(
|
||||
item.span,
|
||||
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
|
||||
|
|
@ -1348,7 +1345,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
|
|||
match param.kind {
|
||||
GenericParamDefKind::Type { .. } => {
|
||||
if is_our_default(param) {
|
||||
let ty = tcx.type_of(param.def_id);
|
||||
let ty = tcx.type_of(param.def_id).subst_identity();
|
||||
// Ignore dependent defaults -- that is, where the default of one type
|
||||
// parameter includes another (e.g., `<T, U = T>`). In those cases, we can't
|
||||
// be sure if it will error or not as user might always specify the other.
|
||||
|
|
@ -1400,7 +1397,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
|
|||
GenericParamDefKind::Type { .. } => {
|
||||
// If the param has a default, ...
|
||||
if is_our_default(param) {
|
||||
let default_ty = tcx.type_of(param.def_id);
|
||||
let default_ty = tcx.type_of(param.def_id).subst_identity();
|
||||
// ... and it's not a dependent default, ...
|
||||
if !default_ty.needs_subst() {
|
||||
// ... then substitute it with the default.
|
||||
|
|
@ -1633,7 +1630,7 @@ const HELP_FOR_SELF_TYPE: &str = "consider changing to `self`, `&self`, `&mut se
|
|||
fn check_method_receiver<'tcx>(
|
||||
wfcx: &WfCheckingCtxt<'_, 'tcx>,
|
||||
fn_sig: &hir::FnSig<'_>,
|
||||
method: &ty::AssocItem,
|
||||
method: ty::AssocItem,
|
||||
self_ty: Ty<'tcx>,
|
||||
) {
|
||||
let tcx = wfcx.tcx();
|
||||
|
|
@ -1816,7 +1813,7 @@ fn check_variances_for_type_defn<'tcx>(
|
|||
item: &hir::Item<'tcx>,
|
||||
hir_generics: &hir::Generics<'_>,
|
||||
) {
|
||||
let ty = tcx.type_of(item.owner_id);
|
||||
let ty = tcx.type_of(item.owner_id).subst_identity();
|
||||
if tcx.has_error_field(ty) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ impl<'tcx> Checker<'tcx> {
|
|||
|
||||
fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
|
||||
// Destructors only work on local ADT types.
|
||||
match tcx.type_of(impl_did).kind() {
|
||||
match tcx.type_of(impl_did).subst_identity().kind() {
|
||||
ty::Adt(def, _) if def.did().is_local() => return,
|
||||
ty::Error(_) => return,
|
||||
_ => {}
|
||||
|
|
@ -64,7 +64,7 @@ fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
|
|||
fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
|
||||
debug!("visit_implementation_of_copy: impl_did={:?}", impl_did);
|
||||
|
||||
let self_type = tcx.type_of(impl_did);
|
||||
let self_type = tcx.type_of(impl_did).subst_identity();
|
||||
debug!("visit_implementation_of_copy: self_type={:?} (bound)", self_type);
|
||||
|
||||
let param_env = tcx.param_env(impl_did);
|
||||
|
|
@ -206,7 +206,7 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
|
|||
|
||||
let dispatch_from_dyn_trait = tcx.require_lang_item(LangItem::DispatchFromDyn, Some(span));
|
||||
|
||||
let source = tcx.type_of(impl_did);
|
||||
let source = tcx.type_of(impl_did).subst_identity();
|
||||
assert!(!source.has_escaping_bound_vars());
|
||||
let target = {
|
||||
let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().subst_identity();
|
||||
|
|
@ -370,7 +370,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
|
|||
tcx.sess.fatal(&format!("`CoerceUnsized` implementation {}", err.to_string()));
|
||||
});
|
||||
|
||||
let source = tcx.type_of(impl_did);
|
||||
let source = tcx.type_of(impl_did).subst_identity();
|
||||
let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().subst_identity();
|
||||
assert_eq!(trait_ref.def_id, coerce_unsized_trait);
|
||||
let target = trait_ref.substs.type_at(1);
|
||||
|
|
@ -482,7 +482,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
|
|||
.filter_map(|(i, f)| {
|
||||
let (a, b) = (f.ty(tcx, substs_a), f.ty(tcx, substs_b));
|
||||
|
||||
if tcx.type_of(f.did).is_phantom_data() {
|
||||
if tcx.type_of(f.did).subst_identity().is_phantom_data() {
|
||||
// Ignore PhantomData fields
|
||||
return None;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ impl<'tcx> InherentCollect<'tcx> {
|
|||
|
||||
let id = id.owner_id.def_id;
|
||||
let item_span = self.tcx.def_span(id);
|
||||
let self_ty = self.tcx.type_of(id);
|
||||
let self_ty = self.tcx.type_of(id).subst_identity();
|
||||
match *self_ty.kind() {
|
||||
ty::Adt(def, _) => self.check_def_id(id, self_ty, def.did()),
|
||||
ty::Foreign(did) => self.check_def_id(id, self_ty, did),
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
|
|||
/// namespace.
|
||||
fn impls_have_common_items(
|
||||
&self,
|
||||
impl_items1: &ty::AssocItems<'_>,
|
||||
impl_items2: &ty::AssocItems<'_>,
|
||||
impl_items1: &ty::AssocItems,
|
||||
impl_items2: &ty::AssocItems,
|
||||
) -> bool {
|
||||
let mut impl_items1 = &impl_items1;
|
||||
let mut impl_items2 = &impl_items2;
|
||||
|
|
@ -38,10 +38,10 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
|
|||
std::mem::swap(&mut impl_items1, &mut impl_items2);
|
||||
}
|
||||
|
||||
for item1 in impl_items1.in_definition_order() {
|
||||
for &item1 in impl_items1.in_definition_order() {
|
||||
let collision = impl_items2
|
||||
.filter_by_name_unhygienic(item1.name)
|
||||
.any(|item2| self.compare_hygienically(item1, item2));
|
||||
.any(|&item2| self.compare_hygienically(item1, item2));
|
||||
|
||||
if collision {
|
||||
return true;
|
||||
|
|
@ -51,7 +51,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
|
|||
false
|
||||
}
|
||||
|
||||
fn compare_hygienically(&self, item1: &ty::AssocItem, item2: &ty::AssocItem) -> bool {
|
||||
fn compare_hygienically(&self, item1: ty::AssocItem, item2: ty::AssocItem) -> bool {
|
||||
// Symbols and namespace match, compare hygienically.
|
||||
item1.kind.namespace() == item2.kind.namespace()
|
||||
&& item1.ident(self.tcx).normalize_to_macros_2_0()
|
||||
|
|
@ -98,10 +98,10 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
|
|||
let impl_items1 = self.tcx.associated_items(impl1);
|
||||
let impl_items2 = self.tcx.associated_items(impl2);
|
||||
|
||||
for item1 in impl_items1.in_definition_order() {
|
||||
for &item1 in impl_items1.in_definition_order() {
|
||||
let collision = impl_items2
|
||||
.filter_by_name_unhygienic(item1.name)
|
||||
.find(|item2| self.compare_hygienically(item1, item2));
|
||||
.find(|&&item2| self.compare_hygienically(item1, item2));
|
||||
|
||||
if let Some(item2) = collision {
|
||||
let name = item1.ident(self.tcx).normalize_to_macros_2_0();
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ use std::iter;
|
|||
|
||||
mod generics_of;
|
||||
mod item_bounds;
|
||||
mod lifetimes;
|
||||
mod predicates_of;
|
||||
mod resolve_bound_vars;
|
||||
mod type_of;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -53,7 +53,7 @@ fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
|
|||
}
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
lifetimes::provide(providers);
|
||||
resolve_bound_vars::provide(providers);
|
||||
*providers = Providers {
|
||||
opt_const_param_of: type_of::opt_const_param_of,
|
||||
type_of: type_of::type_of,
|
||||
|
|
@ -458,13 +458,11 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
|
|||
self.tcx.replace_late_bound_regions_uncached(
|
||||
poly_trait_ref,
|
||||
|_| {
|
||||
self.tcx.mk_region(ty::ReEarlyBound(
|
||||
ty::EarlyBoundRegion {
|
||||
def_id: item_def_id,
|
||||
index: 0,
|
||||
name: Symbol::intern(<_name),
|
||||
},
|
||||
))
|
||||
self.tcx.mk_re_early_bound(ty::EarlyBoundRegion {
|
||||
def_id: item_def_id,
|
||||
index: 0,
|
||||
name: Symbol::intern(<_name),
|
||||
})
|
||||
}
|
||||
),
|
||||
),
|
||||
|
|
@ -1145,8 +1143,8 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<ty::PolyFnSig<'_>>
|
|||
}
|
||||
|
||||
Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor().is_some() => {
|
||||
let ty = tcx.type_of(tcx.hir().get_parent_item(hir_id));
|
||||
let inputs = data.fields().iter().map(|f| tcx.type_of(f.def_id));
|
||||
let ty = tcx.type_of(tcx.hir().get_parent_item(hir_id)).subst_identity();
|
||||
let inputs = data.fields().iter().map(|f| tcx.type_of(f.def_id).subst_identity());
|
||||
ty::Binder::dummy(tcx.mk_fn_sig(
|
||||
inputs,
|
||||
ty,
|
||||
|
|
@ -1347,7 +1345,7 @@ fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::EarlyBinder<ty::
|
|||
.of_trait
|
||||
.as_ref()
|
||||
.map(|ast_trait_ref| {
|
||||
let selfty = tcx.type_of(def_id);
|
||||
let selfty = tcx.type_of(def_id).subst_identity();
|
||||
icx.astconv().instantiate_mono_trait_ref(
|
||||
ast_trait_ref,
|
||||
selfty,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::middle::resolve_lifetime as rl;
|
||||
use crate::middle::resolve_bound_vars as rbv;
|
||||
use hir::{
|
||||
intravisit::{self, Visitor},
|
||||
GenericParamKind, HirId, Node,
|
||||
|
|
@ -394,10 +394,16 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
|
|||
return;
|
||||
}
|
||||
|
||||
match self.tcx.named_region(lt.hir_id) {
|
||||
Some(rl::Region::Static | rl::Region::EarlyBound(..)) => {}
|
||||
Some(rl::Region::LateBound(debruijn, _, _)) if debruijn < self.outer_index => {}
|
||||
Some(rl::Region::LateBound(..) | rl::Region::Free(..)) | None => {
|
||||
match self.tcx.named_bound_var(lt.hir_id) {
|
||||
Some(rbv::ResolvedArg::StaticLifetime | rbv::ResolvedArg::EarlyBound(..)) => {}
|
||||
Some(rbv::ResolvedArg::LateBound(debruijn, _, _))
|
||||
if debruijn < self.outer_index => {}
|
||||
Some(
|
||||
rbv::ResolvedArg::LateBound(..)
|
||||
| rbv::ResolvedArg::Free(..)
|
||||
| rbv::ResolvedArg::Error(_),
|
||||
)
|
||||
| None => {
|
||||
self.has_late_bound_regions = Some(lt.ident.span);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ use rustc_hir::def::DefKind;
|
|||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_middle::ty::subst::InternalSubsts;
|
||||
use rustc_middle::ty::ToPredicate;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{GenericPredicates, ToPredicate};
|
||||
use rustc_span::symbol::{sym, Ident};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
|
|
@ -151,7 +151,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
|||
trace!(?generics);
|
||||
|
||||
// Collect the predicates that were written inline by the user on each
|
||||
// type parameter (e.g., `<T: Foo>`).
|
||||
// type parameter (e.g., `<T: Foo>`). Also add `ConstArgHasType` predicates
|
||||
// for each const parameter.
|
||||
for param in ast_generics.params {
|
||||
match param.kind {
|
||||
// We already dealt with early bound lifetimes above.
|
||||
|
|
@ -175,7 +176,19 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
|||
trace!(?predicates);
|
||||
}
|
||||
GenericParamKind::Const { .. } => {
|
||||
// Bounds on const parameters are currently not possible.
|
||||
let name = param.name.ident().name;
|
||||
let param_const = ty::ParamConst::new(index, name);
|
||||
|
||||
let ct_ty = tcx.type_of(param.def_id.to_def_id()).subst_identity();
|
||||
|
||||
let ct = tcx.mk_const(param_const, ct_ty);
|
||||
|
||||
let predicate = ty::Binder::dummy(ty::PredicateKind::Clause(
|
||||
ty::Clause::ConstArgHasType(ct, ct_ty),
|
||||
))
|
||||
.to_predicate(tcx);
|
||||
predicates.insert((predicate, param.span));
|
||||
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -251,7 +264,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
|||
// in trait checking. See `setup_constraining_predicates`
|
||||
// for details.
|
||||
if let Node::Item(&Item { kind: ItemKind::Impl { .. }, .. }) = node {
|
||||
let self_ty = tcx.type_of(def_id);
|
||||
let self_ty = tcx.type_of(def_id).subst_identity();
|
||||
let trait_ref = tcx.impl_trait_ref(def_id).map(ty::EarlyBinder::subst_identity);
|
||||
cgp::setup_constraining_predicates(
|
||||
tcx,
|
||||
|
|
@ -284,11 +297,11 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
|||
|
||||
let Some(dup_index) = generics.param_def_id_to_index(tcx, dup_def) else { bug!() };
|
||||
|
||||
let dup_region = tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
|
||||
let dup_region = tcx.mk_re_early_bound(ty::EarlyBoundRegion {
|
||||
def_id: dup_def,
|
||||
index: dup_index,
|
||||
name: duplicate.name.ident().name,
|
||||
}));
|
||||
});
|
||||
predicates.push((
|
||||
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::RegionOutlives(
|
||||
ty::OutlivesPredicate(orig_region, dup_region),
|
||||
|
|
@ -439,7 +452,9 @@ pub(super) fn explicit_predicates_of<'tcx>(
|
|||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
|
||||
let parent_def_id = tcx.hir().get_parent_item(hir_id);
|
||||
|
||||
if tcx.hir().opt_const_param_default_param_def_id(hir_id).is_some() {
|
||||
if let Some(defaulted_param_def_id) =
|
||||
tcx.hir().opt_const_param_default_param_def_id(hir_id)
|
||||
{
|
||||
// In `generics_of` we set the generics' parent to be our parent's parent which means that
|
||||
// we lose out on the predicates of our actual parent if we dont return those predicates here.
|
||||
// (See comment in `generics_of` for more information on why the parent shenanigans is necessary)
|
||||
|
|
@ -452,7 +467,39 @@ pub(super) fn explicit_predicates_of<'tcx>(
|
|||
//
|
||||
// In the above code we want the anon const to have predicates in its param env for `T: Trait`
|
||||
// and we would be calling `explicit_predicates_of(Foo)` here
|
||||
return tcx.explicit_predicates_of(parent_def_id);
|
||||
let parent_preds = tcx.explicit_predicates_of(parent_def_id);
|
||||
|
||||
// If we dont filter out `ConstArgHasType` predicates then every single defaulted const parameter
|
||||
// will ICE because of #106994. FIXME(generic_const_exprs): remove this when a more general solution
|
||||
// to #106994 is implemented.
|
||||
let filtered_predicates = parent_preds
|
||||
.predicates
|
||||
.into_iter()
|
||||
.filter(|(pred, _)| {
|
||||
if let ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, _)) =
|
||||
pred.kind().skip_binder()
|
||||
{
|
||||
match ct.kind() {
|
||||
ty::ConstKind::Param(param_const) => {
|
||||
let defaulted_param_idx = tcx
|
||||
.generics_of(parent_def_id)
|
||||
.param_def_id_to_index[&defaulted_param_def_id.to_def_id()];
|
||||
param_const.index < defaulted_param_idx
|
||||
}
|
||||
_ => bug!(
|
||||
"`ConstArgHasType` in `predicates_of`\
|
||||
that isn't a `Param` const"
|
||||
),
|
||||
}
|
||||
} else {
|
||||
true
|
||||
}
|
||||
})
|
||||
.cloned();
|
||||
return GenericPredicates {
|
||||
parent: parent_preds.parent,
|
||||
predicates: { tcx.arena.alloc_from_iter(filtered_predicates) },
|
||||
};
|
||||
}
|
||||
|
||||
let parent_def_kind = tcx.def_kind(parent_def_id);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use rustc_hir::intravisit::{self, Visitor};
|
|||
use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirIdMap, LifetimeName, Node};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::middle::resolve_lifetime::*;
|
||||
use rustc_middle::middle::resolve_bound_vars::*;
|
||||
use rustc_middle::ty::{self, ir::TypeVisitor, DefIdTree, TyCtxt, TypeSuperVisitable};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::symbol::{sym, Ident};
|
||||
|
|
@ -24,59 +24,61 @@ use rustc_span::Span;
|
|||
use std::fmt;
|
||||
|
||||
trait RegionExt {
|
||||
fn early(param: &GenericParam<'_>) -> (LocalDefId, Region);
|
||||
fn early(param: &GenericParam<'_>) -> (LocalDefId, ResolvedArg);
|
||||
|
||||
fn late(index: u32, param: &GenericParam<'_>) -> (LocalDefId, Region);
|
||||
fn late(index: u32, param: &GenericParam<'_>) -> (LocalDefId, ResolvedArg);
|
||||
|
||||
fn id(&self) -> Option<DefId>;
|
||||
|
||||
fn shifted(self, amount: u32) -> Region;
|
||||
fn shifted(self, amount: u32) -> ResolvedArg;
|
||||
}
|
||||
|
||||
impl RegionExt for Region {
|
||||
fn early(param: &GenericParam<'_>) -> (LocalDefId, Region) {
|
||||
debug!("Region::early: def_id={:?}", param.def_id);
|
||||
(param.def_id, Region::EarlyBound(param.def_id.to_def_id()))
|
||||
impl RegionExt for ResolvedArg {
|
||||
fn early(param: &GenericParam<'_>) -> (LocalDefId, ResolvedArg) {
|
||||
debug!("ResolvedArg::early: def_id={:?}", param.def_id);
|
||||
(param.def_id, ResolvedArg::EarlyBound(param.def_id.to_def_id()))
|
||||
}
|
||||
|
||||
fn late(idx: u32, param: &GenericParam<'_>) -> (LocalDefId, Region) {
|
||||
fn late(idx: u32, param: &GenericParam<'_>) -> (LocalDefId, ResolvedArg) {
|
||||
let depth = ty::INNERMOST;
|
||||
debug!(
|
||||
"Region::late: idx={:?}, param={:?} depth={:?} def_id={:?}",
|
||||
"ResolvedArg::late: idx={:?}, param={:?} depth={:?} def_id={:?}",
|
||||
idx, param, depth, param.def_id,
|
||||
);
|
||||
(param.def_id, Region::LateBound(depth, idx, param.def_id.to_def_id()))
|
||||
(param.def_id, ResolvedArg::LateBound(depth, idx, param.def_id.to_def_id()))
|
||||
}
|
||||
|
||||
fn id(&self) -> Option<DefId> {
|
||||
match *self {
|
||||
Region::Static => None,
|
||||
ResolvedArg::StaticLifetime | ResolvedArg::Error(_) => None,
|
||||
|
||||
Region::EarlyBound(id) | Region::LateBound(_, _, id) | Region::Free(_, id) => Some(id),
|
||||
ResolvedArg::EarlyBound(id)
|
||||
| ResolvedArg::LateBound(_, _, id)
|
||||
| ResolvedArg::Free(_, id) => Some(id),
|
||||
}
|
||||
}
|
||||
|
||||
fn shifted(self, amount: u32) -> Region {
|
||||
fn shifted(self, amount: u32) -> ResolvedArg {
|
||||
match self {
|
||||
Region::LateBound(debruijn, idx, id) => {
|
||||
Region::LateBound(debruijn.shifted_in(amount), idx, id)
|
||||
ResolvedArg::LateBound(debruijn, idx, id) => {
|
||||
ResolvedArg::LateBound(debruijn.shifted_in(amount), idx, id)
|
||||
}
|
||||
_ => self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Maps the id of each lifetime reference to the lifetime decl
|
||||
/// Maps the id of each bound variable reference to the variable decl
|
||||
/// that it corresponds to.
|
||||
///
|
||||
/// FIXME. This struct gets converted to a `ResolveLifetimes` for
|
||||
/// FIXME. This struct gets converted to a `ResolveBoundVars` for
|
||||
/// actual use. It has the same data, but indexed by `LocalDefId`. This
|
||||
/// is silly.
|
||||
#[derive(Debug, Default)]
|
||||
struct NamedRegionMap {
|
||||
// maps from every use of a named (not anonymous) lifetime to a
|
||||
// `Region` describing how that region is bound
|
||||
defs: HirIdMap<Region>,
|
||||
struct NamedVarMap {
|
||||
// maps from every use of a named (not anonymous) bound var to a
|
||||
// `ResolvedArg` describing how that variable is bound
|
||||
defs: HirIdMap<ResolvedArg>,
|
||||
|
||||
// Maps relevant hir items to the bound vars on them. These include:
|
||||
// - function defs
|
||||
|
|
@ -87,9 +89,9 @@ struct NamedRegionMap {
|
|||
late_bound_vars: HirIdMap<Vec<ty::BoundVariableKind>>,
|
||||
}
|
||||
|
||||
struct LifetimeContext<'a, 'tcx> {
|
||||
struct BoundVarContext<'a, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
map: &'a mut NamedRegionMap,
|
||||
map: &'a mut NamedVarMap,
|
||||
scope: ScopeRef<'a>,
|
||||
}
|
||||
|
||||
|
|
@ -102,7 +104,7 @@ enum Scope<'a> {
|
|||
Binder {
|
||||
/// We use an IndexMap here because we want these lifetimes in order
|
||||
/// for diagnostics.
|
||||
lifetimes: FxIndexMap<LocalDefId, Region>,
|
||||
bound_vars: FxIndexMap<LocalDefId, ResolvedArg>,
|
||||
|
||||
scope_type: BinderScopeType,
|
||||
|
||||
|
|
@ -141,7 +143,7 @@ enum Scope<'a> {
|
|||
/// inferred in a function body or potentially error outside one),
|
||||
/// for the default choice of lifetime in a trait object type.
|
||||
ObjectLifetimeDefault {
|
||||
lifetime: Option<Region>,
|
||||
lifetime: Option<ResolvedArg>,
|
||||
s: ScopeRef<'a>,
|
||||
},
|
||||
|
||||
|
|
@ -150,7 +152,7 @@ enum Scope<'a> {
|
|||
/// lifetimes encountered when identifying the trait that an associated type
|
||||
/// is declared on.
|
||||
Supertrait {
|
||||
lifetimes: Vec<ty::BoundVariableKind>,
|
||||
bound_vars: Vec<ty::BoundVariableKind>,
|
||||
s: ScopeRef<'a>,
|
||||
},
|
||||
|
||||
|
|
@ -185,9 +187,9 @@ struct TruncatedScopeDebug<'a>(&'a Scope<'a>);
|
|||
impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self.0 {
|
||||
Scope::Binder { lifetimes, scope_type, hir_id, where_bound_origin, s: _ } => f
|
||||
Scope::Binder { bound_vars, scope_type, hir_id, where_bound_origin, s: _ } => f
|
||||
.debug_struct("Binder")
|
||||
.field("lifetimes", lifetimes)
|
||||
.field("bound_vars", bound_vars)
|
||||
.field("scope_type", scope_type)
|
||||
.field("hir_id", hir_id)
|
||||
.field("where_bound_origin", where_bound_origin)
|
||||
|
|
@ -202,9 +204,9 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
|
|||
.field("lifetime", lifetime)
|
||||
.field("s", &"..")
|
||||
.finish(),
|
||||
Scope::Supertrait { lifetimes, s: _ } => f
|
||||
Scope::Supertrait { bound_vars, s: _ } => f
|
||||
.debug_struct("Supertrait")
|
||||
.field("lifetimes", lifetimes)
|
||||
.field("bound_vars", bound_vars)
|
||||
.field("s", &"..")
|
||||
.finish(),
|
||||
Scope::TraitRefBoundary { s: _ } => f.debug_struct("TraitRefBoundary").finish(),
|
||||
|
|
@ -219,27 +221,27 @@ type ScopeRef<'a> = &'a Scope<'a>;
|
|||
|
||||
pub(crate) fn provide(providers: &mut ty::query::Providers) {
|
||||
*providers = ty::query::Providers {
|
||||
resolve_lifetimes,
|
||||
resolve_bound_vars,
|
||||
|
||||
named_region_map: |tcx, id| tcx.resolve_lifetimes(id).defs.get(&id),
|
||||
named_variable_map: |tcx, id| tcx.resolve_bound_vars(id).defs.get(&id),
|
||||
is_late_bound_map,
|
||||
object_lifetime_default,
|
||||
late_bound_vars_map: |tcx, id| tcx.resolve_lifetimes(id).late_bound_vars.get(&id),
|
||||
late_bound_vars_map: |tcx, id| tcx.resolve_bound_vars(id).late_bound_vars.get(&id),
|
||||
|
||||
..*providers
|
||||
};
|
||||
}
|
||||
|
||||
/// Computes the `ResolveLifetimes` map that contains data for an entire `Item`.
|
||||
/// Computes the `ResolveBoundVars` map that contains data for an entire `Item`.
|
||||
/// You should not read the result of this query directly, but rather use
|
||||
/// `named_region_map`, `is_late_bound_map`, etc.
|
||||
/// `named_variable_map`, `is_late_bound_map`, etc.
|
||||
#[instrument(level = "debug", skip(tcx))]
|
||||
fn resolve_lifetimes(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveLifetimes {
|
||||
let mut named_region_map =
|
||||
NamedRegionMap { defs: Default::default(), late_bound_vars: Default::default() };
|
||||
let mut visitor = LifetimeContext {
|
||||
fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBoundVars {
|
||||
let mut named_variable_map =
|
||||
NamedVarMap { defs: Default::default(), late_bound_vars: Default::default() };
|
||||
let mut visitor = BoundVarContext {
|
||||
tcx,
|
||||
map: &mut named_region_map,
|
||||
map: &mut named_variable_map,
|
||||
scope: &Scope::Root { opt_parent_item: None },
|
||||
};
|
||||
match tcx.hir().owner(local_def_id) {
|
||||
|
|
@ -260,13 +262,13 @@ fn resolve_lifetimes(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveLife
|
|||
hir::OwnerNode::Crate(_) => {}
|
||||
}
|
||||
|
||||
let mut rl = ResolveLifetimes::default();
|
||||
let mut rl = ResolveBoundVars::default();
|
||||
|
||||
for (hir_id, v) in named_region_map.defs {
|
||||
for (hir_id, v) in named_variable_map.defs {
|
||||
let map = rl.defs.entry(hir_id.owner).or_default();
|
||||
map.insert(hir_id.local_id, v);
|
||||
}
|
||||
for (hir_id, v) in named_region_map.late_bound_vars {
|
||||
for (hir_id, v) in named_variable_map.late_bound_vars {
|
||||
let map = rl.late_bound_vars.entry(hir_id.owner).or_default();
|
||||
map.insert(hir_id.local_id, v);
|
||||
}
|
||||
|
|
@ -276,21 +278,33 @@ fn resolve_lifetimes(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveLife
|
|||
rl
|
||||
}
|
||||
|
||||
fn late_region_as_bound_region(tcx: TyCtxt<'_>, region: &Region) -> ty::BoundVariableKind {
|
||||
match region {
|
||||
Region::LateBound(_, _, def_id) => {
|
||||
fn late_arg_as_bound_arg<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
arg: &ResolvedArg,
|
||||
param: &GenericParam<'tcx>,
|
||||
) -> ty::BoundVariableKind {
|
||||
match arg {
|
||||
ResolvedArg::LateBound(_, _, def_id) => {
|
||||
let name = tcx.hir().name(tcx.hir().local_def_id_to_hir_id(def_id.expect_local()));
|
||||
ty::BoundVariableKind::Region(ty::BrNamed(*def_id, name))
|
||||
match param.kind {
|
||||
GenericParamKind::Lifetime { .. } => {
|
||||
ty::BoundVariableKind::Region(ty::BrNamed(*def_id, name))
|
||||
}
|
||||
GenericParamKind::Type { .. } => {
|
||||
ty::BoundVariableKind::Ty(ty::BoundTyKind::Param(*def_id, name))
|
||||
}
|
||||
GenericParamKind::Const { .. } => ty::BoundVariableKind::Const,
|
||||
}
|
||||
}
|
||||
_ => bug!("{:?} is not a late region", region),
|
||||
_ => bug!("{:?} is not a late argument", arg),
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
||||
/// Returns the binders in scope and the type of `Binder` that should be created for a poly trait ref.
|
||||
fn poly_trait_ref_binder_info(&mut self) -> (Vec<ty::BoundVariableKind>, BinderScopeType) {
|
||||
let mut scope = self.scope;
|
||||
let mut supertrait_lifetimes = vec![];
|
||||
let mut supertrait_bound_vars = vec![];
|
||||
loop {
|
||||
match scope {
|
||||
Scope::Body { .. } | Scope::Root { .. } => {
|
||||
|
|
@ -301,14 +315,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
scope = s;
|
||||
}
|
||||
|
||||
Scope::Supertrait { s, lifetimes } => {
|
||||
supertrait_lifetimes = lifetimes.clone();
|
||||
Scope::Supertrait { s, bound_vars } => {
|
||||
supertrait_bound_vars = bound_vars.clone();
|
||||
scope = s;
|
||||
}
|
||||
|
||||
Scope::TraitRefBoundary { .. } => {
|
||||
// We should only see super trait lifetimes if there is a `Binder` above
|
||||
assert!(supertrait_lifetimes.is_empty());
|
||||
assert!(supertrait_bound_vars.is_empty());
|
||||
break (vec![], BinderScopeType::Normal);
|
||||
}
|
||||
|
||||
|
|
@ -316,14 +330,64 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
// Nested poly trait refs have the binders concatenated
|
||||
let mut full_binders =
|
||||
self.map.late_bound_vars.entry(*hir_id).or_default().clone();
|
||||
full_binders.extend(supertrait_lifetimes.into_iter());
|
||||
full_binders.extend(supertrait_bound_vars.into_iter());
|
||||
break (full_binders, BinderScopeType::Concatenating);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_poly_trait_ref_inner(
|
||||
&mut self,
|
||||
trait_ref: &'tcx hir::PolyTraitRef<'tcx>,
|
||||
non_lifetime_binder_allowed: NonLifetimeBinderAllowed,
|
||||
) {
|
||||
debug!("visit_poly_trait_ref(trait_ref={:?})", trait_ref);
|
||||
|
||||
let (mut binders, scope_type) = self.poly_trait_ref_binder_info();
|
||||
|
||||
let initial_bound_vars = binders.len() as u32;
|
||||
let mut bound_vars: FxIndexMap<LocalDefId, ResolvedArg> = FxIndexMap::default();
|
||||
let binders_iter =
|
||||
trait_ref.bound_generic_params.iter().enumerate().map(|(late_bound_idx, param)| {
|
||||
let pair = ResolvedArg::late(initial_bound_vars + late_bound_idx as u32, param);
|
||||
let r = late_arg_as_bound_arg(self.tcx, &pair.1, param);
|
||||
bound_vars.insert(pair.0, pair.1);
|
||||
r
|
||||
});
|
||||
binders.extend(binders_iter);
|
||||
|
||||
if let NonLifetimeBinderAllowed::Deny(where_) = non_lifetime_binder_allowed {
|
||||
deny_non_region_late_bound(self.tcx, &mut bound_vars, where_);
|
||||
}
|
||||
|
||||
debug!(?binders);
|
||||
self.record_late_bound_vars(trait_ref.trait_ref.hir_ref_id, binders);
|
||||
|
||||
// Always introduce a scope here, even if this is in a where clause and
|
||||
// we introduced the binders around the bounded Ty. In that case, we
|
||||
// just reuse the concatenation functionality also present in nested trait
|
||||
// refs.
|
||||
let scope = Scope::Binder {
|
||||
hir_id: trait_ref.trait_ref.hir_ref_id,
|
||||
bound_vars,
|
||||
s: self.scope,
|
||||
scope_type,
|
||||
where_bound_origin: None,
|
||||
};
|
||||
self.with(scope, |this| {
|
||||
walk_list!(this, visit_generic_param, trait_ref.bound_generic_params);
|
||||
this.visit_trait_ref(&trait_ref.trait_ref);
|
||||
});
|
||||
}
|
||||
}
|
||||
impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
|
||||
enum NonLifetimeBinderAllowed {
|
||||
Deny(&'static str),
|
||||
Allow,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||
type NestedFilter = nested_filter::OnlyBodies;
|
||||
|
||||
fn nested_visit_map(&mut self) -> Self::Map {
|
||||
|
|
@ -386,22 +450,23 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
let (lifetimes, binders): (FxIndexMap<LocalDefId, Region>, Vec<_>) =
|
||||
let (mut bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) =
|
||||
bound_generic_params
|
||||
.iter()
|
||||
.filter(|param| matches!(param.kind, GenericParamKind::Lifetime { .. }))
|
||||
.enumerate()
|
||||
.map(|(late_bound_idx, param)| {
|
||||
let pair = Region::late(late_bound_idx as u32, param);
|
||||
let r = late_region_as_bound_region(self.tcx, &pair.1);
|
||||
let pair = ResolvedArg::late(late_bound_idx as u32, param);
|
||||
let r = late_arg_as_bound_arg(self.tcx, &pair.1, param);
|
||||
(pair, r)
|
||||
})
|
||||
.unzip();
|
||||
|
||||
deny_non_region_late_bound(self.tcx, &mut bound_vars, "closures");
|
||||
|
||||
self.record_late_bound_vars(e.hir_id, binders);
|
||||
let scope = Scope::Binder {
|
||||
hir_id: e.hir_id,
|
||||
lifetimes,
|
||||
bound_vars,
|
||||
s: self.scope,
|
||||
scope_type: BinderScopeType::Normal,
|
||||
where_bound_origin: None,
|
||||
|
|
@ -461,7 +526,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
// conservatively add all resolved lifetimes. Otherwise we run into problems in
|
||||
// cases like `type Foo<'a> = impl Bar<As = impl Baz + 'a>`.
|
||||
let parent_item = self.tcx.hir().get_parent_item(item.hir_id());
|
||||
let resolved_lifetimes: &ResolveLifetimes = self.tcx.resolve_lifetimes(parent_item);
|
||||
let resolved_lifetimes: &ResolveBoundVars =
|
||||
self.tcx.resolve_bound_vars(parent_item);
|
||||
// We need to add *all* deps, since opaque tys may want them from *us*
|
||||
for (&owner, defs) in resolved_lifetimes.defs.iter() {
|
||||
defs.iter().for_each(|(&local_id, region)| {
|
||||
|
|
@ -478,35 +544,33 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_),
|
||||
origin: hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent),
|
||||
generics,
|
||||
..
|
||||
}) => {
|
||||
// We want to start our early-bound indices at the end of the parent scope,
|
||||
// not including any parent `impl Trait`s.
|
||||
let mut lifetimes = FxIndexMap::default();
|
||||
let mut bound_vars = FxIndexMap::default();
|
||||
debug!(?generics.params);
|
||||
for param in generics.params {
|
||||
match param.kind {
|
||||
GenericParamKind::Lifetime { .. } => {
|
||||
let (def_id, reg) = Region::early(¶m);
|
||||
lifetimes.insert(def_id, reg);
|
||||
}
|
||||
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {}
|
||||
}
|
||||
let (def_id, reg) = ResolvedArg::early(¶m);
|
||||
bound_vars.insert(def_id, reg);
|
||||
}
|
||||
|
||||
let scope = Scope::Binder {
|
||||
hir_id: item.hir_id(),
|
||||
lifetimes,
|
||||
s: self.scope,
|
||||
scope_type: BinderScopeType::Normal,
|
||||
where_bound_origin: None,
|
||||
};
|
||||
let scope = Scope::Root { opt_parent_item: Some(parent) };
|
||||
self.with(scope, |this| {
|
||||
let scope = Scope::TraitRefBoundary { s: this.scope };
|
||||
this.with(scope, |this| intravisit::walk_item(this, item))
|
||||
});
|
||||
let scope = Scope::Binder {
|
||||
hir_id: item.hir_id(),
|
||||
bound_vars,
|
||||
s: this.scope,
|
||||
scope_type: BinderScopeType::Normal,
|
||||
where_bound_origin: None,
|
||||
};
|
||||
this.with(scope, |this| {
|
||||
let scope = Scope::TraitRefBoundary { s: this.scope };
|
||||
this.with(scope, |this| intravisit::walk_item(this, item))
|
||||
});
|
||||
})
|
||||
}
|
||||
hir::ItemKind::TyAlias(_, generics)
|
||||
| hir::ItemKind::Enum(_, generics)
|
||||
|
|
@ -516,18 +580,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
| hir::ItemKind::TraitAlias(generics, ..)
|
||||
| hir::ItemKind::Impl(&hir::Impl { generics, .. }) => {
|
||||
// These kinds of items have only early-bound lifetime parameters.
|
||||
let lifetimes = generics
|
||||
.params
|
||||
.iter()
|
||||
.filter_map(|param| match param.kind {
|
||||
GenericParamKind::Lifetime { .. } => Some(Region::early(param)),
|
||||
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None,
|
||||
})
|
||||
.collect();
|
||||
let bound_vars = generics.params.iter().map(ResolvedArg::early).collect();
|
||||
self.record_late_bound_vars(item.hir_id(), vec![]);
|
||||
let scope = Scope::Binder {
|
||||
hir_id: item.hir_id(),
|
||||
lifetimes,
|
||||
bound_vars,
|
||||
scope_type: BinderScopeType::Normal,
|
||||
s: self.scope,
|
||||
where_bound_origin: None,
|
||||
|
|
@ -562,21 +619,23 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
|
||||
match ty.kind {
|
||||
hir::TyKind::BareFn(c) => {
|
||||
let (lifetimes, binders): (FxIndexMap<LocalDefId, Region>, Vec<_>) = c
|
||||
let (mut bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) = c
|
||||
.generic_params
|
||||
.iter()
|
||||
.filter(|param| matches!(param.kind, GenericParamKind::Lifetime { .. }))
|
||||
.enumerate()
|
||||
.map(|(late_bound_idx, param)| {
|
||||
let pair = Region::late(late_bound_idx as u32, param);
|
||||
let r = late_region_as_bound_region(self.tcx, &pair.1);
|
||||
let pair = ResolvedArg::late(late_bound_idx as u32, param);
|
||||
let r = late_arg_as_bound_arg(self.tcx, &pair.1, param);
|
||||
(pair, r)
|
||||
})
|
||||
.unzip();
|
||||
|
||||
deny_non_region_late_bound(self.tcx, &mut bound_vars, "function pointer types");
|
||||
|
||||
self.record_late_bound_vars(ty.hir_id, binders);
|
||||
let scope = Scope::Binder {
|
||||
hir_id: ty.hir_id,
|
||||
lifetimes,
|
||||
bound_vars,
|
||||
s: self.scope,
|
||||
scope_type: BinderScopeType::Normal,
|
||||
where_bound_origin: None,
|
||||
|
|
@ -592,7 +651,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
let scope = Scope::TraitRefBoundary { s: self.scope };
|
||||
self.with(scope, |this| {
|
||||
for bound in bounds {
|
||||
this.visit_poly_trait_ref(bound);
|
||||
this.visit_poly_trait_ref_inner(
|
||||
bound,
|
||||
NonLifetimeBinderAllowed::Deny("trait object types"),
|
||||
);
|
||||
}
|
||||
});
|
||||
match lifetime.res {
|
||||
|
|
@ -674,7 +736,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
// well-supported at the moment, so this doesn't work.
|
||||
// In the future, this should be fixed and this error should be removed.
|
||||
let def = self.map.defs.get(&lifetime.hir_id).cloned();
|
||||
let Some(Region::LateBound(_, _, def_id)) = def else {
|
||||
let Some(ResolvedArg::LateBound(_, _, def_id)) = def else {
|
||||
continue
|
||||
};
|
||||
let Some(def_id) = def_id.as_local() else {
|
||||
|
|
@ -722,18 +784,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
}
|
||||
Type(bounds, ty) => {
|
||||
let generics = &trait_item.generics;
|
||||
let lifetimes = generics
|
||||
.params
|
||||
.iter()
|
||||
.filter_map(|param| match param.kind {
|
||||
GenericParamKind::Lifetime { .. } => Some(Region::early(param)),
|
||||
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None,
|
||||
})
|
||||
.collect();
|
||||
let bound_vars = generics.params.iter().map(ResolvedArg::early).collect();
|
||||
self.record_late_bound_vars(trait_item.hir_id(), vec![]);
|
||||
let scope = Scope::Binder {
|
||||
hir_id: trait_item.hir_id(),
|
||||
lifetimes,
|
||||
bound_vars,
|
||||
s: self.scope,
|
||||
scope_type: BinderScopeType::Normal,
|
||||
where_bound_origin: None,
|
||||
|
|
@ -768,18 +823,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
}),
|
||||
Type(ty) => {
|
||||
let generics = &impl_item.generics;
|
||||
let lifetimes: FxIndexMap<LocalDefId, Region> = generics
|
||||
.params
|
||||
.iter()
|
||||
.filter_map(|param| match param.kind {
|
||||
GenericParamKind::Lifetime { .. } => Some(Region::early(param)),
|
||||
GenericParamKind::Const { .. } | GenericParamKind::Type { .. } => None,
|
||||
})
|
||||
.collect();
|
||||
let bound_vars: FxIndexMap<LocalDefId, ResolvedArg> =
|
||||
generics.params.iter().map(ResolvedArg::early).collect();
|
||||
self.record_late_bound_vars(impl_item.hir_id(), vec![]);
|
||||
let scope = Scope::Binder {
|
||||
hir_id: impl_item.hir_id(),
|
||||
lifetimes,
|
||||
bound_vars,
|
||||
s: self.scope,
|
||||
scope_type: BinderScopeType::Normal,
|
||||
where_bound_origin: None,
|
||||
|
|
@ -803,7 +852,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
#[instrument(level = "debug", skip(self))]
|
||||
fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
|
||||
match lifetime_ref.res {
|
||||
hir::LifetimeName::Static => self.insert_lifetime(lifetime_ref, Region::Static),
|
||||
hir::LifetimeName::Static => {
|
||||
self.insert_lifetime(lifetime_ref, ResolvedArg::StaticLifetime)
|
||||
}
|
||||
hir::LifetimeName::Param(param_def_id) => {
|
||||
self.resolve_lifetime_ref(param_def_id, lifetime_ref)
|
||||
}
|
||||
|
|
@ -814,13 +865,16 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_path(&mut self, path: &hir::Path<'tcx>, _: hir::HirId) {
|
||||
fn visit_path(&mut self, path: &hir::Path<'tcx>, hir_id: hir::HirId) {
|
||||
for (i, segment) in path.segments.iter().enumerate() {
|
||||
let depth = path.segments.len() - i - 1;
|
||||
if let Some(args) = segment.args {
|
||||
self.visit_segment_args(path.res, depth, args);
|
||||
}
|
||||
}
|
||||
if let Res::Def(DefKind::TyParam | DefKind::ConstParam, param_def_id) = path.res {
|
||||
self.resolve_type_ref(param_def_id.expect_local(), hir_id);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_fn(
|
||||
|
|
@ -869,24 +923,17 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
origin,
|
||||
..
|
||||
}) => {
|
||||
let lifetimes: FxIndexMap<LocalDefId, Region> =
|
||||
|
||||
let (bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) =
|
||||
bound_generic_params
|
||||
.iter()
|
||||
.filter(|param| {
|
||||
matches!(param.kind, GenericParamKind::Lifetime { .. })
|
||||
})
|
||||
.enumerate()
|
||||
.map(|(late_bound_idx, param)| {
|
||||
Region::late(late_bound_idx as u32, param)
|
||||
})
|
||||
.collect();
|
||||
let binders: Vec<_> =
|
||||
lifetimes
|
||||
.iter()
|
||||
.map(|(_, region)| {
|
||||
late_region_as_bound_region(this.tcx, region)
|
||||
})
|
||||
.collect();
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(late_bound_idx, param)| {
|
||||
let pair = ResolvedArg::late(late_bound_idx as u32, param);
|
||||
let r = late_arg_as_bound_arg(this.tcx, &pair.1, param);
|
||||
(pair, r)
|
||||
})
|
||||
.unzip();
|
||||
this.record_late_bound_vars(hir_id, binders.clone());
|
||||
// Even if there are no lifetimes defined here, we still wrap it in a binder
|
||||
// scope. If there happens to be a nested poly trait ref (an error), that
|
||||
|
|
@ -894,7 +941,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
// being wrong.
|
||||
let scope = Scope::Binder {
|
||||
hir_id,
|
||||
lifetimes,
|
||||
bound_vars,
|
||||
s: this.scope,
|
||||
scope_type: BinderScopeType::Normal,
|
||||
where_bound_origin: Some(origin),
|
||||
|
|
@ -920,7 +967,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
if lt.res != hir::LifetimeName::Static {
|
||||
continue;
|
||||
}
|
||||
this.insert_lifetime(lt, Region::Static);
|
||||
this.insert_lifetime(lt, ResolvedArg::StaticLifetime);
|
||||
this.tcx
|
||||
.sess
|
||||
.struct_span_warn(
|
||||
|
|
@ -964,7 +1011,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
self.record_late_bound_vars(*hir_id, binders);
|
||||
let scope = Scope::Binder {
|
||||
hir_id: *hir_id,
|
||||
lifetimes: FxIndexMap::default(),
|
||||
bound_vars: FxIndexMap::default(),
|
||||
s: self.scope,
|
||||
scope_type,
|
||||
where_bound_origin: None,
|
||||
|
|
@ -978,43 +1025,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn visit_poly_trait_ref(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) {
|
||||
debug!("visit_poly_trait_ref(trait_ref={:?})", trait_ref);
|
||||
|
||||
let (mut binders, scope_type) = self.poly_trait_ref_binder_info();
|
||||
|
||||
let initial_bound_vars = binders.len() as u32;
|
||||
let mut lifetimes: FxIndexMap<LocalDefId, Region> = FxIndexMap::default();
|
||||
let binders_iter = trait_ref
|
||||
.bound_generic_params
|
||||
.iter()
|
||||
.filter(|param| matches!(param.kind, GenericParamKind::Lifetime { .. }))
|
||||
.enumerate()
|
||||
.map(|(late_bound_idx, param)| {
|
||||
let pair = Region::late(initial_bound_vars + late_bound_idx as u32, param);
|
||||
let r = late_region_as_bound_region(self.tcx, &pair.1);
|
||||
lifetimes.insert(pair.0, pair.1);
|
||||
r
|
||||
});
|
||||
binders.extend(binders_iter);
|
||||
|
||||
debug!(?binders);
|
||||
self.record_late_bound_vars(trait_ref.trait_ref.hir_ref_id, binders);
|
||||
|
||||
// Always introduce a scope here, even if this is in a where clause and
|
||||
// we introduced the binders around the bounded Ty. In that case, we
|
||||
// just reuse the concatenation functionality also present in nested trait
|
||||
// refs.
|
||||
let scope = Scope::Binder {
|
||||
hir_id: trait_ref.trait_ref.hir_ref_id,
|
||||
lifetimes,
|
||||
s: self.scope,
|
||||
scope_type,
|
||||
where_bound_origin: None,
|
||||
};
|
||||
self.with(scope, |this| {
|
||||
walk_list!(this, visit_generic_param, trait_ref.bound_generic_params);
|
||||
this.visit_trait_ref(&trait_ref.trait_ref);
|
||||
});
|
||||
self.visit_poly_trait_ref_inner(trait_ref, NonLifetimeBinderAllowed::Allow);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1063,13 +1074,13 @@ fn object_lifetime_default(tcx: TyCtxt<'_>, param_def_id: DefId) -> ObjectLifeti
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
||||
fn with<F>(&mut self, wrap_scope: Scope<'_>, f: F)
|
||||
where
|
||||
F: for<'b> FnOnce(&mut LifetimeContext<'b, 'tcx>),
|
||||
F: for<'b> FnOnce(&mut BoundVarContext<'b, 'tcx>),
|
||||
{
|
||||
let LifetimeContext { tcx, map, .. } = self;
|
||||
let mut this = LifetimeContext { tcx: *tcx, map, scope: &wrap_scope };
|
||||
let BoundVarContext { tcx, map, .. } = self;
|
||||
let mut this = BoundVarContext { tcx: *tcx, map, scope: &wrap_scope };
|
||||
let span = debug_span!("scope", scope = ?TruncatedScopeDebug(&this.scope));
|
||||
{
|
||||
let _enter = span.enter();
|
||||
|
|
@ -1110,23 +1121,25 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
generics: &'tcx hir::Generics<'tcx>,
|
||||
walk: F,
|
||||
) where
|
||||
F: for<'b, 'c> FnOnce(&'b mut LifetimeContext<'c, 'tcx>),
|
||||
F: for<'b, 'c> FnOnce(&'b mut BoundVarContext<'c, 'tcx>),
|
||||
{
|
||||
let mut named_late_bound_vars = 0;
|
||||
let lifetimes: FxIndexMap<LocalDefId, Region> = generics
|
||||
let bound_vars: FxIndexMap<LocalDefId, ResolvedArg> = generics
|
||||
.params
|
||||
.iter()
|
||||
.filter_map(|param| match param.kind {
|
||||
.map(|param| match param.kind {
|
||||
GenericParamKind::Lifetime { .. } => {
|
||||
if self.tcx.is_late_bound(param.hir_id) {
|
||||
let late_bound_idx = named_late_bound_vars;
|
||||
named_late_bound_vars += 1;
|
||||
Some(Region::late(late_bound_idx, param))
|
||||
ResolvedArg::late(late_bound_idx, param)
|
||||
} else {
|
||||
Some(Region::early(param))
|
||||
ResolvedArg::early(param)
|
||||
}
|
||||
}
|
||||
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None,
|
||||
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
|
||||
ResolvedArg::early(param)
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
|
@ -1139,14 +1152,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
})
|
||||
.enumerate()
|
||||
.map(|(late_bound_idx, param)| {
|
||||
let pair = Region::late(late_bound_idx as u32, param);
|
||||
late_region_as_bound_region(self.tcx, &pair.1)
|
||||
let pair = ResolvedArg::late(late_bound_idx as u32, param);
|
||||
late_arg_as_bound_arg(self.tcx, &pair.1, param)
|
||||
})
|
||||
.collect();
|
||||
self.record_late_bound_vars(hir_id, binders);
|
||||
let scope = Scope::Binder {
|
||||
hir_id,
|
||||
lifetimes,
|
||||
bound_vars,
|
||||
s: self.scope,
|
||||
scope_type: BinderScopeType::Normal,
|
||||
where_bound_origin: None,
|
||||
|
|
@ -1177,15 +1190,15 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
Scope::Root { opt_parent_item } => {
|
||||
if let Some(parent_item) = opt_parent_item
|
||||
&& let parent_generics = self.tcx.generics_of(parent_item)
|
||||
&& parent_generics.param_def_id_to_index.contains_key(®ion_def_id.to_def_id())
|
||||
&& parent_generics.param_def_id_to_index(self.tcx, region_def_id.to_def_id()).is_some()
|
||||
{
|
||||
break Some(Region::EarlyBound(region_def_id.to_def_id()));
|
||||
break Some(ResolvedArg::EarlyBound(region_def_id.to_def_id()));
|
||||
}
|
||||
break None;
|
||||
}
|
||||
|
||||
Scope::Binder { ref lifetimes, scope_type, s, where_bound_origin, .. } => {
|
||||
if let Some(&def) = lifetimes.get(®ion_def_id) {
|
||||
Scope::Binder { ref bound_vars, scope_type, s, where_bound_origin, .. } => {
|
||||
if let Some(&def) = bound_vars.get(®ion_def_id) {
|
||||
break Some(def.shifted(late_depth));
|
||||
}
|
||||
match scope_type {
|
||||
|
|
@ -1259,7 +1272,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
};
|
||||
|
||||
if let Some(mut def) = result {
|
||||
if let Region::EarlyBound(..) = def {
|
||||
if let ResolvedArg::EarlyBound(..) = def {
|
||||
// Do not free early-bound regions, only late-bound ones.
|
||||
} else if let Some(body_id) = outermost_body {
|
||||
let fn_id = self.tcx.hir().body_owner(body_id);
|
||||
|
|
@ -1275,10 +1288,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
kind: hir::ImplItemKind::Fn(..),
|
||||
..
|
||||
}) => {
|
||||
def = Region::Free(owner_id.to_def_id(), def.id().unwrap());
|
||||
def = ResolvedArg::Free(owner_id.to_def_id(), def.id().unwrap());
|
||||
}
|
||||
Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(closure), .. }) => {
|
||||
def = Region::Free(closure.def_id.to_def_id(), def.id().unwrap());
|
||||
def = ResolvedArg::Free(closure.def_id.to_def_id(), def.id().unwrap());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
@ -1329,6 +1342,59 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
);
|
||||
}
|
||||
|
||||
fn resolve_type_ref(&mut self, param_def_id: LocalDefId, hir_id: hir::HirId) {
|
||||
// Walk up the scope chain, tracking the number of fn scopes
|
||||
// that we pass through, until we find a lifetime with the
|
||||
// given name or we run out of scopes.
|
||||
// search.
|
||||
let mut late_depth = 0;
|
||||
let mut scope = self.scope;
|
||||
let result = loop {
|
||||
match *scope {
|
||||
Scope::Body { s, .. } => {
|
||||
scope = s;
|
||||
}
|
||||
|
||||
Scope::Root { opt_parent_item } => {
|
||||
if let Some(parent_item) = opt_parent_item
|
||||
&& let parent_generics = self.tcx.generics_of(parent_item)
|
||||
&& parent_generics.param_def_id_to_index(self.tcx, param_def_id.to_def_id()).is_some()
|
||||
{
|
||||
break Some(ResolvedArg::EarlyBound(param_def_id.to_def_id()));
|
||||
}
|
||||
break None;
|
||||
}
|
||||
|
||||
Scope::Binder { ref bound_vars, scope_type, s, .. } => {
|
||||
if let Some(&def) = bound_vars.get(¶m_def_id) {
|
||||
break Some(def.shifted(late_depth));
|
||||
}
|
||||
match scope_type {
|
||||
BinderScopeType::Normal => late_depth += 1,
|
||||
BinderScopeType::Concatenating => {}
|
||||
}
|
||||
scope = s;
|
||||
}
|
||||
|
||||
Scope::Elision { s, .. }
|
||||
| Scope::ObjectLifetimeDefault { s, .. }
|
||||
| Scope::Supertrait { s, .. }
|
||||
| Scope::TraitRefBoundary { s, .. } => {
|
||||
scope = s;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(def) = result {
|
||||
self.map.defs.insert(hir_id, def);
|
||||
return;
|
||||
}
|
||||
|
||||
self.tcx
|
||||
.sess
|
||||
.delay_span_bug(self.tcx.hir().span(hir_id), "could not resolve {param_def_id:?}");
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn visit_segment_args(
|
||||
&mut self,
|
||||
|
|
@ -1415,10 +1481,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
if in_body {
|
||||
None
|
||||
} else {
|
||||
Some(Region::Static)
|
||||
Some(ResolvedArg::StaticLifetime)
|
||||
}
|
||||
}
|
||||
ObjectLifetimeDefault::Static => Some(Region::Static),
|
||||
ObjectLifetimeDefault::Static => Some(ResolvedArg::StaticLifetime),
|
||||
ObjectLifetimeDefault::Param(param_def_id) => {
|
||||
// This index can be used with `generic_args` since `parent_count == 0`.
|
||||
let index = generics.param_def_id_to_index[¶m_def_id] as usize;
|
||||
|
|
@ -1507,18 +1573,19 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
// in the trait ref `YY<...>` in `Item: YY<...>`.
|
||||
for binding in generic_args.bindings {
|
||||
let scope = Scope::ObjectLifetimeDefault {
|
||||
lifetime: if has_lifetime_parameter { None } else { Some(Region::Static) },
|
||||
lifetime: if has_lifetime_parameter {
|
||||
None
|
||||
} else {
|
||||
Some(ResolvedArg::StaticLifetime)
|
||||
},
|
||||
s: self.scope,
|
||||
};
|
||||
if let Some(type_def_id) = type_def_id {
|
||||
let lifetimes = LifetimeContext::supertrait_hrtb_lifetimes(
|
||||
self.tcx,
|
||||
type_def_id,
|
||||
binding.ident,
|
||||
);
|
||||
let bound_vars =
|
||||
BoundVarContext::supertrait_hrtb_vars(self.tcx, type_def_id, binding.ident);
|
||||
self.with(scope, |this| {
|
||||
let scope = Scope::Supertrait {
|
||||
lifetimes: lifetimes.unwrap_or_default(),
|
||||
bound_vars: bound_vars.unwrap_or_default(),
|
||||
s: this.scope,
|
||||
};
|
||||
this.with(scope, |this| this.visit_assoc_type_binding(binding));
|
||||
|
|
@ -1541,7 +1608,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
/// ```
|
||||
/// In this case, if we wanted to the supertrait HRTB lifetimes for `As` on
|
||||
/// the starting trait `Bar`, we would return `Some(['b, 'a])`.
|
||||
fn supertrait_hrtb_lifetimes(
|
||||
fn supertrait_hrtb_vars(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: DefId,
|
||||
assoc_name: Ident,
|
||||
|
|
@ -1626,7 +1693,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
scope = s;
|
||||
}
|
||||
|
||||
Scope::Root { .. } | Scope::Elision { .. } => break Region::Static,
|
||||
Scope::Root { .. } | Scope::Elision { .. } => break ResolvedArg::StaticLifetime,
|
||||
|
||||
Scope::Body { .. } | Scope::ObjectLifetimeDefault { lifetime: None, .. } => return,
|
||||
|
||||
|
|
@ -1641,7 +1708,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: Region) {
|
||||
fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: ResolvedArg) {
|
||||
debug!(span = ?lifetime_ref.ident.span);
|
||||
self.map.defs.insert(lifetime_ref.hir_id, def);
|
||||
}
|
||||
|
|
@ -1649,7 +1716,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
/// Sometimes we resolve a lifetime, but later find that it is an
|
||||
/// error (esp. around impl trait). In that case, we remove the
|
||||
/// entry into `map.defs` so as not to confuse later code.
|
||||
fn uninsert_lifetime_on_error(&mut self, lifetime_ref: &'tcx hir::Lifetime, bad_def: Region) {
|
||||
fn uninsert_lifetime_on_error(
|
||||
&mut self,
|
||||
lifetime_ref: &'tcx hir::Lifetime,
|
||||
bad_def: ResolvedArg,
|
||||
) {
|
||||
let old_value = self.map.defs.remove(&lifetime_ref.hir_id);
|
||||
assert_eq!(old_value, Some(bad_def));
|
||||
}
|
||||
|
|
@ -1804,7 +1875,7 @@ fn is_late_bound_map(
|
|||
let mut walker = ConstrainedCollectorPostAstConv {
|
||||
arg_is_constrained: vec![false; generics.params.len()].into_boxed_slice(),
|
||||
};
|
||||
walker.visit_ty(self.tcx.type_of(alias_def));
|
||||
walker.visit_ty(self.tcx.type_of(alias_def).subst_identity());
|
||||
|
||||
match segments.last() {
|
||||
Some(hir::PathSegment { args: Some(args), .. }) => {
|
||||
|
|
@ -1872,3 +1943,37 @@ fn is_late_bound_map(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deny_non_region_late_bound(
|
||||
tcx: TyCtxt<'_>,
|
||||
bound_vars: &mut FxIndexMap<LocalDefId, ResolvedArg>,
|
||||
where_: &str,
|
||||
) {
|
||||
let mut first = true;
|
||||
|
||||
for (var, arg) in bound_vars {
|
||||
let Node::GenericParam(param) = tcx.hir().get_by_def_id(*var) else {
|
||||
bug!();
|
||||
};
|
||||
|
||||
let what = match param.kind {
|
||||
hir::GenericParamKind::Type { .. } => "type",
|
||||
hir::GenericParamKind::Const { .. } => "const",
|
||||
hir::GenericParamKind::Lifetime { .. } => continue,
|
||||
};
|
||||
|
||||
let mut diag = tcx.sess.struct_span_err(
|
||||
param.span,
|
||||
format!("late-bound {what} parameter not allowed on {where_}"),
|
||||
);
|
||||
|
||||
let guar = if tcx.features().non_lifetime_binders && first {
|
||||
diag.emit()
|
||||
} else {
|
||||
diag.delay_as_bug()
|
||||
};
|
||||
|
||||
first = false;
|
||||
*arg = ResolvedArg::Error(guar);
|
||||
}
|
||||
}
|
||||
|
|
@ -243,7 +243,7 @@ fn get_path_containing_arg_in_pat<'hir>(
|
|||
arg_path
|
||||
}
|
||||
|
||||
pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>> {
|
||||
let def_id = def_id.expect_local();
|
||||
use rustc_hir::*;
|
||||
|
||||
|
|
@ -251,7 +251,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||
|
||||
let icx = ItemCtxt::new(tcx, def_id.to_def_id());
|
||||
|
||||
match tcx.hir().get(hir_id) {
|
||||
let output = match tcx.hir().get(hir_id) {
|
||||
Node::TraitItem(item) => match item.kind {
|
||||
TraitItemKind::Fn(..) => {
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
|
||||
|
|
@ -259,13 +259,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||
}
|
||||
TraitItemKind::Const(ty, body_id) => body_id
|
||||
.and_then(|body_id| {
|
||||
if is_suggestable_infer_ty(ty) {
|
||||
Some(infer_placeholder_type(
|
||||
tcx, def_id, body_id, ty.span, item.ident, "constant",
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
is_suggestable_infer_ty(ty)
|
||||
.then(|| infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident, "constant",))
|
||||
})
|
||||
.unwrap_or_else(|| icx.to_ty(ty)),
|
||||
TraitItemKind::Type(_, Some(ty)) => icx.to_ty(ty),
|
||||
|
|
@ -382,7 +377,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||
|
||||
Node::Ctor(def) | Node::Variant(Variant { data: def, .. }) => match def {
|
||||
VariantData::Unit(..) | VariantData::Struct(..) => {
|
||||
tcx.type_of(tcx.hir().get_parent_item(hir_id))
|
||||
tcx.type_of(tcx.hir().get_parent_item(hir_id)).subst_identity()
|
||||
}
|
||||
VariantData::Tuple(..) => {
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
|
||||
|
|
@ -399,7 +394,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||
Node::AnonConst(_) if let Some(param) = tcx.opt_const_param_of(def_id) => {
|
||||
// We defer to `type_of` of the corresponding parameter
|
||||
// for generic arguments.
|
||||
tcx.type_of(param)
|
||||
tcx.type_of(param).subst_identity()
|
||||
}
|
||||
|
||||
Node::AnonConst(_) => {
|
||||
|
|
@ -451,7 +446,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||
&& e.hir_id == hir_id =>
|
||||
{
|
||||
let Some(trait_def_id) = trait_ref.trait_def_id() else {
|
||||
return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait");
|
||||
return ty::EarlyBinder(tcx.ty_error_with_message(DUMMY_SP, "Could not find trait"));
|
||||
};
|
||||
let assoc_items = tcx.associated_items(trait_def_id);
|
||||
let assoc_item = assoc_items.find_by_name_and_kind(
|
||||
|
|
@ -461,7 +456,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||
def_id.to_def_id(),
|
||||
);
|
||||
if let Some(assoc_item) = assoc_item {
|
||||
tcx.type_of(assoc_item.def_id)
|
||||
tcx.type_of(assoc_item.def_id).subst_identity()
|
||||
} else {
|
||||
// FIXME(associated_const_equality): add a useful error message here.
|
||||
tcx.ty_error_with_message(
|
||||
|
|
@ -485,7 +480,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||
}) =>
|
||||
{
|
||||
let Some(trait_def_id) = trait_ref.trait_def_id() else {
|
||||
return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait");
|
||||
return ty::EarlyBinder(tcx.ty_error_with_message(DUMMY_SP, "Could not find trait"));
|
||||
};
|
||||
let assoc_items = tcx.associated_items(trait_def_id);
|
||||
let assoc_item = assoc_items.find_by_name_and_kind(
|
||||
|
|
@ -506,7 +501,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||
if let Some(param)
|
||||
= assoc_item.map(|item| &tcx.generics_of(item.def_id).params[idx]).filter(|param| param.kind.is_ty_or_const())
|
||||
{
|
||||
tcx.type_of(param.def_id)
|
||||
tcx.type_of(param.def_id).subst_identity()
|
||||
} else {
|
||||
// FIXME(associated_const_equality): add a useful error message here.
|
||||
tcx.ty_error_with_message(
|
||||
|
|
@ -520,7 +515,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||
def_id: param_def_id,
|
||||
kind: GenericParamKind::Const { default: Some(ct), .. },
|
||||
..
|
||||
}) if ct.hir_id == hir_id => tcx.type_of(param_def_id),
|
||||
}) if ct.hir_id == hir_id => tcx.type_of(param_def_id).subst_identity(),
|
||||
|
||||
x => tcx.ty_error_with_message(
|
||||
DUMMY_SP,
|
||||
|
|
@ -538,7 +533,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||
x => {
|
||||
bug!("unexpected sort of node in type_of(): {:?}", x);
|
||||
}
|
||||
}
|
||||
};
|
||||
ty::EarlyBinder(output)
|
||||
}
|
||||
|
||||
#[instrument(skip(tcx), level = "debug")]
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ pub fn provide(providers: &mut Providers) {
|
|||
|
||||
fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) {
|
||||
// Every lifetime used in an associated type must be constrained.
|
||||
let impl_self_ty = tcx.type_of(impl_def_id);
|
||||
let impl_self_ty = tcx.type_of(impl_def_id).subst_identity();
|
||||
if impl_self_ty.references_error() {
|
||||
// Don't complain about unconstrained type params when self ty isn't known due to errors.
|
||||
// (#36836)
|
||||
|
|
@ -104,7 +104,7 @@ fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId)
|
|||
match item.kind {
|
||||
ty::AssocKind::Type => {
|
||||
if item.defaultness(tcx).has_value() {
|
||||
cgp::parameters_for(&tcx.type_of(def_id), true)
|
||||
cgp::parameters_for(&tcx.type_of(def_id).subst_identity(), true)
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -496,6 +496,16 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
|
|||
)
|
||||
.emit();
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => {
|
||||
// FIXME(min_specialization), FIXME(const_generics):
|
||||
// It probably isn't right to allow _every_ `ConstArgHasType` but I am somewhat unsure
|
||||
// about the actual rules that would be sound. Can't just always error here because otherwise
|
||||
// std/core doesn't even compile as they have `const N: usize` in some specializing impls.
|
||||
//
|
||||
// While we do not support constructs like `<T, const N: T>` there is probably no risk of
|
||||
// soundness bugs, but when we support generic const parameter types this will need to be
|
||||
// revisited.
|
||||
}
|
||||
_ => {
|
||||
tcx.sess
|
||||
.struct_span_err(span, &format!("cannot specialize on predicate `{}`", predicate))
|
||||
|
|
@ -517,6 +527,7 @@ fn trait_predicate_kind<'tcx>(
|
|||
ty::PredicateKind::Clause(ty::Clause::RegionOutlives(_))
|
||||
| ty::PredicateKind::Clause(ty::Clause::TypeOutlives(_))
|
||||
| ty::PredicateKind::Clause(ty::Clause::Projection(_))
|
||||
| ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
|
||||
| ty::PredicateKind::AliasEq(..)
|
||||
| ty::PredicateKind::WellFormed(_)
|
||||
| ty::PredicateKind::Subtype(_)
|
||||
|
|
|
|||
|
|
@ -113,7 +113,6 @@ use rustc_target::spec::abi::Abi;
|
|||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode};
|
||||
|
||||
use std::iter;
|
||||
use std::ops::Not;
|
||||
|
||||
use astconv::AstConv;
|
||||
|
|
@ -187,7 +186,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
|||
|
||||
fn main_fn_diagnostics_def_id(tcx: TyCtxt<'_>, def_id: DefId, sp: Span) -> LocalDefId {
|
||||
if let Some(local_def_id) = def_id.as_local() {
|
||||
let hir_type = tcx.type_of(local_def_id);
|
||||
let hir_type = tcx.type_of(local_def_id).subst_identity();
|
||||
if !matches!(hir_type.kind(), ty::FnDef(..)) {
|
||||
span_bug!(sp, "main has a non-function type: found `{}`", hir_type);
|
||||
}
|
||||
|
|
@ -204,7 +203,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
|||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
|
||||
match tcx.hir().find(hir_id) {
|
||||
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => {
|
||||
generics.params.is_empty().not().then(|| generics.span)
|
||||
generics.params.is_empty().not().then_some(generics.span)
|
||||
}
|
||||
_ => {
|
||||
span_bug!(tcx.def_span(def_id), "main has a non-function type");
|
||||
|
|
@ -348,7 +347,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
|||
}
|
||||
|
||||
let se_ty = tcx.mk_fn_ptr(expected_return_type.map_bound(|expected_return_type| {
|
||||
tcx.mk_fn_sig(iter::empty(), expected_return_type, false, hir::Unsafety::Normal, Abi::Rust)
|
||||
tcx.mk_fn_sig([], expected_return_type, false, hir::Unsafety::Normal, Abi::Rust)
|
||||
}));
|
||||
|
||||
require_same_types(
|
||||
|
|
@ -366,7 +365,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
|
|||
let start_def_id = start_def_id.expect_local();
|
||||
let start_id = tcx.hir().local_def_id_to_hir_id(start_def_id);
|
||||
let start_span = tcx.def_span(start_def_id);
|
||||
let start_t = tcx.type_of(start_def_id);
|
||||
let start_t = tcx.type_of(start_def_id).subst_identity();
|
||||
match start_t.kind() {
|
||||
ty::FnDef(..) => {
|
||||
if let Some(Node::Item(it)) = tcx.hir().find(start_id) {
|
||||
|
|
@ -434,7 +433,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
|
|||
}
|
||||
|
||||
let se_ty = tcx.mk_fn_ptr(ty::Binder::dummy(tcx.mk_fn_sig(
|
||||
[tcx.types.isize, tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8))].iter().cloned(),
|
||||
[tcx.types.isize, tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8))],
|
||||
tcx.types.isize,
|
||||
false,
|
||||
hir::Unsafety::Normal,
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
|
|||
|
||||
ty::PredicateKind::Clause(ty::Clause::Trait(..))
|
||||
| ty::PredicateKind::Clause(ty::Clause::Projection(..))
|
||||
| ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
|
||||
| ty::PredicateKind::WellFormed(..)
|
||||
| ty::PredicateKind::AliasEq(..)
|
||||
| ty::PredicateKind::ObjectSafe(..)
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ pub(super) fn infer_predicates(
|
|||
// For field of type &'a T (reference) or Adt
|
||||
// (struct/enum/union) there will be outlive
|
||||
// requirements for adt_def.
|
||||
let field_ty = tcx.type_of(field_def.did);
|
||||
let field_ty = tcx.type_of(field_def.did).subst_identity();
|
||||
let field_span = tcx.def_span(field_def.did);
|
||||
insert_required_predicates_to_be_wf(
|
||||
tcx,
|
||||
|
|
|
|||
|
|
@ -423,7 +423,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||
|
||||
fn get_unbound_associated_types(&self) -> Vec<String> {
|
||||
if self.tcx.is_trait(self.def_id) {
|
||||
let items: &AssocItems<'_> = self.tcx.associated_items(self.def_id);
|
||||
let items: &AssocItems = self.tcx.associated_items(self.def_id);
|
||||
items
|
||||
.in_definition_order()
|
||||
.filter(|item| item.kind == AssocKind::Type)
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
|
||||
let inferred_start = self.terms_cx.inferred_starts[&def_id];
|
||||
let current_item = &CurrentItem { inferred_start };
|
||||
match tcx.type_of(def_id).kind() {
|
||||
match tcx.type_of(def_id).subst_identity().kind() {
|
||||
ty::Adt(def, _) => {
|
||||
// Not entirely obvious: constraints on structs/enums do not
|
||||
// affect the variance of their type parameters. See discussion
|
||||
|
|
@ -112,7 +112,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
for field in def.all_fields() {
|
||||
self.add_constraints_from_ty(
|
||||
current_item,
|
||||
tcx.type_of(field.did),
|
||||
tcx.type_of(field.did).subst_identity(),
|
||||
self.covariant,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
|
|||
self.enforce_const_invariance(generics, variances);
|
||||
|
||||
// Functions are permitted to have unused generic parameters: make those invariant.
|
||||
if let ty::FnDef(..) = tcx.type_of(def_id).kind() {
|
||||
if let ty::FnDef(..) = tcx.type_of(def_id).subst_identity().kind() {
|
||||
for variance in variances.iter_mut() {
|
||||
if *variance == ty::Bivariant {
|
||||
*variance = ty::Invariant;
|
||||
|
|
|
|||
|
|
@ -74,15 +74,13 @@ pub(super) fn check_fn<'a, 'tcx>(
|
|||
|
||||
// C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
|
||||
// (as it's created inside the body itself, not passed in from outside).
|
||||
let maybe_va_list = if fn_sig.c_variadic {
|
||||
let maybe_va_list = fn_sig.c_variadic.then(|| {
|
||||
let span = body.params.last().unwrap().span;
|
||||
let va_list_did = tcx.require_lang_item(LangItem::VaList, Some(span));
|
||||
let region = fcx.next_region_var(RegionVariableOrigin::MiscVariable(span));
|
||||
|
||||
Some(tcx.bound_type_of(va_list_did).subst(tcx, &[region.into()]))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
tcx.type_of(va_list_did).subst(tcx, &[region.into()])
|
||||
});
|
||||
|
||||
// Add formal parameters.
|
||||
let inputs_hir = hir.fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs);
|
||||
|
|
@ -266,7 +264,7 @@ fn check_lang_start_fn<'tcx>(
|
|||
let fn_generic = generics.param_at(0, tcx);
|
||||
let generic_ty = tcx.mk_ty_param(fn_generic.index, fn_generic.name);
|
||||
let expected_fn_sig =
|
||||
tcx.mk_fn_sig([].iter(), &generic_ty, false, hir::Unsafety::Normal, Abi::Rust);
|
||||
tcx.mk_fn_sig([], generic_ty, false, hir::Unsafety::Normal, Abi::Rust);
|
||||
let expected_ty = tcx.mk_fn_ptr(Binder::dummy(expected_fn_sig));
|
||||
|
||||
// we emit the same error to suggest changing the arg no matter what's wrong with the arg
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// the `closures` table.
|
||||
let sig = bound_sig.map_bound(|sig| {
|
||||
self.tcx.mk_fn_sig(
|
||||
iter::once(self.tcx.intern_tup(sig.inputs())),
|
||||
[self.tcx.intern_tup(sig.inputs())],
|
||||
sig.output(),
|
||||
sig.c_variadic,
|
||||
sig.unsafety,
|
||||
|
|
@ -326,7 +326,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
debug!(?ret_param_ty);
|
||||
|
||||
let sig = projection.rebind(self.tcx.mk_fn_sig(
|
||||
input_tys.iter(),
|
||||
input_tys,
|
||||
ret_param_ty,
|
||||
false,
|
||||
hir::Unsafety::Normal,
|
||||
|
|
|
|||
|
|
@ -1046,7 +1046,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
self.param_env,
|
||||
)
|
||||
.may_apply()
|
||||
.then(|| deref_ty)
|
||||
.then_some(deref_ty)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1269,10 +1269,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// ```
|
||||
let ref_ty = match mutability {
|
||||
hir::Mutability::Mut => {
|
||||
self.tcx.mk_mut_ref(self.tcx.mk_region(ty::ReStatic), checked_ty)
|
||||
self.tcx.mk_mut_ref(self.tcx.lifetimes.re_static, checked_ty)
|
||||
}
|
||||
hir::Mutability::Not => {
|
||||
self.tcx.mk_imm_ref(self.tcx.mk_region(ty::ReStatic), checked_ty)
|
||||
self.tcx.mk_imm_ref(self.tcx.lifetimes.re_static, checked_ty)
|
||||
}
|
||||
};
|
||||
if self.can_coerce(ref_ty, expected) {
|
||||
|
|
@ -2037,7 +2037,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
args: &[hir::Expr<'_>],
|
||||
kind: CallableKind| {
|
||||
let arg_idx = args.iter().position(|a| a.hir_id == expr.hir_id).unwrap();
|
||||
let fn_ty = self.tcx.bound_type_of(def_id).0;
|
||||
let fn_ty = self.tcx.type_of(def_id).skip_binder();
|
||||
if !fn_ty.is_fn() {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -663,6 +663,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
|
||||
ty::PredicateKind::Clause(ty::Clause::Trait(..))
|
||||
| ty::PredicateKind::Clause(ty::Clause::Projection(..))
|
||||
| ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
|
||||
| ty::PredicateKind::Subtype(..)
|
||||
| ty::PredicateKind::Coerce(..)
|
||||
| ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..))
|
||||
|
|
@ -776,9 +777,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let def_kind = self.tcx.def_kind(def_id);
|
||||
|
||||
let item_ty = if let DefKind::Variant = def_kind {
|
||||
self.tcx.bound_type_of(self.tcx.parent(def_id))
|
||||
self.tcx.type_of(self.tcx.parent(def_id))
|
||||
} else {
|
||||
self.tcx.bound_type_of(def_id)
|
||||
self.tcx.type_of(def_id)
|
||||
};
|
||||
let substs = self.fresh_substs_for_item(span, def_id);
|
||||
let ty = item_ty.subst(self.tcx, substs);
|
||||
|
|
@ -1130,7 +1131,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
.unwrap_or(false);
|
||||
|
||||
let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
|
||||
let ty = self.handle_raw_ty(span, tcx.at(span).type_of(impl_def_id));
|
||||
let ty = self.handle_raw_ty(span, tcx.at(span).type_of(impl_def_id).subst_identity());
|
||||
match ty.normalized.ty_adt_def() {
|
||||
Some(adt_def) if adt_def.has_ctor() => {
|
||||
let (ctor_kind, ctor_def_id) = adt_def.non_enum_variant().ctor.unwrap();
|
||||
|
|
@ -1226,7 +1227,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
(GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
|
||||
let tcx = self.fcx.tcx();
|
||||
self.fcx.ct_infer(tcx.type_of(param.def_id), Some(param), inf.span).into()
|
||||
self.fcx
|
||||
.ct_infer(
|
||||
tcx.type_of(param.def_id)
|
||||
.no_bound_vars()
|
||||
.expect("const parameter types cannot be generic"),
|
||||
Some(param),
|
||||
inf.span,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
|
@ -1248,7 +1257,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// If we have a default, then we it doesn't matter that we're not
|
||||
// inferring the type arguments: we provide the default where any
|
||||
// is missing.
|
||||
tcx.bound_type_of(param.def_id).subst(tcx, substs.unwrap()).into()
|
||||
tcx.type_of(param.def_id).subst(tcx, substs.unwrap()).into()
|
||||
} else {
|
||||
// If no type arguments were provided, we have to infer them.
|
||||
// This case also occurs as a result of some malformed input, e.g.
|
||||
|
|
@ -1296,7 +1305,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
|
||||
// Substitute the values for the type parameters into the type of
|
||||
// the referenced item.
|
||||
let ty = tcx.bound_type_of(def_id);
|
||||
let ty = tcx.type_of(def_id);
|
||||
assert!(!substs.has_escaping_bound_vars());
|
||||
assert!(!ty.0.has_escaping_bound_vars());
|
||||
let ty_substituted = self.normalize(span, ty.subst(tcx, substs));
|
||||
|
|
@ -1307,7 +1316,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// type parameters, which we can infer by unifying the provided `Self`
|
||||
// with the substituted impl type.
|
||||
// This also occurs for an enum variant on a type alias.
|
||||
let impl_ty = self.normalize(span, tcx.bound_type_of(impl_def_id).subst(tcx, substs));
|
||||
let impl_ty = self.normalize(span, tcx.type_of(impl_def_id).subst(tcx, substs));
|
||||
let self_ty = self.normalize(span, self_ty);
|
||||
match self.at(&self.misc(span), self.param_env).eq(impl_ty, self_ty) {
|
||||
Ok(ok) => self.register_infer_ok_obligations(ok),
|
||||
|
|
|
|||
|
|
@ -312,7 +312,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// same rules that check_expr_struct uses for macro hygiene.
|
||||
if self.tcx.adjust_ident(expr_field.ident, variant_def_id) == field.ident(self.tcx)
|
||||
{
|
||||
return Some((expr_field.expr, self.tcx.type_of(field.did)));
|
||||
return Some((expr_field.expr, self.tcx.type_of(field.did).subst_identity()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -339,7 +339,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
receiver: Option<&'tcx hir::Expr<'tcx>>,
|
||||
args: &'tcx [hir::Expr<'tcx>],
|
||||
) -> bool {
|
||||
let ty = self.tcx.type_of(def_id);
|
||||
let ty = self.tcx.type_of(def_id).subst_identity();
|
||||
if !ty.is_fn() {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -477,19 +477,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// This is the "trait" (meaning, the predicate "proved" by this `impl`) which provides the `Self` type we care about.
|
||||
// For the purposes of this function, we hope that it is a `struct` type, and that our current `expr` is a literal of
|
||||
// that struct type.
|
||||
let impl_trait_self_ref: Option<ty::TraitRef<'tcx>> =
|
||||
self.tcx.impl_trait_ref(obligation.impl_def_id).map(|impl_def| impl_def.skip_binder());
|
||||
|
||||
let Some(impl_trait_self_ref) = impl_trait_self_ref else {
|
||||
// It is possible that this is absent. In this case, we make no progress.
|
||||
return Err(expr);
|
||||
let impl_trait_self_ref = if self.tcx.is_trait_alias(obligation.impl_or_alias_def_id) {
|
||||
self.tcx.mk_trait_ref(
|
||||
obligation.impl_or_alias_def_id,
|
||||
ty::InternalSubsts::identity_for_item(self.tcx, obligation.impl_or_alias_def_id),
|
||||
)
|
||||
} else {
|
||||
self.tcx
|
||||
.impl_trait_ref(obligation.impl_or_alias_def_id)
|
||||
.map(|impl_def| impl_def.skip_binder())
|
||||
// It is possible that this is absent. In this case, we make no progress.
|
||||
.ok_or(expr)?
|
||||
};
|
||||
|
||||
// We only really care about the `Self` type itself, which we extract from the ref.
|
||||
let impl_self_ty: Ty<'tcx> = impl_trait_self_ref.self_ty();
|
||||
|
||||
let impl_predicates: ty::GenericPredicates<'tcx> =
|
||||
self.tcx.predicates_of(obligation.impl_def_id);
|
||||
self.tcx.predicates_of(obligation.impl_or_alias_def_id);
|
||||
let Some(impl_predicate_index) = obligation.impl_def_predicate_index else {
|
||||
// We don't have the index, so we can only guess.
|
||||
return Err(expr);
|
||||
|
|
|
|||
|
|
@ -755,15 +755,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
errors.drain_filter(|error| {
|
||||
let Error::Invalid(provided_idx, expected_idx, Compatibility::Incompatible(Some(e))) = error else { return false };
|
||||
let (provided_ty, provided_span) = provided_arg_tys[*provided_idx];
|
||||
let trace = mk_trace(provided_span, formal_and_expected_inputs[*expected_idx], provided_ty);
|
||||
if !matches!(trace.cause.as_failure_code(*e), FailureCode::Error0308(_)) {
|
||||
self.err_ctxt().report_and_explain_type_error(trace, *e).emit();
|
||||
return true;
|
||||
}
|
||||
false
|
||||
});
|
||||
let Error::Invalid(
|
||||
provided_idx,
|
||||
expected_idx,
|
||||
Compatibility::Incompatible(Some(e)),
|
||||
) = error else { return false };
|
||||
let (provided_ty, provided_span) = provided_arg_tys[*provided_idx];
|
||||
let trace =
|
||||
mk_trace(provided_span, formal_and_expected_inputs[*expected_idx], provided_ty);
|
||||
if !matches!(trace.cause.as_failure_code(*e), FailureCode::Error0308(_)) {
|
||||
self.err_ctxt().report_and_explain_type_error(trace, *e).emit();
|
||||
return true;
|
||||
}
|
||||
false
|
||||
});
|
||||
|
||||
// We're done if we found errors, but we already emitted them.
|
||||
if errors.is_empty() {
|
||||
|
|
@ -864,7 +869,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
let mut suggestion_text = SuggestionText::None;
|
||||
|
||||
let ty_to_snippet = |ty: Ty<'tcx>, expected_idx: ExpectedIdx| {
|
||||
if ty.is_unit() {
|
||||
"()".to_string()
|
||||
} else if ty.is_suggestable(tcx, false) {
|
||||
format!("/* {} */", ty)
|
||||
} else if let Some(fn_def_id) = fn_def_id
|
||||
&& self.tcx.def_kind(fn_def_id).is_fn_like()
|
||||
&& let self_implicit =
|
||||
matches!(call_expr.kind, hir::ExprKind::MethodCall(..)) as usize
|
||||
&& let Some(arg) = self.tcx.fn_arg_names(fn_def_id)
|
||||
.get(expected_idx.as_usize() + self_implicit)
|
||||
&& arg.name != kw::SelfLower
|
||||
{
|
||||
format!("/* {} */", arg.name)
|
||||
} else {
|
||||
"/* value */".to_string()
|
||||
}
|
||||
};
|
||||
|
||||
let mut errors = errors.into_iter().peekable();
|
||||
let mut suggestions = vec![];
|
||||
while let Some(error) = errors.next() {
|
||||
match error {
|
||||
Error::Invalid(provided_idx, expected_idx, compatibility) => {
|
||||
|
|
@ -905,7 +930,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
"".to_string()
|
||||
};
|
||||
labels
|
||||
.push((provided_span, format!("argument{} unexpected", provided_ty_name)));
|
||||
.push((provided_span, format!("unexpected argument{}", provided_ty_name)));
|
||||
let mut span = provided_span;
|
||||
if arg_idx.index() > 0
|
||||
&& let Some((_, prev)) = provided_arg_tys
|
||||
.get(ProvidedIdx::from_usize(arg_idx.index() - 1)
|
||||
) {
|
||||
// Include previous comma
|
||||
span = span.with_lo(prev.hi());
|
||||
} else if let Some((_, next)) = provided_arg_tys.get(
|
||||
ProvidedIdx::from_usize(arg_idx.index() + 1),
|
||||
) {
|
||||
// Include next comma
|
||||
span = span.until(*next);
|
||||
}
|
||||
suggestions.push((span, String::new()));
|
||||
|
||||
suggestion_text = match suggestion_text {
|
||||
SuggestionText::None => SuggestionText::Remove(false),
|
||||
SuggestionText::Remove(_) => SuggestionText::Remove(true),
|
||||
|
|
@ -1095,6 +1135,45 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
// Incorporate the argument changes in the removal suggestion.
|
||||
// When a type is *missing*, and the rest are additional, we want to suggest these with a
|
||||
// multipart suggestion, but in order to do so we need to figure out *where* the arg that
|
||||
// was provided but had the wrong type should go, because when looking at `expected_idx`
|
||||
// that is the position in the argument list in the definition, while `provided_idx` will
|
||||
// not be present. So we have to look at what the *last* provided position was, and point
|
||||
// one after to suggest the replacement. FIXME(estebank): This is hacky, and there's
|
||||
// probably a better more involved change we can make to make this work.
|
||||
// For example, if we have
|
||||
// ```
|
||||
// fn foo(i32, &'static str) {}
|
||||
// foo((), (), ());
|
||||
// ```
|
||||
// what should be suggested is
|
||||
// ```
|
||||
// foo(/* i32 */, /* &str */);
|
||||
// ```
|
||||
// which includes the replacement of the first two `()` for the correct type, and the
|
||||
// removal of the last `()`.
|
||||
let mut prev = -1;
|
||||
for (expected_idx, provided_idx) in matched_inputs.iter_enumerated() {
|
||||
// We want to point not at the *current* argument expression index, but rather at the
|
||||
// index position where it *should have been*, which is *after* the previous one.
|
||||
if let Some(provided_idx) = provided_idx {
|
||||
prev = provided_idx.index() as i64;
|
||||
}
|
||||
let idx = ProvidedIdx::from_usize((prev + 1) as usize);
|
||||
if let None = provided_idx
|
||||
&& let Some((_, arg_span)) = provided_arg_tys.get(idx)
|
||||
{
|
||||
// There is a type that was *not* found anywhere, so it isn't a move, but a
|
||||
// replacement and we look at what type it should have been. This will allow us
|
||||
// To suggest a multipart suggestion when encountering `foo(1, "")` where the def
|
||||
// was `fn foo(())`.
|
||||
let (_, expected_ty) = formal_and_expected_inputs[expected_idx];
|
||||
suggestions.push((*arg_span, ty_to_snippet(expected_ty, expected_idx)));
|
||||
}
|
||||
}
|
||||
|
||||
// If we have less than 5 things to say, it would be useful to call out exactly what's wrong
|
||||
if labels.len() <= 5 {
|
||||
for (span, label) in labels {
|
||||
|
|
@ -1112,7 +1191,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
Some(format!("provide the argument{}", if plural { "s" } else { "" }))
|
||||
}
|
||||
SuggestionText::Remove(plural) => {
|
||||
Some(format!("remove the extra argument{}", if plural { "s" } else { "" }))
|
||||
err.multipart_suggestion(
|
||||
&format!("remove the extra argument{}", if plural { "s" } else { "" }),
|
||||
suggestions,
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
None
|
||||
}
|
||||
SuggestionText::Swap => Some("swap these arguments".to_string()),
|
||||
SuggestionText::Reorder => Some("reorder these arguments".to_string()),
|
||||
|
|
@ -1151,20 +1235,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
} else {
|
||||
// Propose a placeholder of the correct type
|
||||
let (_, expected_ty) = formal_and_expected_inputs[expected_idx];
|
||||
if expected_ty.is_unit() {
|
||||
"()".to_string()
|
||||
} else if expected_ty.is_suggestable(tcx, false) {
|
||||
format!("/* {} */", expected_ty)
|
||||
} else if let Some(fn_def_id) = fn_def_id
|
||||
&& self.tcx.def_kind(fn_def_id).is_fn_like()
|
||||
&& let self_implicit = matches!(call_expr.kind, hir::ExprKind::MethodCall(..)) as usize
|
||||
&& let Some(arg) = self.tcx.fn_arg_names(fn_def_id).get(expected_idx.as_usize() + self_implicit)
|
||||
&& arg.name != kw::SelfLower
|
||||
{
|
||||
format!("/* {} */", arg.name)
|
||||
} else {
|
||||
"/* value */".to_string()
|
||||
}
|
||||
ty_to_snippet(expected_ty, expected_idx)
|
||||
};
|
||||
suggestion += &suggestion_text;
|
||||
}
|
||||
|
|
@ -1669,7 +1740,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
match *qpath {
|
||||
QPath::Resolved(ref maybe_qself, ref path) => {
|
||||
let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself).raw);
|
||||
let ty = self.astconv().res_to_ty(self_ty, path, true);
|
||||
let ty = self.astconv().res_to_ty(self_ty, path, hir_id, true);
|
||||
(path.res, self.handle_raw_ty(path_span, ty))
|
||||
}
|
||||
QPath::TypeRelative(ref qself, ref segment) => {
|
||||
|
|
|
|||
|
|
@ -1378,7 +1378,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// Same item
|
||||
return false;
|
||||
}
|
||||
let item_ty = self.tcx.type_of(item.def_id);
|
||||
let item_ty = self.tcx.type_of(item.def_id).subst_identity();
|
||||
// FIXME(compiler-errors): This check is *so* rudimentary
|
||||
if item_ty.needs_subst() {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -271,15 +271,13 @@ pub fn resolve_interior<'a, 'tcx>(
|
|||
},
|
||||
_ => mk_bound_region(None),
|
||||
};
|
||||
let r = fcx.tcx.mk_region(ty::ReLateBound(current_depth, br));
|
||||
let r = fcx.tcx.mk_re_late_bound(current_depth, br);
|
||||
r
|
||||
});
|
||||
if captured_tys.insert(ty) {
|
||||
captured_tys.insert(ty).then(|| {
|
||||
cause.ty = ty;
|
||||
Some(cause)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
cause
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
|
@ -302,7 +300,7 @@ pub fn resolve_interior<'a, 'tcx>(
|
|||
let var = ty::BoundVar::from_usize(bound_vars.len());
|
||||
bound_vars.push(ty::BoundVariableKind::Region(kind));
|
||||
counter += 1;
|
||||
fcx.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { var, kind }))
|
||||
fcx.tcx.mk_re_late_bound(ty::INNERMOST, ty::BoundRegion { var, kind })
|
||||
},
|
||||
types: &mut |b| bug!("unexpected bound ty in binder: {b:?}"),
|
||||
consts: &mut |b, ty| bug!("unexpected bound ct in binder: {b:?} {ty}"),
|
||||
|
|
@ -314,7 +312,7 @@ pub fn resolve_interior<'a, 'tcx>(
|
|||
|
||||
// Extract type components to build the witness type.
|
||||
let type_list = fcx.tcx.mk_type_list(type_causes.iter().map(|cause| cause.ty));
|
||||
let bound_vars = fcx.tcx.mk_bound_variable_kinds(bound_vars.iter());
|
||||
let bound_vars = fcx.tcx.intern_bound_variable_kinds(&bound_vars);
|
||||
let witness =
|
||||
fcx.tcx.mk_generator_witness(ty::Binder::bind_with_vars(type_list, bound_vars.clone()));
|
||||
|
||||
|
|
@ -364,7 +362,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
|
|||
let ty = tcx.mk_ref(
|
||||
// Use `ReErased` as `resolve_interior` is going to replace all the
|
||||
// regions anyway.
|
||||
tcx.mk_region(ty::ReErased),
|
||||
tcx.lifetimes.re_erased,
|
||||
ty::TypeAndMut { ty, mutbl: hir::Mutability::Not },
|
||||
);
|
||||
self.interior_visitor.record(
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ fn typeck_const_arg<'tcx>(
|
|||
tcx: TyCtxt<'tcx>,
|
||||
(did, param_did): (LocalDefId, DefId),
|
||||
) -> &ty::TypeckResults<'tcx> {
|
||||
let fallback = move || tcx.type_of(param_did);
|
||||
let fallback = move || tcx.type_of(param_did).subst_identity();
|
||||
typeck_with_fallback(tcx, did, fallback)
|
||||
}
|
||||
|
||||
|
|
@ -162,7 +162,7 @@ fn typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckResults<'tc
|
|||
if let Some(param_did) = tcx.opt_const_param_of(def_id) {
|
||||
tcx.typeck_const_arg((def_id, param_did))
|
||||
} else {
|
||||
let fallback = move || tcx.type_of(def_id.to_def_id());
|
||||
let fallback = move || tcx.type_of(def_id.to_def_id()).subst_identity();
|
||||
typeck_with_fallback(tcx, def_id, fallback)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -384,7 +384,15 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
|||
}
|
||||
(GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
|
||||
let tcx = self.cfcx.tcx();
|
||||
self.cfcx.ct_infer(tcx.type_of(param.def_id), Some(param), inf.span).into()
|
||||
self.cfcx
|
||||
.ct_infer(
|
||||
tcx.type_of(param.def_id)
|
||||
.no_bound_vars()
|
||||
.expect("const parameter types cannot be generic"),
|
||||
Some(param),
|
||||
inf.span,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -735,7 +735,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
debug!("impl_ty: {:?}", impl_ty);
|
||||
|
||||
// Determine the receiver type that the method itself expects.
|
||||
let (xform_self_ty, xform_ret_ty) = self.xform_self_ty(&item, impl_ty, impl_substs);
|
||||
let (xform_self_ty, xform_ret_ty) = self.xform_self_ty(item, impl_ty, impl_substs);
|
||||
debug!("xform_self_ty: {:?}, xform_ret_ty: {:?}", xform_self_ty, xform_ret_ty);
|
||||
|
||||
// We can't use normalize_associated_types_in as it will pollute the
|
||||
|
|
@ -796,7 +796,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
let new_trait_ref = this.erase_late_bound_regions(new_trait_ref);
|
||||
|
||||
let (xform_self_ty, xform_ret_ty) =
|
||||
this.xform_self_ty(&item, new_trait_ref.self_ty(), new_trait_ref.substs);
|
||||
this.xform_self_ty(item, new_trait_ref.self_ty(), new_trait_ref.substs);
|
||||
this.push_candidate(
|
||||
Candidate {
|
||||
xform_self_ty,
|
||||
|
|
@ -826,6 +826,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
ty::PredicateKind::Subtype(..)
|
||||
| ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
|
||||
| ty::PredicateKind::Coerce(..)
|
||||
| ty::PredicateKind::Clause(ty::Clause::Projection(..))
|
||||
| ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..))
|
||||
|
|
@ -845,7 +846,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
let trait_ref = this.erase_late_bound_regions(poly_trait_ref);
|
||||
|
||||
let (xform_self_ty, xform_ret_ty) =
|
||||
this.xform_self_ty(&item, trait_ref.self_ty(), trait_ref.substs);
|
||||
this.xform_self_ty(item, trait_ref.self_ty(), trait_ref.substs);
|
||||
|
||||
// Because this trait derives from a where-clause, it
|
||||
// should not contain any inference variables or other
|
||||
|
|
@ -916,7 +917,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
|
||||
fn matches_return_type(
|
||||
&self,
|
||||
method: &ty::AssocItem,
|
||||
method: ty::AssocItem,
|
||||
self_ty: Option<Ty<'tcx>>,
|
||||
expected: Ty<'tcx>,
|
||||
) -> bool {
|
||||
|
|
@ -965,11 +966,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
} else {
|
||||
let new_trait_ref = self.erase_late_bound_regions(bound_trait_ref);
|
||||
|
||||
let (xform_self_ty, xform_ret_ty) = self.xform_self_ty(
|
||||
&item,
|
||||
new_trait_ref.self_ty(),
|
||||
new_trait_ref.substs,
|
||||
);
|
||||
let (xform_self_ty, xform_ret_ty) =
|
||||
self.xform_self_ty(item, new_trait_ref.self_ty(), new_trait_ref.substs);
|
||||
self.push_candidate(
|
||||
Candidate {
|
||||
xform_self_ty,
|
||||
|
|
@ -997,7 +995,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
let (xform_self_ty, xform_ret_ty) =
|
||||
self.xform_self_ty(&item, trait_ref.self_ty(), trait_substs);
|
||||
self.xform_self_ty(item, trait_ref.self_ty(), trait_substs);
|
||||
self.push_candidate(
|
||||
Candidate {
|
||||
xform_self_ty,
|
||||
|
|
@ -1024,7 +1022,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
.filter(|candidate| candidate_filter(&candidate.item))
|
||||
.filter(|candidate| {
|
||||
if let Some(return_ty) = self.return_type {
|
||||
self.matches_return_type(&candidate.item, None, return_ty)
|
||||
self.matches_return_type(candidate.item, None, return_ty)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
|
|
@ -1576,7 +1574,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
traits::ImplDerivedObligation(Box::new(
|
||||
traits::ImplDerivedObligationCause {
|
||||
derived,
|
||||
impl_def_id,
|
||||
impl_or_alias_def_id: impl_def_id,
|
||||
impl_def_predicate_index: None,
|
||||
span,
|
||||
},
|
||||
|
|
@ -1883,7 +1881,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
#[instrument(level = "debug", skip(self))]
|
||||
fn xform_self_ty(
|
||||
&self,
|
||||
item: &ty::AssocItem,
|
||||
item: ty::AssocItem,
|
||||
impl_ty: Ty<'tcx>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
) -> (Ty<'tcx>, Option<Ty<'tcx>>) {
|
||||
|
|
@ -1940,7 +1938,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
&self,
|
||||
impl_def_id: DefId,
|
||||
) -> (ty::EarlyBinder<Ty<'tcx>>, SubstsRef<'tcx>) {
|
||||
(self.tcx.bound_type_of(impl_def_id), self.fresh_item_substs(impl_def_id))
|
||||
(self.tcx.type_of(impl_def_id), self.fresh_item_substs(impl_def_id))
|
||||
}
|
||||
|
||||
fn fresh_item_substs(&self, def_id: DefId) -> SubstsRef<'tcx> {
|
||||
|
|
@ -1958,7 +1956,14 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
kind: ConstVariableOriginKind::SubstitutionPlaceholder,
|
||||
span,
|
||||
};
|
||||
self.next_const_var(self.tcx.type_of(param.def_id), origin).into()
|
||||
self.next_const_var(
|
||||
self.tcx
|
||||
.type_of(param.def_id)
|
||||
.no_bound_vars()
|
||||
.expect("const parameter types cannot be generic"),
|
||||
origin,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -616,7 +616,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
ObligationCauseCode::ImplDerivedObligation(data)
|
||||
if matches!(p.kind().skip_binder(), ty::PredicateKind::Clause(_)) =>
|
||||
{
|
||||
Some((p, parent, data.impl_def_id, data))
|
||||
Some((p, parent, data.impl_or_alias_def_id, data))
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
|
|
@ -714,7 +714,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
);
|
||||
}
|
||||
Some(Node::Item(hir::Item {
|
||||
ident, kind: hir::ItemKind::Trait(..), ..
|
||||
ident,
|
||||
kind: hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..),
|
||||
..
|
||||
})) => {
|
||||
skip_list.insert(p);
|
||||
let entry = spanned_predicates.entry(ident.span);
|
||||
|
|
@ -906,8 +908,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// different from the received one
|
||||
// So we avoid suggestion method with Box<Self>
|
||||
// for instance
|
||||
self.tcx.at(span).type_of(*def_id) != rcvr_ty
|
||||
&& self.tcx.at(span).type_of(*def_id) != rcvr_ty
|
||||
self.tcx.at(span).type_of(*def_id).subst_identity()
|
||||
!= rcvr_ty
|
||||
&& self.tcx.at(span).type_of(*def_id).subst_identity()
|
||||
!= rcvr_ty
|
||||
}
|
||||
(Mode::Path, false, _) => true,
|
||||
_ => false,
|
||||
|
|
@ -927,7 +931,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
.iter()
|
||||
.take(limit)
|
||||
.map(|impl_item| {
|
||||
format!("- `{}`", self.tcx.at(span).type_of(*impl_item))
|
||||
format!(
|
||||
"- `{}`",
|
||||
self.tcx.at(span).type_of(*impl_item).subst_identity()
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
|
@ -1104,7 +1111,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
None
|
||||
};
|
||||
|
||||
let impl_ty = self.tcx.at(span).type_of(impl_did);
|
||||
let impl_ty = self.tcx.at(span).type_of(impl_did).subst_identity();
|
||||
|
||||
let insertion = match self.tcx.impl_trait_ref(impl_did) {
|
||||
None => String::new(),
|
||||
|
|
@ -1233,7 +1240,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// When the "method" is resolved through dereferencing, we really want the
|
||||
// original type that has the associated function for accurate suggestions.
|
||||
// (#61411)
|
||||
let impl_ty = self.tcx.type_of(*impl_did);
|
||||
let impl_ty = self.tcx.type_of(*impl_did).subst_identity();
|
||||
let target_ty = self
|
||||
.autoderef(sugg_span, rcvr_ty)
|
||||
.find(|(rcvr_ty, _)| {
|
||||
|
|
@ -1453,8 +1460,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
let range_def_id = self.tcx.require_lang_item(lang_item.unwrap(), None);
|
||||
let range_ty =
|
||||
self.tcx.bound_type_of(range_def_id).subst(self.tcx, &[actual.into()]);
|
||||
let range_ty = self.tcx.type_of(range_def_id).subst(self.tcx, &[actual.into()]);
|
||||
|
||||
let pick = self.lookup_probe_for_diagnostic(
|
||||
item_name,
|
||||
|
|
|
|||
|
|
@ -301,7 +301,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
|
||||
// Build a tuple (U0..Un) of the final upvar types U0..Un
|
||||
// and unify the upvar tuple type in the closure with it:
|
||||
let final_tupled_upvars_type = self.tcx.mk_tup(final_upvar_tys.iter());
|
||||
let final_tupled_upvars_type = self.tcx.intern_tup(&final_upvar_tys);
|
||||
self.demand_suptype(span, substs.tupled_upvars_ty(), final_tupled_upvars_type);
|
||||
|
||||
let fake_reads = delegate
|
||||
|
|
@ -315,8 +315,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
self.typeck_results.borrow_mut().closure_size_eval.insert(
|
||||
closure_def_id,
|
||||
ClosureSizeProfileData {
|
||||
before_feature_tys: self.tcx.mk_tup(before_feature_tys.into_iter()),
|
||||
after_feature_tys: self.tcx.mk_tup(after_feature_tys.into_iter()),
|
||||
before_feature_tys: self.tcx.intern_tup(&before_feature_tys),
|
||||
after_feature_tys: self.tcx.intern_tup(&after_feature_tys),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -363,7 +363,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
|
|||
opportunistically resolved to {:?}",
|
||||
vid, resolved_vid
|
||||
);
|
||||
let r = self.tcx.reuse_or_mk_region(r, ty::ReVar(resolved_vid));
|
||||
let r = self.tcx.mk_re_var(resolved_vid);
|
||||
self.canonicalize_mode.canonicalize_free_region(self, r)
|
||||
}
|
||||
|
||||
|
|
@ -737,8 +737,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
|||
) -> ty::Region<'tcx> {
|
||||
let var = self.canonical_var(info, r.into());
|
||||
let br = ty::BoundRegion { var, kind: ty::BrAnon(var.as_u32(), None) };
|
||||
let region = ty::ReLateBound(self.binder_index, br);
|
||||
self.interner().mk_region(region)
|
||||
self.interner().mk_re_late_bound(self.binder_index, br)
|
||||
}
|
||||
|
||||
/// Given a type variable `ty_var` of the given kind, first check
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
CanonicalVarKind::PlaceholderRegion(ty::PlaceholderRegion { universe, name }) => {
|
||||
let universe_mapped = universe_map(universe);
|
||||
let placeholder_mapped = ty::PlaceholderRegion { universe: universe_mapped, name };
|
||||
self.tcx.mk_region(ty::RePlaceholder(placeholder_mapped)).into()
|
||||
self.tcx.mk_re_placeholder(placeholder_mapped).into()
|
||||
}
|
||||
|
||||
CanonicalVarKind::Const(ui, ty) => self
|
||||
|
|
|
|||
|
|
@ -642,15 +642,14 @@ pub fn make_query_region_constraints<'tcx>(
|
|||
let constraint = match *k {
|
||||
// Swap regions because we are going from sub (<=) to outlives
|
||||
// (>=).
|
||||
Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate(
|
||||
tcx.mk_region(ty::ReVar(v2)).into(),
|
||||
tcx.mk_region(ty::ReVar(v1)),
|
||||
),
|
||||
Constraint::VarSubVar(v1, v2) => {
|
||||
ty::OutlivesPredicate(tcx.mk_re_var(v2).into(), tcx.mk_re_var(v1))
|
||||
}
|
||||
Constraint::VarSubReg(v1, r2) => {
|
||||
ty::OutlivesPredicate(r2.into(), tcx.mk_region(ty::ReVar(v1)))
|
||||
ty::OutlivesPredicate(r2.into(), tcx.mk_re_var(v1))
|
||||
}
|
||||
Constraint::RegSubVar(r1, v2) => {
|
||||
ty::OutlivesPredicate(tcx.mk_region(ty::ReVar(v2)).into(), r1)
|
||||
ty::OutlivesPredicate(tcx.mk_re_var(v2).into(), r1)
|
||||
}
|
||||
Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1),
|
||||
};
|
||||
|
|
@ -690,7 +689,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx> {
|
||||
self.infcx.tcx.mk_region(ty::RePlaceholder(placeholder))
|
||||
self.infcx.tcx.mk_re_placeholder(placeholder)
|
||||
}
|
||||
|
||||
fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> {
|
||||
|
|
|
|||
|
|
@ -125,11 +125,11 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
}
|
||||
|
||||
(ty::Alias(AliasKind::Projection, _), _) if self.tcx.trait_solver_next() => {
|
||||
relation.register_type_equate_obligation(a.into(), b.into());
|
||||
relation.register_type_equate_obligation(a, b);
|
||||
Ok(b)
|
||||
}
|
||||
(_, ty::Alias(AliasKind::Projection, _)) if self.tcx.trait_solver_next() => {
|
||||
relation.register_type_equate_obligation(b.into(), a.into());
|
||||
relation.register_type_equate_obligation(b, a);
|
||||
Ok(a)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1062,7 +1062,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
|
|||
|
||||
let parent_def_id = generics.parent.unwrap();
|
||||
if let DefKind::Impl { .. } = tcx.def_kind(parent_def_id) {
|
||||
let parent_ty = tcx.bound_type_of(parent_def_id).subst(tcx, substs);
|
||||
let parent_ty = tcx.type_of(parent_def_id).subst(tcx, substs);
|
||||
match (parent_ty.kind(), &ty.kind) {
|
||||
(
|
||||
ty::Adt(def, substs),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use rustc_hir as hir;
|
|||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_middle::hir::map::Map;
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::middle::resolve_lifetime as rl;
|
||||
use rustc_middle::middle::resolve_bound_vars as rbv;
|
||||
use rustc_middle::ty::{self, Region, TyCtxt};
|
||||
|
||||
/// This function calls the `visit_ty` method for the parameters
|
||||
|
|
@ -99,11 +99,11 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
|
|||
hir::TyKind::Ref(ref lifetime, _) => {
|
||||
// the lifetime of the Ref
|
||||
let hir_id = lifetime.hir_id;
|
||||
match (self.tcx.named_region(hir_id), self.bound_region) {
|
||||
match (self.tcx.named_bound_var(hir_id), self.bound_region) {
|
||||
// Find the index of the named region that was part of the
|
||||
// error. We will then search the function parameters for a bound
|
||||
// region at the right depth with the same index
|
||||
(Some(rl::Region::EarlyBound(id)), ty::BrNamed(def_id, _)) => {
|
||||
(Some(rbv::ResolvedArg::EarlyBound(id)), ty::BrNamed(def_id, _)) => {
|
||||
debug!("EarlyBound id={:?} def_id={:?}", id, def_id);
|
||||
if id == def_id {
|
||||
self.found_type = Some(arg);
|
||||
|
|
@ -115,7 +115,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
|
|||
// error. We will then search the function parameters for a bound
|
||||
// region at the right depth with the same index
|
||||
(
|
||||
Some(rl::Region::LateBound(debruijn_index, _, id)),
|
||||
Some(rbv::ResolvedArg::LateBound(debruijn_index, _, id)),
|
||||
ty::BrNamed(def_id, _),
|
||||
) => {
|
||||
debug!(
|
||||
|
|
@ -131,10 +131,11 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
|
|||
|
||||
(
|
||||
Some(
|
||||
rl::Region::Static
|
||||
| rl::Region::Free(_, _)
|
||||
| rl::Region::EarlyBound(_)
|
||||
| rl::Region::LateBound(_, _, _),
|
||||
rbv::ResolvedArg::StaticLifetime
|
||||
| rbv::ResolvedArg::Free(_, _)
|
||||
| rbv::ResolvedArg::EarlyBound(_)
|
||||
| rbv::ResolvedArg::LateBound(_, _, _)
|
||||
| rbv::ResolvedArg::Error(_),
|
||||
)
|
||||
| None,
|
||||
_,
|
||||
|
|
@ -186,9 +187,9 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> {
|
|||
}
|
||||
|
||||
fn visit_lifetime(&mut self, lifetime: &hir::Lifetime) {
|
||||
match (self.tcx.named_region(lifetime.hir_id), self.bound_region) {
|
||||
match (self.tcx.named_bound_var(lifetime.hir_id), self.bound_region) {
|
||||
// the lifetime of the TyPath!
|
||||
(Some(rl::Region::EarlyBound(id)), ty::BrNamed(def_id, _)) => {
|
||||
(Some(rbv::ResolvedArg::EarlyBound(id)), ty::BrNamed(def_id, _)) => {
|
||||
debug!("EarlyBound id={:?} def_id={:?}", id, def_id);
|
||||
if id == def_id {
|
||||
self.found_it = true;
|
||||
|
|
@ -196,7 +197,7 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
(Some(rl::Region::LateBound(debruijn_index, _, id)), ty::BrNamed(def_id, _)) => {
|
||||
(Some(rbv::ResolvedArg::LateBound(debruijn_index, _, id)), ty::BrNamed(def_id, _)) => {
|
||||
debug!("FindNestedTypeVisitor::visit_ty: LateBound depth = {:?}", debruijn_index,);
|
||||
debug!("id={:?}", id);
|
||||
debug!("def_id={:?}", def_id);
|
||||
|
|
@ -208,10 +209,11 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> {
|
|||
|
||||
(
|
||||
Some(
|
||||
rl::Region::Static
|
||||
| rl::Region::EarlyBound(_)
|
||||
| rl::Region::LateBound(_, _, _)
|
||||
| rl::Region::Free(_, _),
|
||||
rbv::ResolvedArg::StaticLifetime
|
||||
| rbv::ResolvedArg::EarlyBound(_)
|
||||
| rbv::ResolvedArg::LateBound(_, _, _)
|
||||
| rbv::ResolvedArg::Free(_, _)
|
||||
| rbv::ResolvedArg::Error(_),
|
||||
)
|
||||
| None,
|
||||
_,
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
|||
};
|
||||
|
||||
// Next, let's figure out the set of trait objects with implicit static bounds
|
||||
let ty = self.tcx().type_of(*impl_def_id);
|
||||
let ty = self.tcx().type_of(*impl_def_id).subst_identity();
|
||||
let mut v = super::static_impl_trait::TraitObjectVisitor(FxIndexSet::default());
|
||||
v.visit_ty(ty);
|
||||
let mut traits = vec![];
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use rustc_hir::def_id::DefId;
|
|||
use rustc_middle::ty::error::ExpectedFound;
|
||||
use rustc_middle::ty::print::{FmtPrinter, Print, RegionHighlightMode};
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::{self, RePlaceholder, ReVar, Region, TyCtxt};
|
||||
use rustc_middle::ty::{self, RePlaceholder, Region, TyCtxt};
|
||||
|
||||
use std::fmt;
|
||||
|
||||
|
|
@ -79,7 +79,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
|
|||
sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
|
||||
_,
|
||||
)) => self.try_report_trait_placeholder_mismatch(
|
||||
Some(self.tcx().mk_region(ReVar(*vid))),
|
||||
Some(self.tcx().mk_re_var(*vid)),
|
||||
cause,
|
||||
Some(*sub_placeholder),
|
||||
Some(*sup_placeholder),
|
||||
|
|
@ -95,7 +95,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
|
|||
_,
|
||||
_,
|
||||
)) => self.try_report_trait_placeholder_mismatch(
|
||||
Some(self.tcx().mk_region(ReVar(*vid))),
|
||||
Some(self.tcx().mk_re_var(*vid)),
|
||||
cause,
|
||||
Some(*sub_placeholder),
|
||||
None,
|
||||
|
|
@ -111,7 +111,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
|
|||
sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
|
||||
_,
|
||||
)) => self.try_report_trait_placeholder_mismatch(
|
||||
Some(self.tcx().mk_region(ReVar(*vid))),
|
||||
Some(self.tcx().mk_re_var(*vid)),
|
||||
cause,
|
||||
None,
|
||||
Some(*sup_placeholder),
|
||||
|
|
@ -127,7 +127,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
|
|||
sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
|
||||
_,
|
||||
)) => self.try_report_trait_placeholder_mismatch(
|
||||
Some(self.tcx().mk_region(ReVar(*vid))),
|
||||
Some(self.tcx().mk_re_var(*vid)),
|
||||
cause,
|
||||
None,
|
||||
Some(*sup_placeholder),
|
||||
|
|
@ -141,7 +141,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
|
|||
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
|
||||
sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
|
||||
)) => self.try_report_trait_placeholder_mismatch(
|
||||
Some(self.tcx().mk_region(ReVar(*vid))),
|
||||
Some(self.tcx().mk_re_var(*vid)),
|
||||
cause,
|
||||
None,
|
||||
Some(*sup_placeholder),
|
||||
|
|
|
|||
|
|
@ -90,20 +90,18 @@ pub fn find_param_with_region<'tcx>(
|
|||
r
|
||||
}
|
||||
});
|
||||
if found_anon_region {
|
||||
found_anon_region.then(|| {
|
||||
let ty_hir_id = fn_decl.inputs[index].hir_id;
|
||||
let param_ty_span = hir.span(ty_hir_id);
|
||||
let is_first = index == 0;
|
||||
Some(AnonymousParamInfo {
|
||||
AnonymousParamInfo {
|
||||
param,
|
||||
param_ty: new_param_ty,
|
||||
param_ty_span,
|
||||
bound_region,
|
||||
is_first,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -125,7 +123,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
|||
br: ty::BoundRegionKind,
|
||||
hir_sig: &hir::FnSig<'_>,
|
||||
) -> Option<Span> {
|
||||
let fn_ty = self.tcx().type_of(scope_def_id);
|
||||
let fn_ty = self.tcx().type_of(scope_def_id).subst_identity();
|
||||
if let ty::FnDef(_, _) = fn_ty.kind() {
|
||||
let ret_ty = fn_ty.fn_sig(self.tcx()).output();
|
||||
let span = hir_sig.decl.output.span();
|
||||
|
|
|
|||
|
|
@ -326,7 +326,7 @@ impl<T> Trait<T> for X {
|
|||
diag,
|
||||
&trait_ref,
|
||||
pred.bounds,
|
||||
&assoc,
|
||||
assoc,
|
||||
assoc_substs,
|
||||
ty,
|
||||
msg,
|
||||
|
|
@ -577,7 +577,7 @@ fn foo(&self) -> Self::T { String::new() }
|
|||
if let hir::Defaultness::Default { has_value: true } =
|
||||
tcx.impl_defaultness(item.id.owner_id)
|
||||
{
|
||||
let assoc_ty = tcx.bound_type_of(item.id.owner_id).subst_identity();
|
||||
let assoc_ty = tcx.type_of(item.id.owner_id).subst_identity();
|
||||
if self.infcx.can_eq(param_env, assoc_ty, found) {
|
||||
diag.span_label(
|
||||
item.span,
|
||||
|
|
@ -598,7 +598,7 @@ fn foo(&self) -> Self::T { String::new() }
|
|||
})) => {
|
||||
for item in &items[..] {
|
||||
if let hir::AssocItemKind::Type = item.kind {
|
||||
let assoc_ty = tcx.bound_type_of(item.id.owner_id).subst_identity();
|
||||
let assoc_ty = tcx.type_of(item.id.owner_id).subst_identity();
|
||||
|
||||
if self.infcx.can_eq(param_env, assoc_ty, found) {
|
||||
diag.span_label(item.span, "expected this associated type");
|
||||
|
|
@ -624,7 +624,7 @@ fn foo(&self) -> Self::T { String::new() }
|
|||
diag: &mut Diagnostic,
|
||||
trait_ref: &ty::TraitRef<'tcx>,
|
||||
bounds: hir::GenericBounds<'_>,
|
||||
assoc: &ty::AssocItem,
|
||||
assoc: ty::AssocItem,
|
||||
assoc_substs: &[ty::GenericArg<'tcx>],
|
||||
ty: Ty<'tcx>,
|
||||
msg: &str,
|
||||
|
|
@ -667,7 +667,7 @@ fn foo(&self) -> Self::T { String::new() }
|
|||
&self,
|
||||
diag: &mut Diagnostic,
|
||||
span: Span,
|
||||
assoc: &ty::AssocItem,
|
||||
assoc: ty::AssocItem,
|
||||
assoc_substs: &[ty::GenericArg<'tcx>],
|
||||
ty: Ty<'tcx>,
|
||||
msg: &str,
|
||||
|
|
|
|||
|
|
@ -82,10 +82,10 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
|
||||
let delegate = FnMutDelegate {
|
||||
regions: &mut |br: ty::BoundRegion| {
|
||||
self.tcx.mk_region(ty::RePlaceholder(ty::PlaceholderRegion {
|
||||
self.tcx.mk_re_placeholder(ty::PlaceholderRegion {
|
||||
universe: next_universe,
|
||||
name: br.kind,
|
||||
}))
|
||||
})
|
||||
},
|
||||
types: &mut |bound_ty: ty::BoundTy| {
|
||||
self.tcx.mk_placeholder(ty::PlaceholderType {
|
||||
|
|
|
|||
|
|
@ -382,7 +382,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
|||
// name the placeholder, then the placeholder is
|
||||
// larger; otherwise, the only ancestor is `'static`.
|
||||
Err(placeholder) if empty_ui.can_name(placeholder.universe) => {
|
||||
self.tcx().mk_region(RePlaceholder(placeholder))
|
||||
self.tcx().mk_re_placeholder(placeholder)
|
||||
}
|
||||
Err(_) => self.tcx().lifetimes.re_static,
|
||||
};
|
||||
|
|
@ -1046,7 +1046,7 @@ impl<'tcx> LexicalRegionResolutions<'tcx> {
|
|||
ty::ReVar(rid) => match self.values[rid] {
|
||||
VarValue::Empty(_) => r,
|
||||
VarValue::Value(r) => r,
|
||||
VarValue::ErrorValue => tcx.re_error_misc(),
|
||||
VarValue::ErrorValue => tcx.mk_re_error_misc(),
|
||||
},
|
||||
_ => r,
|
||||
};
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue