Merge from rustc

This commit is contained in:
Ralf Jung 2023-02-18 19:28:51 +01:00
commit 036929d86d
433 changed files with 3551 additions and 2190 deletions

View file

@ -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",

View file

@ -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,
}

View file

@ -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(
_,
_,

View file

@ -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");
}

View file

@ -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();
}

View file

@ -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,
&region_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,
}

View file

@ -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(),

View file

@ -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,
});

View file

@ -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;

View file

@ -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(),

View file

@ -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,

View file

@ -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",
)

View file

@ -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,

View file

@ -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(

View file

@ -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);
}
}

View file

@ -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]));

View file

@ -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);

View file

@ -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()

View file

@ -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);

View file

@ -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)),
})
}

View file

@ -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);
}

View file

@ -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()

View file

@ -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)
}

View file

@ -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) {

View file

@ -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());

View file

@ -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);

View file

@ -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);

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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

View file

@ -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)
}

View file

@ -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

View file

@ -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(),

View file

@ -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) {

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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();

View file

@ -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)

View file

@ -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 {

View file

@ -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;

View file

@ -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,
};

View file

@ -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))
}

View file

@ -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));

View file

@ -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) {

View file

@ -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`.

View file

@ -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.

View file

@ -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())
},
)
}

View file

@ -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(

View file

@ -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()) {

View file

@ -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)]);

View file

@ -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(&region.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);

View file

@ -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) => {

View file

@ -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)
}

View file

@ -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(..) => {}

View file

@ -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)
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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),

View file

@ -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();

View file

@ -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(&lt_name),
},
))
self.tcx.mk_re_early_bound(ty::EarlyBoundRegion {
def_id: item_def_id,
index: 0,
name: Symbol::intern(&lt_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,

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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(&param);
lifetimes.insert(def_id, reg);
}
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {}
}
let (def_id, reg) = ResolvedArg::early(&param);
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(&region_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(&region_def_id) {
Scope::Binder { ref bound_vars, scope_type, s, where_bound_origin, .. } => {
if let Some(&def) = bound_vars.get(&region_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(&param_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[&param_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);
}
}

View file

@ -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")]

View file

@ -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()
}

View file

@ -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(_)

View file

@ -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,

View file

@ -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(..)

View file

@ -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,

View file

@ -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)

View file

@ -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,
);
}

View file

@ -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;

View file

@ -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

View file

@ -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,

View file

@ -1046,7 +1046,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.param_env,
)
.may_apply()
.then(|| deref_ty)
.then_some(deref_ty)
})
}

View file

@ -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;
}

View file

@ -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),

View file

@ -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);

View file

@ -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) => {

View file

@ -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;

View file

@ -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(

View file

@ -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)
}
}

View file

@ -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!(),
}

View file

@ -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()
}
})
}

View file

@ -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,

View file

@ -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),
},
);
}

View file

@ -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

View file

@ -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

View file

@ -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> {

View file

@ -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)
}

View file

@ -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),

View file

@ -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,
_,

View file

@ -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![];

View file

@ -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),

View file

@ -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();

View file

@ -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,

View file

@ -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 {

View file

@ -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