refactor(rustc_middle): Substs -> GenericArg

This commit is contained in:
Mahdi Dibaiee 2023-07-11 22:35:29 +01:00
parent df5c2cf9bc
commit e55583c4b8
466 changed files with 4574 additions and 4604 deletions

View File

@ -7,8 +7,8 @@ use rustc_middle::mir::{
Body, Local, Location, Place, PlaceRef, ProjectionElem, Rvalue, SourceInfo, Statement, Body, Local, Location, Place, PlaceRef, ProjectionElem, Rvalue, SourceInfo, Statement,
StatementKind, Terminator, TerminatorKind, UserTypeProjection, StatementKind, Terminator, TerminatorKind, UserTypeProjection,
}; };
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::visit::TypeVisitable;
use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt}; use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
use crate::{ use crate::{
@ -49,11 +49,11 @@ struct ConstraintGeneration<'cg, 'tcx> {
} }
impl<'cg, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'tcx> { impl<'cg, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'tcx> {
/// We sometimes have `substs` within an rvalue, or within a /// We sometimes have `args` within an rvalue, or within a
/// call. Make them live at the location where they appear. /// call. Make them live at the location where they appear.
fn visit_substs(&mut self, substs: &SubstsRef<'tcx>, location: Location) { fn visit_args(&mut self, args: &GenericArgsRef<'tcx>, location: Location) {
self.add_regular_live_constraint(*substs, location); self.add_regular_live_constraint(*args, location);
self.super_substs(substs); self.super_args(args);
} }
/// We sometimes have `region` within an rvalue, or within a /// We sometimes have `region` within an rvalue, or within a

View File

@ -702,11 +702,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
.iter() .iter()
.copied() .copied()
.find_map(find_fn_kind_from_did), .find_map(find_fn_kind_from_did),
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => tcx ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => tcx
.explicit_item_bounds(def_id) .explicit_item_bounds(def_id)
.subst_iter_copied(tcx, substs) .arg_iter_copied(tcx, args)
.find_map(|(clause, span)| find_fn_kind_from_did((clause, span))), .find_map(|(clause, span)| find_fn_kind_from_did((clause, span))),
ty::Closure(_, substs) => match substs.as_closure().kind() { ty::Closure(_, args) => match args.as_closure().kind() {
ty::ClosureKind::Fn => Some(hir::Mutability::Not), ty::ClosureKind::Fn => Some(hir::Mutability::Not),
ty::ClosureKind::FnMut => Some(hir::Mutability::Mut), ty::ClosureKind::FnMut => Some(hir::Mutability::Mut),
_ => None, _ => None,
@ -1448,11 +1448,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} }
// Get closure's arguments // Get closure's arguments
let ty::Closure(_, substs) = typeck_results.expr_ty(closure_expr).kind() else { let ty::Closure(_, args) = typeck_results.expr_ty(closure_expr).kind() else {
/* hir::Closure can be a generator too */ /* hir::Closure can be a generator too */
return; return;
}; };
let sig = substs.as_closure().sig(); let sig = args.as_closure().sig();
let tupled_params = let tupled_params =
tcx.erase_late_bound_regions(sig.inputs().iter().next().unwrap().map_bound(|&b| b)); tcx.erase_late_bound_regions(sig.inputs().iter().next().unwrap().map_bound(|&b| b));
let ty::Tuple(params) = tupled_params.kind() else { return }; let ty::Tuple(params) = tupled_params.kind() else { return };
@ -2676,7 +2676,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
kind: TerminatorKind::Call { call_source: CallSource::OverloadedOperator, .. }, kind: TerminatorKind::Call { call_source: CallSource::OverloadedOperator, .. },
.. ..
}), }),
Some((method_did, method_substs)), Some((method_did, method_args)),
) = ( ) = (
&self.body[loan.reserve_location.block].terminator, &self.body[loan.reserve_location.block].terminator,
rustc_middle::util::find_self_call( rustc_middle::util::find_self_call(
@ -2689,7 +2689,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if tcx.is_diagnostic_item(sym::deref_method, method_did) { if tcx.is_diagnostic_item(sym::deref_method, method_did) {
let deref_target = let deref_target =
tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| { tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| {
Instance::resolve(tcx, self.param_env, deref_target, method_substs) Instance::resolve(tcx, self.param_env, deref_target, method_args)
.transpose() .transpose()
}); });
if let Some(Ok(instance)) = deref_target { if let Some(Ok(instance)) = deref_target {
@ -2856,11 +2856,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if is_closure { if is_closure {
None None
} else { } else {
let ty = self.infcx.tcx.type_of(self.mir_def_id()).subst_identity(); let ty = self.infcx.tcx.type_of(self.mir_def_id()).instantiate_identity();
match ty.kind() { match ty.kind() {
ty::FnDef(_, _) | ty::FnPtr(_) => self.annotate_fn_sig( ty::FnDef(_, _) | ty::FnPtr(_) => self.annotate_fn_sig(
self.mir_def_id(), self.mir_def_id(),
self.infcx.tcx.fn_sig(self.mir_def_id()).subst_identity(), self.infcx.tcx.fn_sig(self.mir_def_id()).instantiate_identity(),
), ),
_ => None, _ => None,
} }
@ -2902,7 +2902,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
); );
// Check if our `target` was captured by a closure. // Check if our `target` was captured by a closure.
if let Rvalue::Aggregate( if let Rvalue::Aggregate(
box AggregateKind::Closure(def_id, substs), box AggregateKind::Closure(def_id, args),
operands, operands,
) = rvalue ) = rvalue
{ {
@ -2933,7 +2933,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// into a place then we should annotate the closure in // into a place then we should annotate the closure in
// case it ends up being assigned into the return place. // case it ends up being assigned into the return place.
annotated_closure = annotated_closure =
self.annotate_fn_sig(def_id, substs.as_closure().sig()); self.annotate_fn_sig(def_id, args.as_closure().sig());
debug!( debug!(
"annotate_argument_and_return_for_borrow: \ "annotate_argument_and_return_for_borrow: \
annotated_closure={:?} assigned_from_local={:?} \ annotated_closure={:?} assigned_from_local={:?} \

View File

@ -168,17 +168,17 @@ impl<'tcx> BorrowExplanation<'tcx> {
let local_decl = &body.local_decls[dropped_local]; let local_decl = &body.local_decls[dropped_local];
let mut ty = local_decl.ty; let mut ty = local_decl.ty;
if local_decl.source_info.span.desugaring_kind() == Some(DesugaringKind::ForLoop) { if local_decl.source_info.span.desugaring_kind() == Some(DesugaringKind::ForLoop) {
if let ty::Adt(adt, substs) = local_decl.ty.kind() { if let ty::Adt(adt, args) = local_decl.ty.kind() {
if tcx.is_diagnostic_item(sym::Option, adt.did()) { if tcx.is_diagnostic_item(sym::Option, adt.did()) {
// in for loop desugaring, only look at the `Some(..)` inner type // in for loop desugaring, only look at the `Some(..)` inner type
ty = substs.type_at(0); ty = args.type_at(0);
} }
} }
} }
let (dtor_desc, type_desc) = match ty.kind() { let (dtor_desc, type_desc) = match ty.kind() {
// If type is an ADT that implements Drop, then // If type is an ADT that implements Drop, then
// simplify output by reporting just the ADT name. // simplify output by reporting just the ADT name.
ty::Adt(adt, _substs) if adt.has_dtor(tcx) && !adt.is_box() => { ty::Adt(adt, _args) if adt.has_dtor(tcx) && !adt.is_box() => {
("`Drop` code", format!("type `{}`", tcx.def_path_str(adt.did()))) ("`Drop` code", format!("type `{}`", tcx.def_path_str(adt.did())))
} }

View File

@ -732,18 +732,18 @@ impl<'tcx> BorrowedContentSource<'tcx> {
fn from_call(func: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Option<Self> { fn from_call(func: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Option<Self> {
match *func.kind() { match *func.kind() {
ty::FnDef(def_id, substs) => { ty::FnDef(def_id, args) => {
let trait_id = tcx.trait_of_item(def_id)?; let trait_id = tcx.trait_of_item(def_id)?;
let lang_items = tcx.lang_items(); let lang_items = tcx.lang_items();
if Some(trait_id) == lang_items.deref_trait() if Some(trait_id) == lang_items.deref_trait()
|| Some(trait_id) == lang_items.deref_mut_trait() || Some(trait_id) == lang_items.deref_mut_trait()
{ {
Some(BorrowedContentSource::OverloadedDeref(substs.type_at(0))) Some(BorrowedContentSource::OverloadedDeref(args.type_at(0)))
} else if Some(trait_id) == lang_items.index_trait() } else if Some(trait_id) == lang_items.index_trait()
|| Some(trait_id) == lang_items.index_mut_trait() || Some(trait_id) == lang_items.index_mut_trait()
{ {
Some(BorrowedContentSource::OverloadedIndex(substs.type_at(0))) Some(BorrowedContentSource::OverloadedIndex(args.type_at(0)))
} else { } else {
None None
} }
@ -847,7 +847,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
kind: TerminatorKind::Call { fn_span, call_source, .. }, .. kind: TerminatorKind::Call { fn_span, call_source, .. }, ..
}) = &self.body[location.block].terminator }) = &self.body[location.block].terminator
{ {
let Some((method_did, method_substs)) = rustc_middle::util::find_self_call( let Some((method_did, method_args)) = rustc_middle::util::find_self_call(
self.infcx.tcx, self.infcx.tcx,
&self.body, &self.body,
target_temp, target_temp,
@ -860,7 +860,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
self.infcx.tcx, self.infcx.tcx,
self.param_env, self.param_env,
method_did, method_did,
method_substs, method_args,
*fn_span, *fn_span,
call_source.from_hir_call(), call_source.from_hir_call(),
Some(self.infcx.tcx.fn_arg_names(method_did)[0]), Some(self.infcx.tcx.fn_arg_names(method_did)[0]),
@ -1039,7 +1039,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}); });
} }
} }
CallKind::Normal { self_arg, desugaring, method_did, method_substs } => { CallKind::Normal { self_arg, desugaring, method_did, method_args } => {
let self_arg = self_arg.unwrap(); let self_arg = self_arg.unwrap();
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
if let Some((CallDesugaringKind::ForLoopIntoIter, _)) = desugaring { if let Some((CallDesugaringKind::ForLoopIntoIter, _)) = desugaring {
@ -1106,13 +1106,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// Erase and shadow everything that could be passed to the new infcx. // Erase and shadow everything that could be passed to the new infcx.
let ty = moved_place.ty(self.body, tcx).ty; let ty = moved_place.ty(self.body, tcx).ty;
if let ty::Adt(def, substs) = ty.kind() if let ty::Adt(def, args) = ty.kind()
&& Some(def.did()) == tcx.lang_items().pin_type() && Some(def.did()) == tcx.lang_items().pin_type()
&& let ty::Ref(_, _, hir::Mutability::Mut) = substs.type_at(0).kind() && let ty::Ref(_, _, hir::Mutability::Mut) = args.type_at(0).kind()
&& let self_ty = self.infcx.instantiate_binder_with_fresh_vars( && let self_ty = self.infcx.instantiate_binder_with_fresh_vars(
fn_call_span, fn_call_span,
LateBoundRegionConversionTime::FnCall, LateBoundRegionConversionTime::FnCall,
tcx.fn_sig(method_did).subst(tcx, method_substs).input(0), tcx.fn_sig(method_did).instantiate(tcx, method_args).input(0),
) )
&& self.infcx.can_eq(self.param_env, ty, self_ty) && self.infcx.can_eq(self.param_env, ty, self_ty)
{ {
@ -1161,7 +1161,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let parent_self_ty = let parent_self_ty =
matches!(tcx.def_kind(parent_did), rustc_hir::def::DefKind::Impl { .. }) matches!(tcx.def_kind(parent_did), rustc_hir::def::DefKind::Impl { .. })
.then_some(parent_did) .then_some(parent_did)
.and_then(|did| match tcx.type_of(did).subst_identity().kind() { .and_then(|did| match tcx.type_of(did).instantiate_identity().kind() {
ty::Adt(def, ..) => Some(def.did()), ty::Adt(def, ..) => Some(def.did()),
_ => None, _ => None,
}); });

View File

@ -324,10 +324,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
ty::Array(..) | ty::Slice(..) => { ty::Array(..) | ty::Slice(..) => {
self.cannot_move_out_of_interior_noncopy(span, ty, None) self.cannot_move_out_of_interior_noncopy(span, ty, None)
} }
ty::Closure(def_id, closure_substs) ty::Closure(def_id, closure_args)
if def_id.as_local() == Some(self.mir_def_id()) && upvar_field.is_some() => if def_id.as_local() == Some(self.mir_def_id()) && upvar_field.is_some() =>
{ {
let closure_kind_ty = closure_substs.as_closure().kind_ty(); let closure_kind_ty = closure_args.as_closure().kind_ty();
let closure_kind = match closure_kind_ty.to_opt_closure_kind() { let closure_kind = match closure_kind_ty.to_opt_closure_kind() {
Some(kind @ (ty::ClosureKind::Fn | ty::ClosureKind::FnMut)) => kind, Some(kind @ (ty::ClosureKind::Fn | ty::ClosureKind::FnMut)) => kind,
Some(ty::ClosureKind::FnOnce) => { Some(ty::ClosureKind::FnOnce) => {

View File

@ -22,7 +22,7 @@ use rustc_infer::infer::{
}; };
use rustc_middle::hir::place::PlaceBase; use rustc_middle::hir::place::PlaceBase;
use rustc_middle::mir::{ConstraintCategory, ReturnConstraint}; use rustc_middle::mir::{ConstraintCategory, ReturnConstraint};
use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::GenericArgs;
use rustc_middle::ty::TypeVisitor; use rustc_middle::ty::TypeVisitor;
use rustc_middle::ty::{self, RegionVid, Ty}; use rustc_middle::ty::{self, RegionVid, Ty};
use rustc_middle::ty::{Region, TyCtxt}; use rustc_middle::ty::{Region, TyCtxt};
@ -183,9 +183,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
fn is_closure_fn_mut(&self, fr: RegionVid) -> bool { fn is_closure_fn_mut(&self, fr: RegionVid) -> bool {
if let Some(ty::ReFree(free_region)) = self.to_error_region(fr).as_deref() if let Some(ty::ReFree(free_region)) = self.to_error_region(fr).as_deref()
&& let ty::BoundRegionKind::BrEnv = free_region.bound_region && let ty::BoundRegionKind::BrEnv = free_region.bound_region
&& let DefiningTy::Closure(_, substs) = self.regioncx.universal_regions().defining_ty && let DefiningTy::Closure(_, args) = self.regioncx.universal_regions().defining_ty
{ {
return substs.as_closure().kind() == ty::ClosureKind::FnMut; return args.as_closure().kind() == ty::ClosureKind::FnMut;
} }
false false
@ -502,12 +502,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
.to_string(), .to_string(),
) )
} }
ty::Adt(adt, substs) => { ty::Adt(adt, args) => {
let generic_arg = substs[param_index as usize]; let generic_arg = args[param_index as usize];
let identity_substs = let identity_args =
InternalSubsts::identity_for_item(self.infcx.tcx, adt.did()); GenericArgs::identity_for_item(self.infcx.tcx, adt.did());
let base_ty = Ty::new_adt(self.infcx.tcx, *adt, identity_substs); let base_ty = Ty::new_adt(self.infcx.tcx, *adt, identity_args);
let base_generic_arg = identity_substs[param_index as usize]; let base_generic_arg = identity_args[param_index as usize];
let adt_desc = adt.descr(); let adt_desc = adt.descr();
let desc = format!( let desc = format!(
@ -520,12 +520,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
} }
ty::FnDef(def_id, _) => { ty::FnDef(def_id, _) => {
let name = self.infcx.tcx.item_name(*def_id); let name = self.infcx.tcx.item_name(*def_id);
let identity_substs = let identity_args = GenericArgs::identity_for_item(self.infcx.tcx, *def_id);
InternalSubsts::identity_for_item(self.infcx.tcx, *def_id);
let desc = format!("a function pointer to `{name}`"); let desc = format!("a function pointer to `{name}`");
let note = format!( let note = format!(
"the function `{name}` is invariant over the parameter `{}`", "the function `{name}` is invariant over the parameter `{}`",
identity_substs[param_index as usize] identity_args[param_index as usize]
); );
(desc, note) (desc, note)
} }
@ -573,7 +572,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty; let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty;
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *output_ty.kind() { if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *output_ty.kind() {
output_ty = self.infcx.tcx.type_of(def_id).subst_identity() output_ty = self.infcx.tcx.type_of(def_id).instantiate_identity()
}; };
debug!("report_fnmut_error: output_ty={:?}", output_ty); debug!("report_fnmut_error: output_ty={:?}", output_ty);
@ -899,14 +898,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
let instance = if let ConstraintCategory::CallArgument(Some(func_ty)) = category { let instance = if let ConstraintCategory::CallArgument(Some(func_ty)) = category {
let (fn_did, substs) = match func_ty.kind() { let (fn_did, args) = match func_ty.kind() {
ty::FnDef(fn_did, substs) => (fn_did, substs), ty::FnDef(fn_did, args) => (fn_did, args),
_ => return, _ => return,
}; };
debug!(?fn_did, ?substs); debug!(?fn_did, ?args);
// Only suggest this on function calls, not closures // Only suggest this on function calls, not closures
let ty = tcx.type_of(fn_did).subst_identity(); let ty = tcx.type_of(fn_did).instantiate_identity();
debug!("ty: {:?}, ty.kind: {:?}", ty, ty.kind()); debug!("ty: {:?}, ty.kind: {:?}", ty, ty.kind());
if let ty::Closure(_, _) = ty.kind() { if let ty::Closure(_, _) = ty.kind() {
return; return;
@ -916,7 +915,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
tcx, tcx,
self.param_env, self.param_env,
*fn_did, *fn_did,
self.infcx.resolve_vars_if_possible(substs), self.infcx.resolve_vars_if_possible(args),
) { ) {
instance instance
} else { } else {

View File

@ -5,8 +5,8 @@ use rustc_errors::Diagnostic;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_middle::ty::print::RegionHighlightMode; use rustc_middle::ty::print::RegionHighlightMode;
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
use rustc_middle::ty::{self, RegionVid, Ty}; use rustc_middle::ty::{self, RegionVid, Ty};
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP}; use rustc_span::{Span, DUMMY_SP};
@ -321,7 +321,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
ty::BoundRegionKind::BrEnv => { ty::BoundRegionKind::BrEnv => {
let def_ty = self.regioncx.universal_regions().defining_ty; let def_ty = self.regioncx.universal_regions().defining_ty;
let DefiningTy::Closure(_, substs) = def_ty else { let DefiningTy::Closure(_, args) = def_ty else {
// Can't have BrEnv in functions, constants or generators. // Can't have BrEnv in functions, constants or generators.
bug!("BrEnv outside of closure."); bug!("BrEnv outside of closure.");
}; };
@ -332,7 +332,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
}; };
let region_name = self.synthesize_region_name(); let region_name = self.synthesize_region_name();
let closure_kind_ty = substs.as_closure().kind_ty(); let closure_kind_ty = args.as_closure().kind_ty();
let note = match closure_kind_ty.to_opt_closure_kind() { let note = match closure_kind_ty.to_opt_closure_kind() {
Some(ty::ClosureKind::Fn) => { Some(ty::ClosureKind::Fn) => {
"closure implements `Fn`, so references to captured variables \ "closure implements `Fn`, so references to captured variables \
@ -510,10 +510,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
} }
// Match up something like `Foo<'1>` // Match up something like `Foo<'1>`
( (ty::Adt(_adt_def, args), hir::TyKind::Path(hir::QPath::Resolved(None, path))) => {
ty::Adt(_adt_def, substs),
hir::TyKind::Path(hir::QPath::Resolved(None, path)),
) => {
match path.res { match path.res {
// Type parameters of the type alias have no reason to // Type parameters of the type alias have no reason to
// be the same as those of the ADT. // be the same as those of the ADT.
@ -523,7 +520,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
_ => { _ => {
if let Some(last_segment) = path.segments.last() { if let Some(last_segment) = path.segments.last() {
if let Some(highlight) = self.match_adt_and_segment( if let Some(highlight) = self.match_adt_and_segment(
substs, args,
needle_fr, needle_fr,
last_segment, last_segment,
search_stack, search_stack,
@ -560,22 +557,22 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
None None
} }
/// We've found an enum/struct/union type with the substitutions /// We've found an enum/struct/union type with the generic args
/// `substs` and -- in the HIR -- a path type with the final /// `args` and -- in the HIR -- a path type with the final
/// segment `last_segment`. Try to find a `'_` to highlight in /// segment `last_segment`. Try to find a `'_` to highlight in
/// the generic args (or, if not, to produce new zipped pairs of /// the generic args (or, if not, to produce new zipped pairs of
/// types+hir to search through). /// types+hir to search through).
fn match_adt_and_segment<'hir>( fn match_adt_and_segment<'hir>(
&self, &self,
substs: SubstsRef<'tcx>, args: GenericArgsRef<'tcx>,
needle_fr: RegionVid, needle_fr: RegionVid,
last_segment: &'hir hir::PathSegment<'hir>, last_segment: &'hir hir::PathSegment<'hir>,
search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty<'hir>)>, search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty<'hir>)>,
) -> Option<RegionNameHighlight> { ) -> Option<RegionNameHighlight> {
// Did the user give explicit arguments? (e.g., `Foo<..>`) // Did the user give explicit arguments? (e.g., `Foo<..>`)
let args = last_segment.args.as_ref()?; let explicit_args = last_segment.args.as_ref()?;
let lifetime = let lifetime =
self.try_match_adt_and_generic_args(substs, needle_fr, args, search_stack)?; self.try_match_adt_and_generic_args(args, needle_fr, explicit_args, search_stack)?;
if lifetime.is_anonymous() { if lifetime.is_anonymous() {
None None
} else { } else {
@ -583,19 +580,19 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
} }
} }
/// We've found an enum/struct/union type with the substitutions /// We've found an enum/struct/union type with the generic args
/// `substs` and -- in the HIR -- a path with the generic /// `args` and -- in the HIR -- a path with the generic
/// arguments `args`. If `needle_fr` appears in the args, return /// arguments `hir_args`. If `needle_fr` appears in the args, return
/// the `hir::Lifetime` that corresponds to it. If not, push onto /// the `hir::Lifetime` that corresponds to it. If not, push onto
/// `search_stack` the types+hir to search through. /// `search_stack` the types+hir to search through.
fn try_match_adt_and_generic_args<'hir>( fn try_match_adt_and_generic_args<'hir>(
&self, &self,
substs: SubstsRef<'tcx>, args: GenericArgsRef<'tcx>,
needle_fr: RegionVid, needle_fr: RegionVid,
args: &'hir hir::GenericArgs<'hir>, hir_args: &'hir hir::GenericArgs<'hir>,
search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty<'hir>)>, search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty<'hir>)>,
) -> Option<&'hir hir::Lifetime> { ) -> Option<&'hir hir::Lifetime> {
for (kind, hir_arg) in iter::zip(substs, args.args) { for (kind, hir_arg) in iter::zip(args, hir_args.args) {
match (kind.unpack(), hir_arg) { match (kind.unpack(), hir_arg) {
(GenericArgKind::Lifetime(r), hir::GenericArg::Lifetime(lt)) => { (GenericArgKind::Lifetime(r), hir::GenericArg::Lifetime(lt)) => {
if r.as_var() == needle_fr { if r.as_var() == needle_fr {
@ -849,9 +846,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
return None; return None;
}; };
let found = tcx.any_free_region_meets(&tcx.type_of(region_parent).subst_identity(), |r| { let found = tcx
*r == ty::ReEarlyBound(region) .any_free_region_meets(&tcx.type_of(region_parent).instantiate_identity(), |r| {
}); *r == ty::ReEarlyBound(region)
});
Some(RegionName { Some(RegionName {
name: self.synthesize_region_name(), name: self.synthesize_region_name(),

View File

@ -301,7 +301,7 @@ fn do_mir_borrowck<'tcx>(
let movable_generator = let movable_generator =
// The first argument is the generator type passed by value // The first argument is the generator type passed by value
if let Some(local) = body.local_decls.raw.get(1) if let Some(local) = body.local_decls.raw.get(1)
// Get the interior types and substs which typeck computed // Get the interior types and args which typeck computed
&& let ty::Generator(_, _, hir::Movability::Static) = local.ty.kind() && let ty::Generator(_, _, hir::Movability::Static) = local.ty.kind()
{ {
false false

View File

@ -1115,7 +1115,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
) -> Option<ClosureOutlivesSubject<'tcx>> { ) -> Option<ClosureOutlivesSubject<'tcx>> {
let tcx = infcx.tcx; let tcx = infcx.tcx;
// Opaque types' substs may include useless lifetimes. // Opaque types' args may include useless lifetimes.
// We will replace them with ReStatic. // We will replace them with ReStatic.
struct OpaqueFolder<'tcx> { struct OpaqueFolder<'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
@ -1127,19 +1127,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
use ty::TypeSuperFoldable as _; use ty::TypeSuperFoldable as _;
let tcx = self.tcx; let tcx = self.tcx;
let &ty::Alias(ty::Opaque, ty::AliasTy { substs, def_id, .. }) = t.kind() else { let &ty::Alias(ty::Opaque, ty::AliasTy { args, def_id, .. }) = t.kind() else {
return t.super_fold_with(self); return t.super_fold_with(self);
}; };
let substs = let args = std::iter::zip(args, tcx.variances_of(def_id)).map(|(arg, v)| {
std::iter::zip(substs, tcx.variances_of(def_id)).map(|(arg, v)| { match (arg.unpack(), v) {
match (arg.unpack(), v) { (ty::GenericArgKind::Lifetime(_), ty::Bivariant) => {
(ty::GenericArgKind::Lifetime(_), ty::Bivariant) => { tcx.lifetimes.re_static.into()
tcx.lifetimes.re_static.into()
}
_ => arg.fold_with(self),
} }
}); _ => arg.fold_with(self),
Ty::new_opaque(tcx, def_id, tcx.mk_substs_from_iter(substs)) }
});
Ty::new_opaque(tcx, def_id, tcx.mk_args_from_iter(args))
} }
} }

View File

@ -6,9 +6,9 @@ use rustc_infer::infer::InferCtxt;
use rustc_infer::infer::TyCtxtInferExt as _; use rustc_infer::infer::TyCtxtInferExt as _;
use rustc_infer::traits::{Obligation, ObligationCause}; use rustc_infer::traits::{Obligation, ObligationCause};
use rustc_middle::traits::DefiningAnchor; use rustc_middle::traits::DefiningAnchor;
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable}; use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable};
use rustc_middle::ty::{GenericArgKind, GenericArgs};
use rustc_span::Span; use rustc_span::Span;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
use rustc_trait_selection::traits::ObligationCtxt; use rustc_trait_selection::traits::ObligationCtxt;
@ -38,15 +38,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// back to concrete lifetimes: `'static`, `ReEarlyBound` or `ReFree`. /// back to concrete lifetimes: `'static`, `ReEarlyBound` or `ReFree`.
/// ///
/// First we map all the lifetimes in the concrete type to an equal /// First we map all the lifetimes in the concrete type to an equal
/// universal region that occurs in the concrete type's substs, in this case /// universal region that occurs in the concrete type's args, in this case
/// this would result in `&'1 i32`. We only consider regions in the substs /// this would result in `&'1 i32`. We only consider regions in the args
/// in case there is an equal region that does not. For example, this should /// in case there is an equal region that does not. For example, this should
/// be allowed: /// be allowed:
/// `fn f<'a: 'b, 'b: 'a>(x: *mut &'b i32) -> impl Sized + 'a { x }` /// `fn f<'a: 'b, 'b: 'a>(x: *mut &'b i32) -> impl Sized + 'a { x }`
/// ///
/// Then we map the regions in both the type and the subst to their /// Then we map the regions in both the type and the subst to their
/// `external_name` giving `concrete_type = &'a i32`, /// `external_name` giving `concrete_type = &'a i32`,
/// `substs = ['static, 'a]`. This will then allow /// `args = ['static, 'a]`. This will then allow
/// `infer_opaque_definition_from_instantiation` to determine that /// `infer_opaque_definition_from_instantiation` to determine that
/// `_Return<'_a> = &'_a i32`. /// `_Return<'_a> = &'_a i32`.
/// ///
@ -73,8 +73,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
debug!(?member_constraints); debug!(?member_constraints);
for (opaque_type_key, concrete_type) in opaque_ty_decls { for (opaque_type_key, concrete_type) in opaque_ty_decls {
let substs = opaque_type_key.substs; let args = opaque_type_key.args;
debug!(?concrete_type, ?substs); debug!(?concrete_type, ?args);
let mut subst_regions = vec![self.universal_regions.fr_static]; let mut subst_regions = vec![self.universal_regions.fr_static];
@ -95,7 +95,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
ty::Region::new_error_with_message( ty::Region::new_error_with_message(
infcx.tcx, infcx.tcx,
concrete_type.span, concrete_type.span,
"opaque type with non-universal region substs", "opaque type with non-universal region args",
) )
} }
} }
@ -110,17 +110,17 @@ impl<'tcx> RegionInferenceContext<'tcx> {
} }
debug!(?subst_regions); debug!(?subst_regions);
// Next, insert universal regions from substs, so we can translate regions that appear // Next, insert universal regions from args, so we can translate regions that appear
// in them but are not subject to member constraints, for instance closure substs. // in them but are not subject to member constraints, for instance closure args.
let universal_substs = infcx.tcx.fold_regions(substs, |region, _| { let universal_args = infcx.tcx.fold_regions(args, |region, _| {
if let ty::RePlaceholder(..) = region.kind() { if let ty::RePlaceholder(..) = region.kind() {
// Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs. // Higher kinded regions don't need remapping, they don't refer to anything outside of this the args.
return region; return region;
} }
let vid = self.to_region_vid(region); let vid = self.to_region_vid(region);
to_universal_region(vid, &mut subst_regions) to_universal_region(vid, &mut subst_regions)
}); });
debug!(?universal_substs); debug!(?universal_args);
debug!(?subst_regions); debug!(?subst_regions);
// Deduplicate the set of regions while keeping the chosen order. // Deduplicate the set of regions while keeping the chosen order.
@ -139,7 +139,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
debug!(?universal_concrete_type); debug!(?universal_concrete_type);
let opaque_type_key = let opaque_type_key =
OpaqueTypeKey { def_id: opaque_type_key.def_id, substs: universal_substs }; OpaqueTypeKey { def_id: opaque_type_key.def_id, args: universal_args };
let ty = infcx.infer_opaque_definition_from_instantiation( let ty = infcx.infer_opaque_definition_from_instantiation(
opaque_type_key, opaque_type_key,
universal_concrete_type, universal_concrete_type,
@ -175,7 +175,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// Map the regions in the type to named regions. This is similar to what /// Map the regions in the type to named regions. This is similar to what
/// `infer_opaque_types` does, but can infer any universal region, not only /// `infer_opaque_types` does, but can infer any universal region, not only
/// ones from the substs for the opaque type. It also doesn't double check /// ones from the args for the opaque type. It also doesn't double check
/// that the regions produced are in fact equal to the named region they are /// that the regions produced are in fact equal to the named region they are
/// replaced with. This is fine because this function is only to improve the /// replaced with. This is fine because this function is only to improve the
/// region names in error messages. /// region names in error messages.
@ -238,7 +238,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
/// # Parameters /// # Parameters
/// ///
/// - `def_id`, the `impl Trait` type /// - `def_id`, the `impl Trait` type
/// - `substs`, the substs used to instantiate this opaque type /// - `args`, the args used to instantiate this opaque type
/// - `instantiated_ty`, the inferred type C1 -- fully resolved, lifted version of /// - `instantiated_ty`, the inferred type C1 -- fully resolved, lifted version of
/// `opaque_defn.concrete_ty` /// `opaque_defn.concrete_ty`
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
@ -309,11 +309,11 @@ fn check_opaque_type_well_formed<'tcx>(
}) })
.build(); .build();
let ocx = ObligationCtxt::new(&infcx); let ocx = ObligationCtxt::new(&infcx);
let identity_substs = InternalSubsts::identity_for_item(tcx, def_id); let identity_args = GenericArgs::identity_for_item(tcx, def_id);
// Require that the hidden type actually fulfills all the bounds of the opaque type, even without // Require that the hidden type actually fulfills all the bounds of the opaque type, even without
// the bounds that the function supplies. // the bounds that the function supplies.
let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), identity_substs); let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), identity_args);
ocx.eq(&ObligationCause::misc(definition_span, def_id), param_env, opaque_ty, definition_ty) ocx.eq(&ObligationCause::misc(definition_span, def_id), param_env, opaque_ty, definition_ty)
.map_err(|err| { .map_err(|err| {
infcx infcx
@ -384,7 +384,7 @@ fn check_opaque_type_parameter_valid(
} }
let opaque_generics = tcx.generics_of(opaque_type_key.def_id); let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default(); let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default();
for (i, arg) in opaque_type_key.substs.iter().enumerate() { for (i, arg) in opaque_type_key.args.iter().enumerate() {
let arg_is_param = match arg.unpack() { let arg_is_param = match arg.unpack() {
GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)), GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)),
GenericArgKind::Lifetime(lt) => { GenericArgKind::Lifetime(lt) => {

View File

@ -6,7 +6,7 @@ use rustc_infer::infer::NllRegionVariableOrigin;
use rustc_middle::mir::visit::{MutVisitor, TyContext}; use rustc_middle::mir::visit::{MutVisitor, TyContext};
use rustc_middle::mir::Constant; use rustc_middle::mir::Constant;
use rustc_middle::mir::{Body, Location, Promoted}; use rustc_middle::mir::{Body, Location, Promoted};
use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc_span::{Span, Symbol}; use rustc_span::{Span, Symbol};
@ -94,10 +94,10 @@ impl<'a, 'tcx> MutVisitor<'tcx> for RegionRenumberer<'a, 'tcx> {
} }
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "debug")]
fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, location: Location) { fn visit_args(&mut self, args: &mut GenericArgsRef<'tcx>, location: Location) {
*substs = self.renumber_regions(*substs, || RegionCtxt::Location(location)); *args = self.renumber_regions(*args, || RegionCtxt::Location(location));
debug!(?substs); debug!(?args);
} }
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "debug")]

View File

@ -5,7 +5,7 @@ use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelega
use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound}; use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
use rustc_infer::infer::{self, InferCtxt, SubregionOrigin}; use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory}; use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::GenericArgKind;
use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::ty::{self, TyCtxt};
use rustc_middle::ty::{TypeFoldable, TypeVisitableExt}; use rustc_middle::ty::{TypeFoldable, TypeVisitableExt};
use rustc_span::{Span, DUMMY_SP}; use rustc_span::{Span, DUMMY_SP};
@ -89,20 +89,20 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
/// Given an instance of the closure type, this method instantiates the "extra" requirements /// Given an instance of the closure type, this method instantiates the "extra" requirements
/// that we computed for the closure. This has the effect of adding new outlives obligations /// that we computed for the closure. This has the effect of adding new outlives obligations
/// to existing region variables in `closure_substs`. /// to existing region variables in `closure_args`.
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "debug")]
pub fn apply_closure_requirements( pub fn apply_closure_requirements(
&mut self, &mut self,
closure_requirements: &ClosureRegionRequirements<'tcx>, closure_requirements: &ClosureRegionRequirements<'tcx>,
closure_def_id: DefId, closure_def_id: DefId,
closure_substs: ty::SubstsRef<'tcx>, closure_args: ty::GenericArgsRef<'tcx>,
) { ) {
// Extract the values of the free regions in `closure_substs` // Extract the values of the free regions in `closure_args`
// into a vector. These are the regions that we will be // into a vector. These are the regions that we will be
// relating to one another. // relating to one another.
let closure_mapping = &UniversalRegions::closure_mapping( let closure_mapping = &UniversalRegions::closure_mapping(
self.tcx, self.tcx,
closure_substs, closure_args,
closure_requirements.num_external_vids, closure_requirements.num_external_vids,
closure_def_id.expect_local(), closure_def_id.expect_local(),
); );

View File

@ -2,7 +2,7 @@ use crate::def_use::{self, DefUse};
use crate::location::{LocationIndex, LocationTable}; use crate::location::{LocationIndex, LocationTable};
use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::{Body, Local, Location, Place}; use rustc_middle::mir::{Body, Local, Location, Place};
use rustc_middle::ty::subst::GenericArg; use rustc_middle::ty::GenericArg;
use rustc_mir_dataflow::move_paths::{LookupResult, MoveData, MovePathIndex}; use rustc_mir_dataflow::move_paths::{LookupResult, MoveData, MovePathIndex};
use super::TypeChecker; use super::TypeChecker;

View File

@ -30,12 +30,12 @@ use rustc_middle::traits::query::NoSolution;
use rustc_middle::traits::ObligationCause; use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::cast::CastTy; use rustc_middle::ty::cast::CastTy;
use rustc_middle::ty::subst::{SubstsRef, UserSubsts};
use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, Dynamic, self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, Dynamic,
OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, UserTypeAnnotationIndex, OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, UserTypeAnnotationIndex,
}; };
use rustc_middle::ty::{GenericArgsRef, UserArgs};
use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::def_id::CRATE_DEF_ID;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use rustc_span::{Span, DUMMY_SP}; use rustc_span::{Span, DUMMY_SP};
@ -389,15 +389,12 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
} else { } else {
self.cx.ascribe_user_type( self.cx.ascribe_user_type(
constant.literal.ty(), constant.literal.ty(),
UserType::TypeOf( UserType::TypeOf(uv.def, UserArgs { args: uv.args, user_self_ty: None }),
uv.def,
UserSubsts { substs: uv.substs, user_self_ty: None },
),
locations.span(&self.cx.body), locations.span(&self.cx.body),
); );
} }
} else if let Some(static_def_id) = constant.check_static_ptr(tcx) { } else if let Some(static_def_id) = constant.check_static_ptr(tcx) {
let unnormalized_ty = tcx.type_of(static_def_id).subst_identity(); let unnormalized_ty = tcx.type_of(static_def_id).instantiate_identity();
let normalized_ty = self.cx.normalize(unnormalized_ty, locations); let normalized_ty = self.cx.normalize(unnormalized_ty, locations);
let literal_ty = constant.literal.ty().builtin_deref(true).unwrap().ty; let literal_ty = constant.literal.ty().builtin_deref(true).unwrap().ty;
@ -411,11 +408,11 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
} }
} }
if let ty::FnDef(def_id, substs) = *constant.literal.ty().kind() { if let ty::FnDef(def_id, args) = *constant.literal.ty().kind() {
// const_trait_impl: use a non-const param env when checking that a FnDef type is well formed. // const_trait_impl: use a non-const param env when checking that a FnDef type is well formed.
// this is because the well-formedness of the function does not need to be proved to have `const` // this is because the well-formedness of the function does not need to be proved to have `const`
// impls for trait bounds. // impls for trait bounds.
let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs); let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, args);
let prev = self.cx.param_env; let prev = self.cx.param_env;
self.cx.param_env = prev.without_const(); self.cx.param_env = prev.without_const();
self.cx.normalize_and_prove_instantiated_predicates( self.cx.normalize_and_prove_instantiated_predicates(
@ -666,7 +663,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
}) })
} }
ProjectionElem::Downcast(maybe_name, index) => match base_ty.kind() { ProjectionElem::Downcast(maybe_name, index) => match base_ty.kind() {
ty::Adt(adt_def, _substs) if adt_def.is_enum() => { ty::Adt(adt_def, _args) if adt_def.is_enum() => {
if index.as_usize() >= adt_def.variants().len() { if index.as_usize() >= adt_def.variants().len() {
PlaceTy::from_ty(span_mirbug_and_err!( PlaceTy::from_ty(span_mirbug_and_err!(
self, self,
@ -776,16 +773,16 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
) -> Result<Ty<'tcx>, FieldAccessError> { ) -> Result<Ty<'tcx>, FieldAccessError> {
let tcx = self.tcx(); let tcx = self.tcx();
let (variant, substs) = match base_ty { let (variant, args) = match base_ty {
PlaceTy { ty, variant_index: Some(variant_index) } => match *ty.kind() { PlaceTy { ty, variant_index: Some(variant_index) } => match *ty.kind() {
ty::Adt(adt_def, substs) => (adt_def.variant(variant_index), substs), ty::Adt(adt_def, args) => (adt_def.variant(variant_index), args),
ty::Generator(def_id, substs, _) => { ty::Generator(def_id, args, _) => {
let mut variants = substs.as_generator().state_tys(def_id, tcx); let mut variants = args.as_generator().state_tys(def_id, tcx);
let Some(mut variant) = variants.nth(variant_index.into()) else { let Some(mut variant) = variants.nth(variant_index.into()) else {
bug!( bug!(
"variant_index of generator out of range: {:?}/{:?}", "variant_index of generator out of range: {:?}/{:?}",
variant_index, variant_index,
substs.as_generator().state_tys(def_id, tcx).count() args.as_generator().state_tys(def_id, tcx).count()
); );
}; };
return match variant.nth(field.index()) { return match variant.nth(field.index()) {
@ -796,11 +793,11 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
_ => bug!("can't have downcast of non-adt non-generator type"), _ => bug!("can't have downcast of non-adt non-generator type"),
}, },
PlaceTy { ty, variant_index: None } => match *ty.kind() { PlaceTy { ty, variant_index: None } => match *ty.kind() {
ty::Adt(adt_def, substs) if !adt_def.is_enum() => { ty::Adt(adt_def, args) if !adt_def.is_enum() => {
(adt_def.variant(FIRST_VARIANT), substs) (adt_def.variant(FIRST_VARIANT), args)
} }
ty::Closure(_, substs) => { ty::Closure(_, args) => {
return match substs return match args
.as_closure() .as_closure()
.tupled_upvars_ty() .tupled_upvars_ty()
.tuple_fields() .tuple_fields()
@ -808,17 +805,17 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
{ {
Some(&ty) => Ok(ty), Some(&ty) => Ok(ty),
None => Err(FieldAccessError::OutOfRange { None => Err(FieldAccessError::OutOfRange {
field_count: substs.as_closure().upvar_tys().count(), field_count: args.as_closure().upvar_tys().count(),
}), }),
}; };
} }
ty::Generator(_, substs, _) => { ty::Generator(_, args, _) => {
// Only prefix fields (upvars and current state) are // Only prefix fields (upvars and current state) are
// accessible without a variant index. // accessible without a variant index.
return match substs.as_generator().prefix_tys().nth(field.index()) { return match args.as_generator().prefix_tys().nth(field.index()) {
Some(ty) => Ok(ty), Some(ty) => Ok(ty),
None => Err(FieldAccessError::OutOfRange { None => Err(FieldAccessError::OutOfRange {
field_count: substs.as_generator().prefix_tys().count(), field_count: args.as_generator().prefix_tys().count(),
}), }),
}; };
} }
@ -840,7 +837,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
}; };
if let Some(field) = variant.fields.get(field) { if let Some(field) = variant.fields.get(field) {
Ok(self.cx.normalize(field.ty(tcx, substs), location)) Ok(self.cx.normalize(field.ty(tcx, args), location))
} else { } else {
Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() }) Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() })
} }
@ -1065,7 +1062,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
ocx.infcx.add_item_bounds_for_hidden_type( ocx.infcx.add_item_bounds_for_hidden_type(
opaque_type_key.def_id.to_def_id(), opaque_type_key.def_id.to_def_id(),
opaque_type_key.substs, opaque_type_key.args,
cause, cause,
param_env, param_env,
hidden_ty.ty, hidden_ty.ty,
@ -1770,32 +1767,32 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let tcx = self.tcx(); let tcx = self.tcx();
match *ak { match *ak {
AggregateKind::Adt(adt_did, variant_index, substs, _, active_field_index) => { AggregateKind::Adt(adt_did, variant_index, args, _, active_field_index) => {
let def = tcx.adt_def(adt_did); let def = tcx.adt_def(adt_did);
let variant = &def.variant(variant_index); let variant = &def.variant(variant_index);
let adj_field_index = active_field_index.unwrap_or(field_index); let adj_field_index = active_field_index.unwrap_or(field_index);
if let Some(field) = variant.fields.get(adj_field_index) { if let Some(field) = variant.fields.get(adj_field_index) {
Ok(self.normalize(field.ty(tcx, substs), location)) Ok(self.normalize(field.ty(tcx, args), location))
} else { } else {
Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() }) Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() })
} }
} }
AggregateKind::Closure(_, substs) => { AggregateKind::Closure(_, args) => {
match substs.as_closure().upvar_tys().nth(field_index.as_usize()) { match args.as_closure().upvar_tys().nth(field_index.as_usize()) {
Some(ty) => Ok(ty), Some(ty) => Ok(ty),
None => Err(FieldAccessError::OutOfRange { None => Err(FieldAccessError::OutOfRange {
field_count: substs.as_closure().upvar_tys().count(), field_count: args.as_closure().upvar_tys().count(),
}), }),
} }
} }
AggregateKind::Generator(_, substs, _) => { AggregateKind::Generator(_, args, _) => {
// It doesn't make sense to look at a field beyond the prefix; // It doesn't make sense to look at a field beyond the prefix;
// these require a variant index, and are not initialized in // these require a variant index, and are not initialized in
// aggregate rvalues. // aggregate rvalues.
match substs.as_generator().prefix_tys().nth(field_index.as_usize()) { match args.as_generator().prefix_tys().nth(field_index.as_usize()) {
Some(ty) => Ok(ty), Some(ty) => Ok(ty),
None => Err(FieldAccessError::OutOfRange { None => Err(FieldAccessError::OutOfRange {
field_count: substs.as_generator().prefix_tys().count(), field_count: args.as_generator().prefix_tys().count(),
}), }),
} }
} }
@ -1821,8 +1818,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let def_id = uv.def; let def_id = uv.def;
if tcx.def_kind(def_id) == DefKind::InlineConst { if tcx.def_kind(def_id) == DefKind::InlineConst {
let def_id = def_id.expect_local(); let def_id = def_id.expect_local();
let predicates = let predicates = self.prove_closure_bounds(tcx, def_id, uv.args, location);
self.prove_closure_bounds(tcx, def_id, uv.substs, location);
self.normalize_and_prove_instantiated_predicates( self.normalize_and_prove_instantiated_predicates(
def_id.to_def_id(), def_id.to_def_id(),
predicates, predicates,
@ -1939,7 +1935,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(unsafety)) => { CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(unsafety)) => {
let sig = match op.ty(body, tcx).kind() { let sig = match op.ty(body, tcx).kind() {
ty::Closure(_, substs) => substs.as_closure().sig(), ty::Closure(_, args) => args.as_closure().sig(),
_ => bug!(), _ => bug!(),
}; };
let ty_fn_ptr_from = let ty_fn_ptr_from =
@ -2591,8 +2587,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
); );
let (def_id, instantiated_predicates) = match *aggregate_kind { let (def_id, instantiated_predicates) = match *aggregate_kind {
AggregateKind::Adt(adt_did, _, substs, _, _) => { AggregateKind::Adt(adt_did, _, args, _, _) => {
(adt_did, tcx.predicates_of(adt_did).instantiate(tcx, substs)) (adt_did, tcx.predicates_of(adt_did).instantiate(tcx, args))
} }
// For closures, we have some **extra requirements** we // For closures, we have some **extra requirements** we
@ -2614,9 +2610,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// desugaring. A closure gets desugared to a struct, and // desugaring. A closure gets desugared to a struct, and
// these extra requirements are basically like where // these extra requirements are basically like where
// clauses on the struct. // clauses on the struct.
AggregateKind::Closure(def_id, substs) AggregateKind::Closure(def_id, args) | AggregateKind::Generator(def_id, args, _) => {
| AggregateKind::Generator(def_id, substs, _) => { (def_id, self.prove_closure_bounds(tcx, def_id.expect_local(), args, location))
(def_id, self.prove_closure_bounds(tcx, def_id.expect_local(), substs, location))
} }
AggregateKind::Array(_) | AggregateKind::Tuple => { AggregateKind::Array(_) | AggregateKind::Tuple => {
@ -2635,7 +2630,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
&mut self, &mut self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
def_id: LocalDefId, def_id: LocalDefId,
substs: SubstsRef<'tcx>, args: GenericArgsRef<'tcx>,
location: Location, location: Location,
) -> ty::InstantiatedPredicates<'tcx> { ) -> ty::InstantiatedPredicates<'tcx> {
if let Some(closure_requirements) = &tcx.mir_borrowck(def_id).closure_requirements { if let Some(closure_requirements) = &tcx.mir_borrowck(def_id).closure_requirements {
@ -2653,26 +2648,26 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
.apply_closure_requirements( .apply_closure_requirements(
&closure_requirements, &closure_requirements,
def_id.to_def_id(), def_id.to_def_id(),
substs, args,
); );
} }
// Now equate closure substs to regions inherited from `typeck_root_def_id`. Fixes #98589. // Now equate closure args to regions inherited from `typeck_root_def_id`. Fixes #98589.
let typeck_root_def_id = tcx.typeck_root_def_id(self.body.source.def_id()); let typeck_root_def_id = tcx.typeck_root_def_id(self.body.source.def_id());
let typeck_root_substs = ty::InternalSubsts::identity_for_item(tcx, typeck_root_def_id); let typeck_root_args = ty::GenericArgs::identity_for_item(tcx, typeck_root_def_id);
let parent_substs = match tcx.def_kind(def_id) { let parent_args = match tcx.def_kind(def_id) {
DefKind::Closure => substs.as_closure().parent_substs(), DefKind::Closure => args.as_closure().parent_args(),
DefKind::Generator => substs.as_generator().parent_substs(), DefKind::Generator => args.as_generator().parent_args(),
DefKind::InlineConst => substs.as_inline_const().parent_substs(), DefKind::InlineConst => args.as_inline_const().parent_args(),
other => bug!("unexpected item {:?}", other), other => bug!("unexpected item {:?}", other),
}; };
let parent_substs = tcx.mk_substs(parent_substs); let parent_args = tcx.mk_args(parent_args);
assert_eq!(typeck_root_substs.len(), parent_substs.len()); assert_eq!(typeck_root_args.len(), parent_args.len());
if let Err(_) = self.eq_substs( if let Err(_) = self.eq_args(
typeck_root_substs, typeck_root_args,
parent_substs, parent_args,
location.to_locations(), location.to_locations(),
ConstraintCategory::BoringNoLocation, ConstraintCategory::BoringNoLocation,
) { ) {
@ -2680,12 +2675,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
self, self,
def_id, def_id,
"could not relate closure to parent {:?} != {:?}", "could not relate closure to parent {:?} != {:?}",
typeck_root_substs, typeck_root_args,
parent_substs parent_args
); );
} }
tcx.predicates_of(def_id).instantiate(tcx, substs) tcx.predicates_of(def_id).instantiate(tcx, args)
} }
#[instrument(skip(self, body), level = "debug")] #[instrument(skip(self, body), level = "debug")]

View File

@ -42,10 +42,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
} }
/// Add sufficient constraints to ensure `a == b`. See also [Self::relate_types]. /// Add sufficient constraints to ensure `a == b`. See also [Self::relate_types].
pub(super) fn eq_substs( pub(super) fn eq_args(
&mut self, &mut self,
a: ty::SubstsRef<'tcx>, a: ty::GenericArgsRef<'tcx>,
b: ty::SubstsRef<'tcx>, b: ty::GenericArgsRef<'tcx>,
locations: Locations, locations: Locations,
category: ConstraintCategory<'tcx>, category: ConstraintCategory<'tcx>,
) -> Result<(), NoSolution> { ) -> Result<(), NoSolution> {

View File

@ -22,8 +22,8 @@ use rustc_hir::BodyOwnerKind;
use rustc_index::IndexVec; use rustc_index::IndexVec;
use rustc_infer::infer::NllRegionVariableOrigin; use rustc_infer::infer::NllRegionVariableOrigin;
use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::{self, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt}; use rustc_middle::ty::{self, InlineConstArgs, InlineConstArgsParts, RegionVid, Ty, TyCtxt};
use rustc_middle::ty::{InternalSubsts, SubstsRef}; use rustc_middle::ty::{GenericArgs, GenericArgsRef};
use rustc_span::symbol::{kw, sym}; use rustc_span::symbol::{kw, sym};
use rustc_span::Symbol; use rustc_span::Symbol;
use std::iter; use std::iter;
@ -88,26 +88,26 @@ pub struct UniversalRegions<'tcx> {
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub enum DefiningTy<'tcx> { pub enum DefiningTy<'tcx> {
/// The MIR is a closure. The signature is found via /// The MIR is a closure. The signature is found via
/// `ClosureSubsts::closure_sig_ty`. /// `ClosureArgs::closure_sig_ty`.
Closure(DefId, SubstsRef<'tcx>), Closure(DefId, GenericArgsRef<'tcx>),
/// The MIR is a generator. The signature is that generators take /// The MIR is a generator. The signature is that generators take
/// no parameters and return the result of /// no parameters and return the result of
/// `ClosureSubsts::generator_return_ty`. /// `ClosureArgs::generator_return_ty`.
Generator(DefId, SubstsRef<'tcx>, hir::Movability), Generator(DefId, GenericArgsRef<'tcx>, hir::Movability),
/// The MIR is a fn item with the given `DefId` and substs. The signature /// The MIR is a fn item with the given `DefId` and args. The signature
/// of the function can be bound then with the `fn_sig` query. /// of the function can be bound then with the `fn_sig` query.
FnDef(DefId, SubstsRef<'tcx>), FnDef(DefId, GenericArgsRef<'tcx>),
/// The MIR represents some form of constant. The signature then /// The MIR represents some form of constant. The signature then
/// is that it has no inputs and a single return value, which is /// is that it has no inputs and a single return value, which is
/// the value of the constant. /// the value of the constant.
Const(DefId, SubstsRef<'tcx>), Const(DefId, GenericArgsRef<'tcx>),
/// The MIR represents an inline const. The signature has no inputs and a /// The MIR represents an inline const. The signature has no inputs and a
/// single return value found via `InlineConstSubsts::ty`. /// single return value found via `InlineConstArgs::ty`.
InlineConst(DefId, SubstsRef<'tcx>), InlineConst(DefId, GenericArgsRef<'tcx>),
} }
impl<'tcx> DefiningTy<'tcx> { impl<'tcx> DefiningTy<'tcx> {
@ -117,9 +117,9 @@ impl<'tcx> DefiningTy<'tcx> {
/// match up with the upvar order in the HIR, typesystem, and MIR. /// match up with the upvar order in the HIR, typesystem, and MIR.
pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx { pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
match self { match self {
DefiningTy::Closure(_, substs) => Either::Left(substs.as_closure().upvar_tys()), DefiningTy::Closure(_, args) => Either::Left(args.as_closure().upvar_tys()),
DefiningTy::Generator(_, substs, _) => { DefiningTy::Generator(_, args, _) => {
Either::Right(Either::Left(substs.as_generator().upvar_tys())) Either::Right(Either::Left(args.as_generator().upvar_tys()))
} }
DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => { DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => {
Either::Right(Either::Right(iter::empty())) Either::Right(Either::Right(iter::empty()))
@ -164,9 +164,9 @@ struct UniversalRegionIndices<'tcx> {
/// used because trait matching and type-checking will feed us /// used because trait matching and type-checking will feed us
/// region constraints that reference those regions and we need to /// region constraints that reference those regions and we need to
/// be able to map them to our internal `RegionVid`. This is /// be able to map them to our internal `RegionVid`. This is
/// basically equivalent to an `InternalSubsts`, except that it also /// basically equivalent to an `GenericArgs`, except that it also
/// contains an entry for `ReStatic` -- it might be nice to just /// contains an entry for `ReStatic` -- it might be nice to just
/// use a substs, and then handle `ReStatic` another way. /// use a args, and then handle `ReStatic` another way.
indices: FxHashMap<ty::Region<'tcx>, RegionVid>, indices: FxHashMap<ty::Region<'tcx>, RegionVid>,
/// The vid assigned to `'static`. Used only for diagnostics. /// The vid assigned to `'static`. Used only for diagnostics.
@ -243,13 +243,13 @@ impl<'tcx> UniversalRegions<'tcx> {
/// `V[1]: V[2]`. /// `V[1]: V[2]`.
pub fn closure_mapping( pub fn closure_mapping(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
closure_substs: SubstsRef<'tcx>, closure_args: GenericArgsRef<'tcx>,
expected_num_vars: usize, expected_num_vars: usize,
closure_def_id: LocalDefId, closure_def_id: LocalDefId,
) -> IndexVec<RegionVid, ty::Region<'tcx>> { ) -> IndexVec<RegionVid, ty::Region<'tcx>> {
let mut region_mapping = IndexVec::with_capacity(expected_num_vars); let mut region_mapping = IndexVec::with_capacity(expected_num_vars);
region_mapping.push(tcx.lifetimes.re_static); region_mapping.push(tcx.lifetimes.re_static);
tcx.for_each_free_region(&closure_substs, |fr| { tcx.for_each_free_region(&closure_args, |fr| {
region_mapping.push(fr); region_mapping.push(fr);
}); });
@ -334,11 +334,11 @@ impl<'tcx> UniversalRegions<'tcx> {
/// state. /// state.
pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) { pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) {
match self.defining_ty { match self.defining_ty {
DefiningTy::Closure(def_id, substs) => { DefiningTy::Closure(def_id, args) => {
err.note(format!( err.note(format!(
"defining type: {} with closure substs {:#?}", "defining type: {} with closure args {:#?}",
tcx.def_path_str_with_substs(def_id, substs), tcx.def_path_str_with_args(def_id, args),
&substs[tcx.generics_of(def_id).parent_count..], &args[tcx.generics_of(def_id).parent_count..],
)); ));
// FIXME: It'd be nice to print the late-bound regions // FIXME: It'd be nice to print the late-bound regions
@ -350,11 +350,11 @@ impl<'tcx> UniversalRegions<'tcx> {
err.note(format!("late-bound region is {:?}", self.to_region_vid(r))); err.note(format!("late-bound region is {:?}", self.to_region_vid(r)));
}); });
} }
DefiningTy::Generator(def_id, substs, _) => { DefiningTy::Generator(def_id, args, _) => {
err.note(format!( err.note(format!(
"defining type: {} with generator substs {:#?}", "defining type: {} with generator args {:#?}",
tcx.def_path_str_with_substs(def_id, substs), tcx.def_path_str_with_args(def_id, args),
&substs[tcx.generics_of(def_id).parent_count..], &args[tcx.generics_of(def_id).parent_count..],
)); ));
// FIXME: As above, we'd like to print out the region // FIXME: As above, we'd like to print out the region
@ -364,22 +364,19 @@ impl<'tcx> UniversalRegions<'tcx> {
err.note(format!("late-bound region is {:?}", self.to_region_vid(r))); err.note(format!("late-bound region is {:?}", self.to_region_vid(r)));
}); });
} }
DefiningTy::FnDef(def_id, substs) => { DefiningTy::FnDef(def_id, args) => {
err.note(format!( err.note(format!("defining type: {}", tcx.def_path_str_with_args(def_id, args),));
"defining type: {}",
tcx.def_path_str_with_substs(def_id, substs),
));
} }
DefiningTy::Const(def_id, substs) => { DefiningTy::Const(def_id, args) => {
err.note(format!( err.note(format!(
"defining constant type: {}", "defining constant type: {}",
tcx.def_path_str_with_substs(def_id, substs), tcx.def_path_str_with_args(def_id, args),
)); ));
} }
DefiningTy::InlineConst(def_id, substs) => { DefiningTy::InlineConst(def_id, args) => {
err.note(format!( err.note(format!(
"defining inline constant type: {}", "defining inline constant type: {}",
tcx.def_path_str_with_substs(def_id, substs), tcx.def_path_str_with_args(def_id, args),
)); ));
} }
} }
@ -501,8 +498,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
.as_var(); .as_var();
let region = ty::Region::new_var(self.infcx.tcx, reg_vid); let region = ty::Region::new_var(self.infcx.tcx, reg_vid);
let va_list_ty = let va_list_ty = self
self.infcx.tcx.type_of(va_list_did).subst(self.infcx.tcx, &[region.into()]); .infcx
.tcx
.type_of(va_list_did)
.instantiate(self.infcx.tcx, &[region.into()]);
unnormalized_input_tys = self.infcx.tcx.mk_type_list_from_iter( unnormalized_input_tys = self.infcx.tcx.mk_type_list_from_iter(
unnormalized_input_tys.iter().copied().chain(iter::once(va_list_ty)), unnormalized_input_tys.iter().copied().chain(iter::once(va_list_ty)),
@ -522,7 +522,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
debug!("build: local regions = {}..{}", first_local_index, num_universals); debug!("build: local regions = {}..{}", first_local_index, num_universals);
let yield_ty = match defining_ty { let yield_ty = match defining_ty {
DefiningTy::Generator(_, substs, _) => Some(substs.as_generator().yield_ty()), DefiningTy::Generator(_, args, _) => Some(args.as_generator().yield_ty()),
_ => None, _ => None,
}; };
@ -548,7 +548,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
match tcx.hir().body_owner_kind(self.mir_def) { match tcx.hir().body_owner_kind(self.mir_def) {
BodyOwnerKind::Closure | BodyOwnerKind::Fn => { BodyOwnerKind::Closure | BodyOwnerKind::Fn => {
let defining_ty = tcx.type_of(self.mir_def).subst_identity(); let defining_ty = tcx.type_of(self.mir_def).instantiate_identity();
debug!("defining_ty (pre-replacement): {:?}", defining_ty); debug!("defining_ty (pre-replacement): {:?}", defining_ty);
@ -556,11 +556,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
self.infcx.replace_free_regions_with_nll_infer_vars(FR, defining_ty); self.infcx.replace_free_regions_with_nll_infer_vars(FR, defining_ty);
match *defining_ty.kind() { match *defining_ty.kind() {
ty::Closure(def_id, substs) => DefiningTy::Closure(def_id, substs), ty::Closure(def_id, args) => DefiningTy::Closure(def_id, args),
ty::Generator(def_id, substs, movability) => { ty::Generator(def_id, args, movability) => {
DefiningTy::Generator(def_id, substs, movability) DefiningTy::Generator(def_id, args, movability)
} }
ty::FnDef(def_id, substs) => DefiningTy::FnDef(def_id, substs), ty::FnDef(def_id, args) => DefiningTy::FnDef(def_id, args),
_ => span_bug!( _ => span_bug!(
tcx.def_span(self.mir_def), tcx.def_span(self.mir_def),
"expected defining type for `{:?}`: `{:?}`", "expected defining type for `{:?}`: `{:?}`",
@ -571,11 +571,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
} }
BodyOwnerKind::Const | BodyOwnerKind::Static(..) => { BodyOwnerKind::Const | BodyOwnerKind::Static(..) => {
let identity_substs = InternalSubsts::identity_for_item(tcx, typeck_root_def_id); let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id);
if self.mir_def.to_def_id() == typeck_root_def_id { if self.mir_def.to_def_id() == typeck_root_def_id {
let substs = let args =
self.infcx.replace_free_regions_with_nll_infer_vars(FR, identity_substs); self.infcx.replace_free_regions_with_nll_infer_vars(FR, identity_args);
DefiningTy::Const(self.mir_def.to_def_id(), substs) DefiningTy::Const(self.mir_def.to_def_id(), args)
} else { } else {
// FIXME this line creates a dependency between borrowck and typeck. // FIXME this line creates a dependency between borrowck and typeck.
// //
@ -584,18 +584,18 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
// into borrowck, which is ICE #78174. // into borrowck, which is ICE #78174.
// //
// As a workaround, inline consts have an additional generic param (`ty` // As a workaround, inline consts have an additional generic param (`ty`
// below), so that `type_of(inline_const_def_id).substs(substs)` uses the // below), so that `type_of(inline_const_def_id).args(args)` uses the
// proper type with NLL infer vars. // proper type with NLL infer vars.
let ty = tcx let ty = tcx
.typeck(self.mir_def) .typeck(self.mir_def)
.node_type(tcx.local_def_id_to_hir_id(self.mir_def)); .node_type(tcx.local_def_id_to_hir_id(self.mir_def));
let substs = InlineConstSubsts::new( let args = InlineConstArgs::new(
tcx, tcx,
InlineConstSubstsParts { parent_substs: identity_substs, ty }, InlineConstArgsParts { parent_args: identity_args, ty },
) )
.substs; .args;
let substs = self.infcx.replace_free_regions_with_nll_infer_vars(FR, substs); let args = self.infcx.replace_free_regions_with_nll_infer_vars(FR, args);
DefiningTy::InlineConst(self.mir_def.to_def_id(), substs) DefiningTy::InlineConst(self.mir_def.to_def_id(), args)
} }
} }
} }
@ -612,29 +612,29 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
) -> UniversalRegionIndices<'tcx> { ) -> UniversalRegionIndices<'tcx> {
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id()); let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id());
let identity_substs = InternalSubsts::identity_for_item(tcx, typeck_root_def_id); let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id);
let fr_substs = match defining_ty { let fr_args = match defining_ty {
DefiningTy::Closure(_, substs) DefiningTy::Closure(_, args)
| DefiningTy::Generator(_, substs, _) | DefiningTy::Generator(_, args, _)
| DefiningTy::InlineConst(_, substs) => { | DefiningTy::InlineConst(_, args) => {
// In the case of closures, we rely on the fact that // In the case of closures, we rely on the fact that
// the first N elements in the ClosureSubsts are // the first N elements in the ClosureArgs are
// inherited from the `typeck_root_def_id`. // inherited from the `typeck_root_def_id`.
// Therefore, when we zip together (below) with // Therefore, when we zip together (below) with
// `identity_substs`, we will get only those regions // `identity_args`, we will get only those regions
// that correspond to early-bound regions declared on // that correspond to early-bound regions declared on
// the `typeck_root_def_id`. // the `typeck_root_def_id`.
assert!(substs.len() >= identity_substs.len()); assert!(args.len() >= identity_args.len());
assert_eq!(substs.regions().count(), identity_substs.regions().count()); assert_eq!(args.regions().count(), identity_args.regions().count());
substs args
} }
DefiningTy::FnDef(_, substs) | DefiningTy::Const(_, substs) => substs, DefiningTy::FnDef(_, args) | DefiningTy::Const(_, args) => args,
}; };
let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static)); let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static));
let subst_mapping = let subst_mapping =
iter::zip(identity_substs.regions(), fr_substs.regions().map(|r| r.as_var())); iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var()));
UniversalRegionIndices { indices: global_mapping.chain(subst_mapping).collect(), fr_static } UniversalRegionIndices { indices: global_mapping.chain(subst_mapping).collect(), fr_static }
} }
@ -646,9 +646,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
) -> ty::Binder<'tcx, &'tcx ty::List<Ty<'tcx>>> { ) -> ty::Binder<'tcx, &'tcx ty::List<Ty<'tcx>>> {
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
match defining_ty { match defining_ty {
DefiningTy::Closure(def_id, substs) => { DefiningTy::Closure(def_id, args) => {
assert_eq!(self.mir_def.to_def_id(), def_id); assert_eq!(self.mir_def.to_def_id(), def_id);
let closure_sig = substs.as_closure().sig(); let closure_sig = args.as_closure().sig();
let inputs_and_output = closure_sig.inputs_and_output(); let inputs_and_output = closure_sig.inputs_and_output();
let bound_vars = tcx.mk_bound_variable_kinds_from_iter( let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
inputs_and_output inputs_and_output
@ -661,7 +661,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
kind: ty::BrEnv, kind: ty::BrEnv,
}; };
let env_region = ty::Region::new_late_bound(tcx, ty::INNERMOST, br); let env_region = ty::Region::new_late_bound(tcx, ty::INNERMOST, br);
let closure_ty = tcx.closure_env_ty(def_id, substs, env_region).unwrap(); let closure_ty = tcx.closure_env_ty(def_id, args, env_region).unwrap();
// The "inputs" of the closure in the // The "inputs" of the closure in the
// signature appear as a tuple. The MIR side // signature appear as a tuple. The MIR side
@ -681,18 +681,18 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
) )
} }
DefiningTy::Generator(def_id, substs, movability) => { DefiningTy::Generator(def_id, args, movability) => {
assert_eq!(self.mir_def.to_def_id(), def_id); assert_eq!(self.mir_def.to_def_id(), def_id);
let resume_ty = substs.as_generator().resume_ty(); let resume_ty = args.as_generator().resume_ty();
let output = substs.as_generator().return_ty(); let output = args.as_generator().return_ty();
let generator_ty = Ty::new_generator(tcx, def_id, substs, movability); let generator_ty = Ty::new_generator(tcx, def_id, args, movability);
let inputs_and_output = let inputs_and_output =
self.infcx.tcx.mk_type_list(&[generator_ty, resume_ty, output]); self.infcx.tcx.mk_type_list(&[generator_ty, resume_ty, output]);
ty::Binder::dummy(inputs_and_output) ty::Binder::dummy(inputs_and_output)
} }
DefiningTy::FnDef(def_id, _) => { DefiningTy::FnDef(def_id, _) => {
let sig = tcx.fn_sig(def_id).subst_identity(); let sig = tcx.fn_sig(def_id).instantiate_identity();
let sig = indices.fold_to_region_vids(tcx, sig); let sig = indices.fold_to_region_vids(tcx, sig);
sig.inputs_and_output() sig.inputs_and_output()
} }
@ -701,14 +701,14 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
// For a constant body, there are no inputs, and one // For a constant body, there are no inputs, and one
// "output" (the type of the constant). // "output" (the type of the constant).
assert_eq!(self.mir_def.to_def_id(), def_id); assert_eq!(self.mir_def.to_def_id(), def_id);
let ty = tcx.type_of(self.mir_def).subst_identity(); let ty = tcx.type_of(self.mir_def).instantiate_identity();
let ty = indices.fold_to_region_vids(tcx, ty); let ty = indices.fold_to_region_vids(tcx, ty);
ty::Binder::dummy(tcx.mk_type_list(&[ty])) ty::Binder::dummy(tcx.mk_type_list(&[ty]))
} }
DefiningTy::InlineConst(def_id, substs) => { DefiningTy::InlineConst(def_id, args) => {
assert_eq!(self.mir_def.to_def_id(), def_id); assert_eq!(self.mir_def.to_def_id(), def_id);
let ty = substs.as_inline_const().ty(); let ty = args.as_inline_const().ty();
ty::Binder::dummy(tcx.mk_type_list(&[ty])) ty::Binder::dummy(tcx.mk_type_list(&[ty]))
} }
} }

View File

@ -70,7 +70,7 @@ pub(crate) fn get_function_sig<'tcx>(
default_call_conv: CallConv, default_call_conv: CallConv,
inst: Instance<'tcx>, inst: Instance<'tcx>,
) -> Signature { ) -> Signature {
assert!(!inst.substs.has_infer()); assert!(!inst.args.has_infer());
clif_sig_from_fn_abi( clif_sig_from_fn_abi(
tcx, tcx,
default_call_conv, default_call_conv,
@ -377,16 +377,16 @@ pub(crate) fn codegen_terminator_call<'tcx>(
let ret_place = codegen_place(fx, destination); let ret_place = codegen_place(fx, destination);
// Handle special calls like intrinsics and empty drop glue. // Handle special calls like intrinsics and empty drop glue.
let instance = if let ty::FnDef(def_id, substs) = *func.layout().ty.kind() { let instance = if let ty::FnDef(def_id, fn_args) = *func.layout().ty.kind() {
let instance = let instance =
ty::Instance::expect_resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, substs) ty::Instance::expect_resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, fn_args)
.polymorphize(fx.tcx); .polymorphize(fx.tcx);
if fx.tcx.symbol_name(instance).name.starts_with("llvm.") { if fx.tcx.symbol_name(instance).name.starts_with("llvm.") {
crate::intrinsics::codegen_llvm_intrinsic_call( crate::intrinsics::codegen_llvm_intrinsic_call(
fx, fx,
&fx.tcx.symbol_name(instance).name, &fx.tcx.symbol_name(instance).name,
substs, fn_args,
args, args,
ret_place, ret_place,
target, target,
@ -611,7 +611,7 @@ pub(crate) fn codegen_drop<'tcx>(
// `Instance::resolve_drop_in_place`? // `Instance::resolve_drop_in_place`?
let virtual_drop = Instance { let virtual_drop = Instance {
def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0), def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0),
substs: drop_instance.substs, args: drop_instance.args,
}; };
let fn_abi = let fn_abi =
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, ty::List::empty()); RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, ty::List::empty());
@ -648,7 +648,7 @@ pub(crate) fn codegen_drop<'tcx>(
let virtual_drop = Instance { let virtual_drop = Instance {
def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0), def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0),
substs: drop_instance.substs, args: drop_instance.args,
}; };
let fn_abi = let fn_abi =
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, ty::List::empty()); RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, ty::List::empty());

View File

@ -28,7 +28,7 @@ pub(crate) fn codegen_fn<'tcx>(
module: &mut dyn Module, module: &mut dyn Module,
instance: Instance<'tcx>, instance: Instance<'tcx>,
) -> CodegenedFunction { ) -> CodegenedFunction {
debug_assert!(!instance.substs.has_infer()); debug_assert!(!instance.args.has_infer());
let symbol_name = tcx.symbol_name(instance).name.to_string(); let symbol_name = tcx.symbol_name(instance).name.to_string();
let _timer = tcx.prof.generic_activity_with_arg("codegen fn", &*symbol_name); let _timer = tcx.prof.generic_activity_with_arg("codegen fn", &*symbol_name);
@ -578,13 +578,13 @@ fn codegen_stmt<'tcx>(
let from_ty = fx.monomorphize(operand.ty(&fx.mir.local_decls, fx.tcx)); let from_ty = fx.monomorphize(operand.ty(&fx.mir.local_decls, fx.tcx));
let to_layout = fx.layout_of(fx.monomorphize(to_ty)); let to_layout = fx.layout_of(fx.monomorphize(to_ty));
match *from_ty.kind() { match *from_ty.kind() {
ty::FnDef(def_id, substs) => { ty::FnDef(def_id, args) => {
let func_ref = fx.get_function_ref( let func_ref = fx.get_function_ref(
Instance::resolve_for_fn_ptr( Instance::resolve_for_fn_ptr(
fx.tcx, fx.tcx,
ParamEnv::reveal_all(), ParamEnv::reveal_all(),
def_id, def_id,
substs, args,
) )
.unwrap() .unwrap()
.polymorphize(fx.tcx), .polymorphize(fx.tcx),
@ -668,11 +668,11 @@ fn codegen_stmt<'tcx>(
) => { ) => {
let operand = codegen_operand(fx, operand); let operand = codegen_operand(fx, operand);
match *operand.layout().ty.kind() { match *operand.layout().ty.kind() {
ty::Closure(def_id, substs) => { ty::Closure(def_id, args) => {
let instance = Instance::resolve_closure( let instance = Instance::resolve_closure(
fx.tcx, fx.tcx,
def_id, def_id,
substs, args,
ty::ClosureKind::FnOnce, ty::ClosureKind::FnOnce,
) )
.expect("failed to normalize and resolve closure during codegen") .expect("failed to normalize and resolve closure during codegen")

View File

@ -57,7 +57,7 @@ pub(crate) fn codegen_tls_ref<'tcx>(
let tls_ptr = if !def_id.is_local() && fx.tcx.needs_thread_local_shim(def_id) { let tls_ptr = if !def_id.is_local() && fx.tcx.needs_thread_local_shim(def_id) {
let instance = ty::Instance { let instance = ty::Instance {
def: ty::InstanceDef::ThreadLocalShim(def_id), def: ty::InstanceDef::ThreadLocalShim(def_id),
substs: ty::InternalSubsts::empty(), args: ty::GenericArgs::empty(),
}; };
let func_ref = fx.get_function_ref(instance); let func_ref = fx.get_function_ref(instance);
let call = fx.bcx.ins().call(func_ref, &[]); let call = fx.bcx.ins().call(func_ref, &[]);

View File

@ -42,7 +42,7 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
InlineAsmOperand::SymFn { anon_const } => { InlineAsmOperand::SymFn { anon_const } => {
let ty = tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id); let ty = tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id);
let instance = match ty.kind() { let instance = match ty.kind() {
&ty::FnDef(def_id, substs) => Instance::new(def_id, substs), &ty::FnDef(def_id, args) => Instance::new(def_id, args),
_ => span_bug!(op_sp, "asm sym is not a function"), _ => span_bug!(op_sp, "asm sym is not a function"),
}; };
let symbol = tcx.symbol_name(instance); let symbol = tcx.symbol_name(instance);

View File

@ -254,12 +254,12 @@ pub(crate) fn codegen_inline_asm<'tcx>(
} }
InlineAsmOperand::SymFn { ref value } => { InlineAsmOperand::SymFn { ref value } => {
let literal = fx.monomorphize(value.literal); let literal = fx.monomorphize(value.literal);
if let ty::FnDef(def_id, substs) = *literal.ty().kind() { if let ty::FnDef(def_id, args) = *literal.ty().kind() {
let instance = ty::Instance::resolve_for_fn_ptr( let instance = ty::Instance::resolve_for_fn_ptr(
fx.tcx, fx.tcx,
ty::ParamEnv::reveal_all(), ty::ParamEnv::reveal_all(),
def_id, def_id,
substs, args,
) )
.unwrap(); .unwrap();
let symbol = fx.tcx.symbol_name(instance); let symbol = fx.tcx.symbol_name(instance);

View File

@ -3,23 +3,35 @@
use crate::intrinsics::*; use crate::intrinsics::*;
use crate::prelude::*; use crate::prelude::*;
use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::GenericArgsRef;
pub(crate) fn codegen_llvm_intrinsic_call<'tcx>( pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>, fx: &mut FunctionCx<'_, '_, 'tcx>,
intrinsic: &str, intrinsic: &str,
substs: SubstsRef<'tcx>, generic_args: GenericArgsRef<'tcx>,
args: &[mir::Operand<'tcx>], args: &[mir::Operand<'tcx>],
ret: CPlace<'tcx>, ret: CPlace<'tcx>,
target: Option<BasicBlock>, target: Option<BasicBlock>,
) { ) {
if intrinsic.starts_with("llvm.aarch64") { if intrinsic.starts_with("llvm.aarch64") {
return llvm_aarch64::codegen_aarch64_llvm_intrinsic_call( return llvm_aarch64::codegen_aarch64_llvm_intrinsic_call(
fx, intrinsic, substs, args, ret, target, fx,
intrinsic,
generic_args,
args,
ret,
target,
); );
} }
if intrinsic.starts_with("llvm.x86") { if intrinsic.starts_with("llvm.x86") {
return llvm_x86::codegen_x86_llvm_intrinsic_call(fx, intrinsic, substs, args, ret, target); return llvm_x86::codegen_x86_llvm_intrinsic_call(
fx,
intrinsic,
generic_args,
args,
ret,
target,
);
} }
match intrinsic { match intrinsic {

View File

@ -3,12 +3,12 @@
use crate::intrinsics::*; use crate::intrinsics::*;
use crate::prelude::*; use crate::prelude::*;
use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::GenericArgsRef;
pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>( pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>, fx: &mut FunctionCx<'_, '_, 'tcx>,
intrinsic: &str, intrinsic: &str,
_substs: SubstsRef<'tcx>, _args: GenericArgsRef<'tcx>,
args: &[mir::Operand<'tcx>], args: &[mir::Operand<'tcx>],
ret: CPlace<'tcx>, ret: CPlace<'tcx>,
target: Option<BasicBlock>, target: Option<BasicBlock>,

View File

@ -3,12 +3,12 @@
use crate::intrinsics::*; use crate::intrinsics::*;
use crate::prelude::*; use crate::prelude::*;
use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::GenericArgsRef;
pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>, fx: &mut FunctionCx<'_, '_, 'tcx>,
intrinsic: &str, intrinsic: &str,
_substs: SubstsRef<'tcx>, _args: GenericArgsRef<'tcx>,
args: &[mir::Operand<'tcx>], args: &[mir::Operand<'tcx>],
ret: CPlace<'tcx>, ret: CPlace<'tcx>,
target: Option<BasicBlock>, target: Option<BasicBlock>,

View File

@ -24,7 +24,7 @@ pub(crate) use llvm::codegen_llvm_intrinsic_call;
use rustc_middle::ty; use rustc_middle::ty;
use rustc_middle::ty::layout::{HasParamEnv, ValidityRequirement}; use rustc_middle::ty::layout::{HasParamEnv, ValidityRequirement};
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::GenericArgsRef;
use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::symbol::{kw, sym, Symbol};
use crate::prelude::*; use crate::prelude::*;
@ -213,13 +213,13 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
source_info: mir::SourceInfo, source_info: mir::SourceInfo,
) { ) {
let intrinsic = fx.tcx.item_name(instance.def_id()); let intrinsic = fx.tcx.item_name(instance.def_id());
let substs = instance.substs; let instance_args = instance.args;
if intrinsic.as_str().starts_with("simd_") { if intrinsic.as_str().starts_with("simd_") {
self::simd::codegen_simd_intrinsic_call( self::simd::codegen_simd_intrinsic_call(
fx, fx,
intrinsic, intrinsic,
substs, instance_args,
args, args,
destination, destination,
target.expect("target for simd intrinsic"), target.expect("target for simd intrinsic"),
@ -233,7 +233,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
fx, fx,
instance, instance,
intrinsic, intrinsic,
substs, instance_args,
args, args,
destination, destination,
target, target,
@ -365,7 +365,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>, fx: &mut FunctionCx<'_, '_, 'tcx>,
instance: Instance<'tcx>, instance: Instance<'tcx>,
intrinsic: Symbol, intrinsic: Symbol,
substs: SubstsRef<'tcx>, generic_args: GenericArgsRef<'tcx>,
args: &[mir::Operand<'tcx>], args: &[mir::Operand<'tcx>],
ret: CPlace<'tcx>, ret: CPlace<'tcx>,
destination: Option<BasicBlock>, destination: Option<BasicBlock>,
@ -394,7 +394,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
let dst = dst.load_scalar(fx); let dst = dst.load_scalar(fx);
let count = count.load_scalar(fx); let count = count.load_scalar(fx);
let elem_ty = substs.type_at(0); let elem_ty = generic_args.type_at(0);
let elem_size: u64 = fx.layout_of(elem_ty).size.bytes(); let elem_size: u64 = fx.layout_of(elem_ty).size.bytes();
assert_eq!(args.len(), 3); assert_eq!(args.len(), 3);
let byte_amount = let byte_amount =
@ -410,7 +410,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
let src = src.load_scalar(fx); let src = src.load_scalar(fx);
let count = count.load_scalar(fx); let count = count.load_scalar(fx);
let elem_ty = substs.type_at(0); let elem_ty = generic_args.type_at(0);
let elem_size: u64 = fx.layout_of(elem_ty).size.bytes(); let elem_size: u64 = fx.layout_of(elem_ty).size.bytes();
assert_eq!(args.len(), 3); assert_eq!(args.len(), 3);
let byte_amount = let byte_amount =
@ -428,7 +428,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
sym::size_of_val => { sym::size_of_val => {
intrinsic_args!(fx, args => (ptr); intrinsic); intrinsic_args!(fx, args => (ptr); intrinsic);
let layout = fx.layout_of(substs.type_at(0)); let layout = fx.layout_of(generic_args.type_at(0));
// Note: Can't use is_unsized here as truly unsized types need to take the fixed size // Note: Can't use is_unsized here as truly unsized types need to take the fixed size
// branch // branch
let size = if let Abi::ScalarPair(_, _) = ptr.layout().abi { let size = if let Abi::ScalarPair(_, _) = ptr.layout().abi {
@ -443,7 +443,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
sym::min_align_of_val => { sym::min_align_of_val => {
intrinsic_args!(fx, args => (ptr); intrinsic); intrinsic_args!(fx, args => (ptr); intrinsic);
let layout = fx.layout_of(substs.type_at(0)); let layout = fx.layout_of(generic_args.type_at(0));
// Note: Can't use is_unsized here as truly unsized types need to take the fixed size // Note: Can't use is_unsized here as truly unsized types need to take the fixed size
// branch // branch
let align = if let Abi::ScalarPair(_, _) = ptr.layout().abi { let align = if let Abi::ScalarPair(_, _) = ptr.layout().abi {
@ -602,7 +602,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
sym::assert_inhabited | sym::assert_zero_valid | sym::assert_mem_uninitialized_valid => { sym::assert_inhabited | sym::assert_zero_valid | sym::assert_mem_uninitialized_valid => {
intrinsic_args!(fx, args => (); intrinsic); intrinsic_args!(fx, args => (); intrinsic);
let ty = substs.type_at(0); let ty = generic_args.type_at(0);
let requirement = ValidityRequirement::from_intrinsic(intrinsic); let requirement = ValidityRequirement::from_intrinsic(intrinsic);
@ -674,7 +674,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
intrinsic_args!(fx, args => (ptr, base); intrinsic); intrinsic_args!(fx, args => (ptr, base); intrinsic);
let ptr = ptr.load_scalar(fx); let ptr = ptr.load_scalar(fx);
let base = base.load_scalar(fx); let base = base.load_scalar(fx);
let ty = substs.type_at(0); let ty = generic_args.type_at(0);
let pointee_size: u64 = fx.layout_of(ty).size.bytes(); let pointee_size: u64 = fx.layout_of(ty).size.bytes();
let diff_bytes = fx.bcx.ins().isub(ptr, base); let diff_bytes = fx.bcx.ins().isub(ptr, base);
@ -720,7 +720,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
intrinsic_args!(fx, args => (ptr); intrinsic); intrinsic_args!(fx, args => (ptr); intrinsic);
let ptr = ptr.load_scalar(fx); let ptr = ptr.load_scalar(fx);
let ty = substs.type_at(0); let ty = generic_args.type_at(0);
match ty.kind() { match ty.kind() {
ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => {
// FIXME implement 128bit atomics // FIXME implement 128bit atomics
@ -751,7 +751,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
intrinsic_args!(fx, args => (ptr, val); intrinsic); intrinsic_args!(fx, args => (ptr, val); intrinsic);
let ptr = ptr.load_scalar(fx); let ptr = ptr.load_scalar(fx);
let ty = substs.type_at(0); let ty = generic_args.type_at(0);
match ty.kind() { match ty.kind() {
ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => {
// FIXME implement 128bit atomics // FIXME implement 128bit atomics
@ -1128,7 +1128,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
let lhs_ref = lhs_ref.load_scalar(fx); let lhs_ref = lhs_ref.load_scalar(fx);
let rhs_ref = rhs_ref.load_scalar(fx); let rhs_ref = rhs_ref.load_scalar(fx);
let size = fx.layout_of(substs.type_at(0)).layout.size(); let size = fx.layout_of(generic_args.type_at(0)).layout.size();
// FIXME add and use emit_small_memcmp // FIXME add and use emit_small_memcmp
let is_eq_value = if size == Size::ZERO { let is_eq_value = if size == Size::ZERO {
// No bytes means they're trivially equal // No bytes means they're trivially equal

View File

@ -1,6 +1,6 @@
//! Codegen `extern "platform-intrinsic"` intrinsics. //! Codegen `extern "platform-intrinsic"` intrinsics.
use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::GenericArgsRef;
use rustc_span::Symbol; use rustc_span::Symbol;
use rustc_target::abi::Endian; use rustc_target::abi::Endian;
@ -21,7 +21,7 @@ fn report_simd_type_validation_error(
pub(super) fn codegen_simd_intrinsic_call<'tcx>( pub(super) fn codegen_simd_intrinsic_call<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>, fx: &mut FunctionCx<'_, '_, 'tcx>,
intrinsic: Symbol, intrinsic: Symbol,
_substs: SubstsRef<'tcx>, _args: GenericArgsRef<'tcx>,
args: &[mir::Operand<'tcx>], args: &[mir::Operand<'tcx>],
ret: CPlace<'tcx>, ret: CPlace<'tcx>,
target: BasicBlock, target: BasicBlock,

View File

@ -1,6 +1,6 @@
use rustc_hir::LangItem; use rustc_hir::LangItem;
use rustc_middle::ty::subst::GenericArg;
use rustc_middle::ty::AssocKind; use rustc_middle::ty::AssocKind;
use rustc_middle::ty::GenericArg;
use rustc_session::config::{sigpipe, EntryFnType}; use rustc_session::config::{sigpipe, EntryFnType};
use rustc_span::symbol::Ident; use rustc_span::symbol::Ident;
@ -119,7 +119,7 @@ pub(crate) fn maybe_create_entry_wrapper(
tcx, tcx,
ParamEnv::reveal_all(), ParamEnv::reveal_all(),
report.def_id, report.def_id,
tcx.mk_substs(&[GenericArg::from(main_ret_ty)]), tcx.mk_args(&[GenericArg::from(main_ret_ty)]),
) )
.unwrap() .unwrap()
.unwrap() .unwrap()
@ -146,7 +146,7 @@ pub(crate) fn maybe_create_entry_wrapper(
tcx, tcx,
ParamEnv::reveal_all(), ParamEnv::reveal_all(),
start_def_id, start_def_id,
tcx.mk_substs(&[main_ret_ty.into()]), tcx.mk_args(&[main_ret_ty.into()]),
) )
.unwrap() .unwrap()
.unwrap() .unwrap()

View File

@ -9,7 +9,7 @@
//! //!
//! function u0:22(i64) -> i8, i8 system_v { //! function u0:22(i64) -> i8, i8 system_v {
//! ; symbol _ZN97_$LT$example..IsNotEmpty$u20$as$u20$mini_core..FnOnce$LT$$LP$$RF$$RF$$u5b$u16$u5d$$C$$RP$$GT$$GT$9call_once17hd517c453d67c0915E //! ; symbol _ZN97_$LT$example..IsNotEmpty$u20$as$u20$mini_core..FnOnce$LT$$LP$$RF$$RF$$u5b$u16$u5d$$C$$RP$$GT$$GT$9call_once17hd517c453d67c0915E
//! ; instance Instance { def: Item(WithOptConstParam { did: DefId(0:42 ~ example[4e51]::{impl#0}::call_once), const_param_did: None }), substs: [ReErased, ReErased] } //! ; instance Instance { def: Item(WithOptConstParam { did: DefId(0:42 ~ example[4e51]::{impl#0}::call_once), const_param_did: None }), args: [ReErased, ReErased] }
//! ; abi FnAbi { args: [ArgAbi { layout: TyAndLayout { ty: IsNotEmpty, layout: Layout { size: Size(0 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, abi: Aggregate { sized: true }, fields: Arbitrary { offsets: [], memory_index: [] }, largest_niche: None, variants: Single { index: 0 } } }, mode: Ignore }, ArgAbi { layout: TyAndLayout { ty: &&[u16], layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), variants: Single { index: 0 } } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(8 bytes)) }) }], ret: ArgAbi { layout: TyAndLayout { ty: (u8, u8), layout: Layout { size: Size(2 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, abi: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=255 }, Initialized { value: Int(I8, false), valid_range: 0..=255 }), fields: Arbitrary { offsets: [Size(0 bytes), Size(1 bytes)], memory_index: [0, 1] }, largest_niche: None, variants: Single { index: 0 } } }, mode: Pair(ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }, ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }) }, c_variadic: false, fixed_count: 1, conv: Rust, can_unwind: false } //! ; abi FnAbi { args: [ArgAbi { layout: TyAndLayout { ty: IsNotEmpty, layout: Layout { size: Size(0 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, abi: Aggregate { sized: true }, fields: Arbitrary { offsets: [], memory_index: [] }, largest_niche: None, variants: Single { index: 0 } } }, mode: Ignore }, ArgAbi { layout: TyAndLayout { ty: &&[u16], layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), variants: Single { index: 0 } } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(8 bytes)) }) }], ret: ArgAbi { layout: TyAndLayout { ty: (u8, u8), layout: Layout { size: Size(2 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, abi: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=255 }, Initialized { value: Int(I8, false), valid_range: 0..=255 }), fields: Arbitrary { offsets: [Size(0 bytes), Size(1 bytes)], memory_index: [0, 1] }, largest_niche: None, variants: Single { index: 0 } } }, mode: Pair(ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }, ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }) }, c_variadic: false, fixed_count: 1, conv: Rust, can_unwind: false }
//! //!
//! ; kind loc.idx param pass mode ty //! ; kind loc.idx param pass mode ty
@ -25,7 +25,7 @@
//! //!
//! ss0 = explicit_slot 16 //! ss0 = explicit_slot 16
//! sig0 = (i64, i64) -> i8, i8 system_v //! sig0 = (i64, i64) -> i8, i8 system_v
//! fn0 = colocated u0:23 sig0 ; Instance { def: Item(WithOptConstParam { did: DefId(0:46 ~ example[4e51]::{impl#1}::call_mut), const_param_did: None }), substs: [ReErased, ReErased] } //! fn0 = colocated u0:23 sig0 ; Instance { def: Item(WithOptConstParam { did: DefId(0:46 ~ example[4e51]::{impl#1}::call_mut), const_param_did: None }), args: [ReErased, ReErased] }
//! //!
//! block0(v0: i64): //! block0(v0: i64):
//! nop //! nop
@ -261,7 +261,7 @@ pub(crate) fn write_clif_file(
impl fmt::Debug for FunctionCx<'_, '_, '_> { impl fmt::Debug for FunctionCx<'_, '_, '_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "{:?}", self.instance.substs)?; writeln!(f, "{:?}", self.instance.args)?;
writeln!(f, "{:?}", self.local_map)?; writeln!(f, "{:?}", self.local_map)?;
let mut clif = String::new(); let mut clif = String::new();

View File

@ -850,11 +850,11 @@ pub(crate) fn assert_assignable<'tcx>(
} }
} }
} }
(&ty::Adt(adt_def_a, substs_a), &ty::Adt(adt_def_b, substs_b)) (&ty::Adt(adt_def_a, args_a), &ty::Adt(adt_def_b, args_b))
if adt_def_a.did() == adt_def_b.did() => if adt_def_a.did() == adt_def_b.did() =>
{ {
let mut types_a = substs_a.types(); let mut types_a = args_a.types();
let mut types_b = substs_b.types(); let mut types_b = args_b.types();
loop { loop {
match (types_a.next(), types_b.next()) { match (types_a.next(), types_b.next()) {
(Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1), (Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),
@ -864,11 +864,11 @@ pub(crate) fn assert_assignable<'tcx>(
} }
} }
(ty::Array(a, _), ty::Array(b, _)) => assert_assignable(fx, *a, *b, limit - 1), (ty::Array(a, _), ty::Array(b, _)) => assert_assignable(fx, *a, *b, limit - 1),
(&ty::Closure(def_id_a, substs_a), &ty::Closure(def_id_b, substs_b)) (&ty::Closure(def_id_a, args_a), &ty::Closure(def_id_b, args_b))
if def_id_a == def_id_b => if def_id_a == def_id_b =>
{ {
let mut types_a = substs_a.types(); let mut types_a = args_a.types();
let mut types_b = substs_b.types(); let mut types_b = args_b.types();
loop { loop {
match (types_a.next(), types_b.next()) { match (types_a.next(), types_b.next()) {
(Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1), (Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),

View File

@ -17,8 +17,8 @@ use crate::context::CodegenCx;
pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>) -> Function<'gcc> { pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>) -> Function<'gcc> {
let tcx = cx.tcx(); let tcx = cx.tcx();
assert!(!instance.substs.has_infer()); assert!(!instance.args.has_infer());
assert!(!instance.substs.has_escaping_bound_vars()); assert!(!instance.args.has_escaping_bound_vars());
let sym = tcx.symbol_name(instance).name; let sym = tcx.symbol_name(instance).name;
@ -100,7 +100,7 @@ pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>)
// whether we are sharing generics or not. The important thing here is // whether we are sharing generics or not. The important thing here is
// that the visibility we apply to the declaration is the same one that // that the visibility we apply to the declaration is the same one that
// has been applied to the definition (wherever that definition may be). // has been applied to the definition (wherever that definition may be).
let is_generic = instance.substs.non_erasable_generics().next().is_some(); let is_generic = instance.args.non_erasable_generics().next().is_some();
if is_generic { if is_generic {
// This is a monomorphization. Its expected visibility depends // This is a monomorphization. Its expected visibility depends

View File

@ -92,8 +92,8 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
let tcx = self.tcx; let tcx = self.tcx;
let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all()); let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
let (def_id, substs) = match *callee_ty.kind() { let (def_id, fn_args) = match *callee_ty.kind() {
ty::FnDef(def_id, substs) => (def_id, substs), ty::FnDef(def_id, fn_args) => (def_id, fn_args),
_ => bug!("expected fn item type, found {}", callee_ty), _ => bug!("expected fn item type, found {}", callee_ty),
}; };
@ -142,7 +142,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
} }
sym::volatile_load | sym::unaligned_volatile_load => { sym::volatile_load | sym::unaligned_volatile_load => {
let tp_ty = substs.type_at(0); let tp_ty = fn_args.type_at(0);
let mut ptr = args[0].immediate(); let mut ptr = args[0].immediate();
if let PassMode::Cast(ty, _) = &fn_abi.ret.mode { if let PassMode::Cast(ty, _) = &fn_abi.ret.mode {
ptr = self.pointercast(ptr, self.type_ptr_to(ty.gcc_type(self))); ptr = self.pointercast(ptr, self.type_ptr_to(ty.gcc_type(self)));
@ -264,7 +264,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
sym::raw_eq => { sym::raw_eq => {
use rustc_target::abi::Abi::*; use rustc_target::abi::Abi::*;
let tp_ty = substs.type_at(0); let tp_ty = fn_args.type_at(0);
let layout = self.layout_of(tp_ty).layout; let layout = self.layout_of(tp_ty).layout;
let _use_integer_compare = match layout.abi() { let _use_integer_compare = match layout.abi() {
Scalar(_) | ScalarPair(_, _) => true, Scalar(_) | ScalarPair(_, _) => true,

View File

@ -31,7 +31,7 @@ impl<'gcc, 'tcx> PreDefineMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
#[cfg_attr(not(feature="master"), allow(unused_variables))] #[cfg_attr(not(feature="master"), allow(unused_variables))]
fn predefine_fn(&self, instance: Instance<'tcx>, linkage: Linkage, visibility: Visibility, symbol_name: &str) { fn predefine_fn(&self, instance: Instance<'tcx>, linkage: Linkage, visibility: Visibility, symbol_name: &str) {
assert!(!instance.substs.has_infer()); assert!(!instance.args.has_infer());
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty()); let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
self.linkage.set(base::linkage_to_gcc(linkage)); self.linkage.set(base::linkage_to_gcc(linkage));

View File

@ -101,7 +101,7 @@ fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout
if let (&ty::Generator(_, _, _), &Variants::Single { index }) = if let (&ty::Generator(_, _, _), &Variants::Single { index }) =
(layout.ty.kind(), &layout.variants) (layout.ty.kind(), &layout.variants)
{ {
write!(&mut name, "::{}", ty::GeneratorSubsts::variant_name(index)).unwrap(); write!(&mut name, "::{}", ty::GeneratorArgs::variant_name(index)).unwrap();
} }
Some(name) Some(name)
} }
@ -282,7 +282,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
} }
// only wide pointer boxes are handled as pointers // only wide pointer boxes are handled as pointers
// thin pointer boxes with scalar allocators are handled by the general logic below // thin pointer boxes with scalar allocators are handled by the general logic below
ty::Adt(def, substs) if def.is_box() && cx.layout_of(substs.type_at(1)).is_zst() => { ty::Adt(def, args) if def.is_box() && cx.layout_of(args.type_at(1)).is_zst() => {
let ptr_ty = Ty::new_mut_ptr(cx.tcx,self.ty.boxed_ty()); let ptr_ty = Ty::new_mut_ptr(cx.tcx,self.ty.boxed_ty());
return cx.layout_of(ptr_ty).scalar_pair_element_gcc_type(cx, index, immediate); return cx.layout_of(ptr_ty).scalar_pair_element_gcc_type(cx, index, immediate);
} }

View File

@ -27,8 +27,8 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) ->
debug!("get_fn(instance={:?})", instance); debug!("get_fn(instance={:?})", instance);
assert!(!instance.substs.has_infer()); assert!(!instance.args.has_infer());
assert!(!instance.substs.has_escaping_bound_vars()); assert!(!instance.args.has_escaping_bound_vars());
if let Some(&llfn) = cx.instances.borrow().get(&instance) { if let Some(&llfn) = cx.instances.borrow().get(&instance) {
return llfn; return llfn;
@ -129,7 +129,7 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) ->
unsafe { unsafe {
llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage); llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
let is_generic = instance.substs.non_erasable_generics().next().is_some(); let is_generic = instance.args.non_erasable_generics().next().is_some();
if is_generic { if is_generic {
// This is a monomorphization. Its expected visibility depends // This is a monomorphization. Its expected visibility depends

View File

@ -22,7 +22,7 @@ use rustc_middle::mir::coverage::{
use rustc_middle::mir::Coverage; use rustc_middle::mir::Coverage;
use rustc_middle::ty; use rustc_middle::ty;
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt}; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::GenericArgs;
use rustc_middle::ty::Instance; use rustc_middle::ty::Instance;
use rustc_middle::ty::Ty; use rustc_middle::ty::Ty;
@ -250,7 +250,7 @@ fn declare_unused_fn<'tcx>(cx: &CodegenCx<'_, 'tcx>, def_id: DefId) -> Instance<
let instance = Instance::new( let instance = Instance::new(
def_id, def_id,
InternalSubsts::for_item(tcx, def_id, |param, _| { GenericArgs::for_item(tcx, def_id, |param, _| {
if let ty::GenericParamDefKind::Lifetime = param.kind { if let ty::GenericParamDefKind::Lifetime = param.kind {
tcx.lifetimes.re_erased.into() tcx.lifetimes.re_erased.into()
} else { } else {

View File

@ -91,7 +91,7 @@ fn make_mir_scope<'ll, 'tcx>(
// FIXME(eddyb) this would be `self.monomorphize(&callee)` // FIXME(eddyb) this would be `self.monomorphize(&callee)`
// if this is moved to `rustc_codegen_ssa::mir::debuginfo`. // if this is moved to `rustc_codegen_ssa::mir::debuginfo`.
let callee = cx.tcx.subst_and_normalize_erasing_regions( let callee = cx.tcx.subst_and_normalize_erasing_regions(
instance.substs, instance.args,
ty::ParamEnv::reveal_all(), ty::ParamEnv::reveal_all(),
ty::EarlyBinder::bind(callee), ty::EarlyBinder::bind(callee),
); );

View File

@ -449,7 +449,7 @@ pub fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll D
} }
// Box<T, A> may have a non-ZST allocator A. In that case, we // Box<T, A> may have a non-ZST allocator A. In that case, we
// cannot treat Box<T, A> as just an owned alias of `*mut T`. // cannot treat Box<T, A> as just an owned alias of `*mut T`.
ty::Adt(def, substs) if def.is_box() && cx.layout_of(substs.type_at(1)).is_zst() => { ty::Adt(def, args) if def.is_box() && cx.layout_of(args.type_at(1)).is_zst() => {
build_pointer_or_reference_di_node(cx, t, t.boxed_ty(), unique_type_id) build_pointer_or_reference_di_node(cx, t, t.boxed_ty(), unique_type_id)
} }
ty::FnDef(..) | ty::FnPtr(_) => build_subroutine_type_di_node(cx, unique_type_id), ty::FnDef(..) | ty::FnPtr(_) => build_subroutine_type_di_node(cx, unique_type_id),
@ -1007,12 +1007,12 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>(
closure_or_generator_di_node: &'ll DIType, closure_or_generator_di_node: &'ll DIType,
) -> SmallVec<&'ll DIType> { ) -> SmallVec<&'ll DIType> {
let (&def_id, up_var_tys) = match closure_or_generator_ty.kind() { let (&def_id, up_var_tys) = match closure_or_generator_ty.kind() {
ty::Generator(def_id, substs, _) => { ty::Generator(def_id, args, _) => {
let upvar_tys: SmallVec<_> = substs.as_generator().prefix_tys().collect(); let upvar_tys: SmallVec<_> = args.as_generator().prefix_tys().collect();
(def_id, upvar_tys) (def_id, upvar_tys)
} }
ty::Closure(def_id, substs) => { ty::Closure(def_id, args) => {
let upvar_tys: SmallVec<_> = substs.as_closure().upvar_tys().collect(); let upvar_tys: SmallVec<_> = args.as_closure().upvar_tys().collect();
(def_id, upvar_tys) (def_id, upvar_tys)
} }
_ => { _ => {
@ -1102,7 +1102,7 @@ fn build_closure_env_di_node<'ll, 'tcx>(
unique_type_id: UniqueTypeId<'tcx>, unique_type_id: UniqueTypeId<'tcx>,
) -> DINodeCreationResult<'ll> { ) -> DINodeCreationResult<'ll> {
let closure_env_type = unique_type_id.expect_ty(); let closure_env_type = unique_type_id.expect_ty();
let &ty::Closure(def_id, _substs) = closure_env_type.kind() else { let &ty::Closure(def_id, _args) = closure_env_type.kind() else {
bug!("build_closure_env_di_node() called with non-closure-type: {:?}", closure_env_type) bug!("build_closure_env_di_node() called with non-closure-type: {:?}", closure_env_type)
}; };
let containing_scope = get_namespace_for_item(cx, def_id); let containing_scope = get_namespace_for_item(cx, def_id);
@ -1180,11 +1180,11 @@ fn build_generic_type_param_di_nodes<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>, cx: &CodegenCx<'ll, 'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> SmallVec<&'ll DIType> { ) -> SmallVec<&'ll DIType> {
if let ty::Adt(def, substs) = *ty.kind() { if let ty::Adt(def, args) = *ty.kind() {
if substs.types().next().is_some() { if args.types().next().is_some() {
let generics = cx.tcx.generics_of(def.did()); let generics = cx.tcx.generics_of(def.did());
let names = get_parameter_names(cx, generics); let names = get_parameter_names(cx, generics);
let template_params: SmallVec<_> = iter::zip(substs, names) let template_params: SmallVec<_> = iter::zip(args, names)
.filter_map(|(kind, name)| { .filter_map(|(kind, name)| {
kind.as_type().map(|ty| { kind.as_type().map(|ty| {
let actual_type = let actual_type =

View File

@ -12,7 +12,7 @@ use rustc_middle::{
ty::{ ty::{
self, self,
layout::{LayoutOf, TyAndLayout}, layout::{LayoutOf, TyAndLayout},
AdtDef, GeneratorSubsts, Ty, AdtDef, GeneratorArgs, Ty,
}, },
}; };
use rustc_target::abi::{Align, Endian, Size, TagEncoding, VariantIdx, Variants}; use rustc_target::abi::{Align, Endian, Size, TagEncoding, VariantIdx, Variants};
@ -673,15 +673,15 @@ fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>(
bug!("This function only supports layouts with directly encoded tags.") bug!("This function only supports layouts with directly encoded tags.")
}; };
let (generator_def_id, generator_substs) = match generator_type_and_layout.ty.kind() { let (generator_def_id, generator_args) = match generator_type_and_layout.ty.kind() {
&ty::Generator(def_id, substs, _) => (def_id, substs.as_generator()), &ty::Generator(def_id, args, _) => (def_id, args.as_generator()),
_ => unreachable!(), _ => unreachable!(),
}; };
let generator_layout = cx.tcx.optimized_mir(generator_def_id).generator_layout().unwrap(); let generator_layout = cx.tcx.optimized_mir(generator_def_id).generator_layout().unwrap();
let common_upvar_names = cx.tcx.closure_saved_names_of_captured_variables(generator_def_id); let common_upvar_names = cx.tcx.closure_saved_names_of_captured_variables(generator_def_id);
let variant_range = generator_substs.variant_range(generator_def_id, cx.tcx); let variant_range = generator_args.variant_range(generator_def_id, cx.tcx);
let variant_count = (variant_range.start.as_u32()..variant_range.end.as_u32()).len(); let variant_count = (variant_range.start.as_u32()..variant_range.end.as_u32()).len();
let tag_base_type = tag_base_type(cx, generator_type_and_layout); let tag_base_type = tag_base_type(cx, generator_type_and_layout);
@ -691,11 +691,11 @@ fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>(
generator_type_di_node, generator_type_di_node,
variant_range variant_range
.clone() .clone()
.map(|variant_index| (variant_index, GeneratorSubsts::variant_name(variant_index))), .map(|variant_index| (variant_index, GeneratorArgs::variant_name(variant_index))),
); );
let discriminants: IndexVec<VariantIdx, DiscrResult> = { let discriminants: IndexVec<VariantIdx, DiscrResult> = {
let discriminants_iter = generator_substs.discriminants(generator_def_id, cx.tcx); let discriminants_iter = generator_args.discriminants(generator_def_id, cx.tcx);
let mut discriminants: IndexVec<VariantIdx, DiscrResult> = let mut discriminants: IndexVec<VariantIdx, DiscrResult> =
IndexVec::with_capacity(variant_count); IndexVec::with_capacity(variant_count);
for (variant_index, discr) in discriminants_iter { for (variant_index, discr) in discriminants_iter {

View File

@ -10,7 +10,7 @@ use rustc_middle::{
ty::{ ty::{
self, self,
layout::{IntegerExt, LayoutOf, PrimitiveExt, TyAndLayout}, layout::{IntegerExt, LayoutOf, PrimitiveExt, TyAndLayout},
AdtDef, GeneratorSubsts, Ty, VariantDef, AdtDef, GeneratorArgs, Ty, VariantDef,
}, },
}; };
use rustc_span::Symbol; use rustc_span::Symbol;
@ -325,7 +325,7 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>(
generator_layout: &GeneratorLayout<'tcx>, generator_layout: &GeneratorLayout<'tcx>,
common_upvar_names: &IndexSlice<FieldIdx, Symbol>, common_upvar_names: &IndexSlice<FieldIdx, Symbol>,
) -> &'ll DIType { ) -> &'ll DIType {
let variant_name = GeneratorSubsts::variant_name(variant_index); let variant_name = GeneratorArgs::variant_name(variant_index);
let unique_type_id = UniqueTypeId::for_enum_variant_struct_type( let unique_type_id = UniqueTypeId::for_enum_variant_struct_type(
cx.tcx, cx.tcx,
generator_type_and_layout.ty, generator_type_and_layout.ty,
@ -334,8 +334,8 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>(
let variant_layout = generator_type_and_layout.for_variant(cx, variant_index); let variant_layout = generator_type_and_layout.for_variant(cx, variant_index);
let generator_substs = match generator_type_and_layout.ty.kind() { let generator_args = match generator_type_and_layout.ty.kind() {
ty::Generator(_, substs, _) => substs.as_generator(), ty::Generator(_, args, _) => args.as_generator(),
_ => unreachable!(), _ => unreachable!(),
}; };
@ -377,7 +377,7 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>(
.collect(); .collect();
// Fields that are common to all states // Fields that are common to all states
let common_fields: SmallVec<_> = generator_substs let common_fields: SmallVec<_> = generator_args
.prefix_tys() .prefix_tys()
.zip(common_upvar_names) .zip(common_upvar_names)
.enumerate() .enumerate()

View File

@ -175,7 +175,7 @@ pub(super) fn build_generator_di_node<'ll, 'tcx>(
.indices() .indices()
.map(|variant_index| { .map(|variant_index| {
// FIXME: This is problematic because just a number is not a valid identifier. // FIXME: This is problematic because just a number is not a valid identifier.
// GeneratorSubsts::variant_name(variant_index), would be consistent // GeneratorArgs::variant_name(variant_index), would be consistent
// with enums? // with enums?
let variant_name = format!("{}", variant_index.as_usize()).into(); let variant_name = format!("{}", variant_index.as_usize()).into();

View File

@ -27,7 +27,7 @@ use rustc_hir::def_id::{DefId, DefIdMap};
use rustc_index::IndexVec; use rustc_index::IndexVec;
use rustc_middle::mir; use rustc_middle::mir;
use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TypeVisitableExt}; use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TypeVisitableExt};
use rustc_session::config::{self, DebugInfo}; use rustc_session::config::{self, DebugInfo};
use rustc_session::Session; use rustc_session::Session;
@ -338,19 +338,19 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
// Find the enclosing function, in case this is a closure. // Find the enclosing function, in case this is a closure.
let enclosing_fn_def_id = tcx.typeck_root_def_id(def_id); let enclosing_fn_def_id = tcx.typeck_root_def_id(def_id);
// We look up the generics of the enclosing function and truncate the substs // We look up the generics of the enclosing function and truncate the args
// to their length in order to cut off extra stuff that might be in there for // to their length in order to cut off extra stuff that might be in there for
// closures or generators. // closures or generators.
let generics = tcx.generics_of(enclosing_fn_def_id); let generics = tcx.generics_of(enclosing_fn_def_id);
let substs = instance.substs.truncate_to(tcx, generics); let args = instance.args.truncate_to(tcx, generics);
type_names::push_generic_params( type_names::push_generic_params(
tcx, tcx,
tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substs), tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args),
&mut name, &mut name,
); );
let template_parameters = get_template_parameters(self, generics, substs); let template_parameters = get_template_parameters(self, generics, args);
let linkage_name = &mangled_name_of_instance(self, instance).name; let linkage_name = &mangled_name_of_instance(self, instance).name;
// Omit the linkage_name if it is the same as subprogram name. // Omit the linkage_name if it is the same as subprogram name.
@ -471,16 +471,16 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn get_template_parameters<'ll, 'tcx>( fn get_template_parameters<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>, cx: &CodegenCx<'ll, 'tcx>,
generics: &ty::Generics, generics: &ty::Generics,
substs: SubstsRef<'tcx>, args: GenericArgsRef<'tcx>,
) -> &'ll DIArray { ) -> &'ll DIArray {
if substs.types().next().is_none() { if args.types().next().is_none() {
return create_DIArray(DIB(cx), &[]); return create_DIArray(DIB(cx), &[]);
} }
// Again, only create type information if full debuginfo is enabled // Again, only create type information if full debuginfo is enabled
let template_params: Vec<_> = if cx.sess().opts.debuginfo == DebugInfo::Full { let template_params: Vec<_> = if cx.sess().opts.debuginfo == DebugInfo::Full {
let names = get_parameter_names(cx, generics); let names = get_parameter_names(cx, generics);
iter::zip(substs, names) iter::zip(args, names)
.filter_map(|(kind, name)| { .filter_map(|(kind, name)| {
kind.as_type().map(|ty| { kind.as_type().map(|ty| {
let actual_type = let actual_type =
@ -527,7 +527,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
// If the method does *not* belong to a trait, proceed // If the method does *not* belong to a trait, proceed
if cx.tcx.trait_id_of_impl(impl_def_id).is_none() { if cx.tcx.trait_id_of_impl(impl_def_id).is_none() {
let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions( let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions(
instance.substs, instance.args,
ty::ParamEnv::reveal_all(), ty::ParamEnv::reveal_all(),
cx.tcx.type_of(impl_def_id), cx.tcx.type_of(impl_def_id),
); );

View File

@ -90,7 +90,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
let tcx = self.tcx; let tcx = self.tcx;
let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all()); let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
let ty::FnDef(def_id, substs) = *callee_ty.kind() else { let ty::FnDef(def_id, fn_args) = *callee_ty.kind() else {
bug!("expected fn item type, found {}", callee_ty); bug!("expected fn item type, found {}", callee_ty);
}; };
@ -163,7 +163,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
} }
sym::volatile_load | sym::unaligned_volatile_load => { sym::volatile_load | sym::unaligned_volatile_load => {
let tp_ty = substs.type_at(0); let tp_ty = fn_args.type_at(0);
let ptr = args[0].immediate(); let ptr = args[0].immediate();
let load = if let PassMode::Cast(ty, _) = &fn_abi.ret.mode { let load = if let PassMode::Cast(ty, _) = &fn_abi.ret.mode {
let llty = ty.llvm_type(self); let llty = ty.llvm_type(self);
@ -298,7 +298,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
sym::raw_eq => { sym::raw_eq => {
use abi::Abi::*; use abi::Abi::*;
let tp_ty = substs.type_at(0); let tp_ty = fn_args.type_at(0);
let layout = self.layout_of(tp_ty).layout; let layout = self.layout_of(tp_ty).layout;
let use_integer_compare = match layout.abi() { let use_integer_compare = match layout.abi() {
Scalar(_) | ScalarPair(_, _) => true, Scalar(_) | ScalarPair(_, _) => true,

View File

@ -48,7 +48,7 @@ impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'_, 'tcx> {
visibility: Visibility, visibility: Visibility,
symbol_name: &str, symbol_name: &str,
) { ) {
assert!(!instance.substs.has_infer()); assert!(!instance.args.has_infer());
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty()); let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
let lldecl = self.declare_fn(symbol_name, fn_abi, Some(instance)); let lldecl = self.declare_fn(symbol_name, fn_abi, Some(instance));

View File

@ -57,7 +57,7 @@ fn uncached_llvm_type<'a, 'tcx>(
if let (&ty::Generator(_, _, _), &Variants::Single { index }) = if let (&ty::Generator(_, _, _), &Variants::Single { index }) =
(layout.ty.kind(), &layout.variants) (layout.ty.kind(), &layout.variants)
{ {
write!(&mut name, "::{}", ty::GeneratorSubsts::variant_name(index)).unwrap(); write!(&mut name, "::{}", ty::GeneratorArgs::variant_name(index)).unwrap();
} }
Some(name) Some(name)
} }
@ -336,7 +336,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
} }
// only wide pointer boxes are handled as pointers // only wide pointer boxes are handled as pointers
// thin pointer boxes with scalar allocators are handled by the general logic below // thin pointer boxes with scalar allocators are handled by the general logic below
ty::Adt(def, substs) if def.is_box() && cx.layout_of(substs.type_at(1)).is_zst() => { ty::Adt(def, args) if def.is_box() && cx.layout_of(args.type_at(1)).is_zst() => {
let ptr_ty = Ty::new_mut_ptr(cx.tcx, self.ty.boxed_ty()); let ptr_ty = Ty::new_mut_ptr(cx.tcx, self.ty.boxed_ty());
return cx.layout_of(ptr_ty).scalar_pair_element_llvm_type(cx, index, immediate); return cx.layout_of(ptr_ty).scalar_pair_element_llvm_type(cx, index, immediate);
} }

View File

@ -12,9 +12,9 @@ use rustc_middle::middle::exported_symbols::{
}; };
use rustc_middle::query::LocalCrate; use rustc_middle::query::LocalCrate;
use rustc_middle::query::{ExternProviders, Providers}; use rustc_middle::query::{ExternProviders, Providers};
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
use rustc_middle::ty::Instance; use rustc_middle::ty::Instance;
use rustc_middle::ty::{self, SymbolName, TyCtxt}; use rustc_middle::ty::{self, SymbolName, TyCtxt};
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
use rustc_session::config::{CrateType, OomStrategy}; use rustc_session::config::{CrateType, OomStrategy};
use rustc_target::spec::SanitizerSet; use rustc_target::spec::SanitizerSet;
@ -342,9 +342,9 @@ fn exported_symbols_provider_local(
} }
match *mono_item { match *mono_item {
MonoItem::Fn(Instance { def: InstanceDef::Item(def), substs }) => { MonoItem::Fn(Instance { def: InstanceDef::Item(def), args }) => {
if substs.non_erasable_generics().next().is_some() { if args.non_erasable_generics().next().is_some() {
let symbol = ExportedSymbol::Generic(def, substs); let symbol = ExportedSymbol::Generic(def, args);
symbols.push(( symbols.push((
symbol, symbol,
SymbolExportInfo { SymbolExportInfo {
@ -355,10 +355,10 @@ fn exported_symbols_provider_local(
)); ));
} }
} }
MonoItem::Fn(Instance { def: InstanceDef::DropGlue(_, Some(ty)), substs }) => { MonoItem::Fn(Instance { def: InstanceDef::DropGlue(_, Some(ty)), args }) => {
// A little sanity-check // A little sanity-check
debug_assert_eq!( debug_assert_eq!(
substs.non_erasable_generics().next(), args.non_erasable_generics().next(),
Some(GenericArgKind::Type(ty)) Some(GenericArgKind::Type(ty))
); );
symbols.push(( symbols.push((
@ -386,7 +386,7 @@ fn exported_symbols_provider_local(
fn upstream_monomorphizations_provider( fn upstream_monomorphizations_provider(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
(): (), (): (),
) -> DefIdMap<FxHashMap<SubstsRef<'_>, CrateNum>> { ) -> DefIdMap<FxHashMap<GenericArgsRef<'_>, CrateNum>> {
let cnums = tcx.crates(()); let cnums = tcx.crates(());
let mut instances: DefIdMap<FxHashMap<_, _>> = Default::default(); let mut instances: DefIdMap<FxHashMap<_, _>> = Default::default();
@ -395,11 +395,11 @@ fn upstream_monomorphizations_provider(
for &cnum in cnums.iter() { for &cnum in cnums.iter() {
for (exported_symbol, _) in tcx.exported_symbols(cnum).iter() { for (exported_symbol, _) in tcx.exported_symbols(cnum).iter() {
let (def_id, substs) = match *exported_symbol { let (def_id, args) = match *exported_symbol {
ExportedSymbol::Generic(def_id, substs) => (def_id, substs), ExportedSymbol::Generic(def_id, args) => (def_id, args),
ExportedSymbol::DropGlue(ty) => { ExportedSymbol::DropGlue(ty) => {
if let Some(drop_in_place_fn_def_id) = drop_in_place_fn_def_id { if let Some(drop_in_place_fn_def_id) = drop_in_place_fn_def_id {
(drop_in_place_fn_def_id, tcx.mk_substs(&[ty.into()])) (drop_in_place_fn_def_id, tcx.mk_args(&[ty.into()]))
} else { } else {
// `drop_in_place` in place does not exist, don't try // `drop_in_place` in place does not exist, don't try
// to use it. // to use it.
@ -414,9 +414,9 @@ fn upstream_monomorphizations_provider(
} }
}; };
let substs_map = instances.entry(def_id).or_default(); let args_map = instances.entry(def_id).or_default();
match substs_map.entry(substs) { match args_map.entry(args) {
Occupied(mut e) => { Occupied(mut e) => {
// If there are multiple monomorphizations available, // If there are multiple monomorphizations available,
// we select one deterministically. // we select one deterministically.
@ -438,17 +438,17 @@ fn upstream_monomorphizations_provider(
fn upstream_monomorphizations_for_provider( fn upstream_monomorphizations_for_provider(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
def_id: DefId, def_id: DefId,
) -> Option<&FxHashMap<SubstsRef<'_>, CrateNum>> { ) -> Option<&FxHashMap<GenericArgsRef<'_>, CrateNum>> {
debug_assert!(!def_id.is_local()); debug_assert!(!def_id.is_local());
tcx.upstream_monomorphizations(()).get(&def_id) tcx.upstream_monomorphizations(()).get(&def_id)
} }
fn upstream_drop_glue_for_provider<'tcx>( fn upstream_drop_glue_for_provider<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
substs: SubstsRef<'tcx>, args: GenericArgsRef<'tcx>,
) -> Option<CrateNum> { ) -> Option<CrateNum> {
if let Some(def_id) = tcx.lang_items().drop_in_place_fn() { if let Some(def_id) = tcx.lang_items().drop_in_place_fn() {
tcx.upstream_monomorphizations_for(def_id).and_then(|monos| monos.get(&substs).cloned()) tcx.upstream_monomorphizations_for(def_id).and_then(|monos| monos.get(&args).cloned())
} else { } else {
None None
} }
@ -521,10 +521,10 @@ pub fn symbol_name_for_instance_in_crate<'tcx>(
instantiating_crate, instantiating_crate,
) )
} }
ExportedSymbol::Generic(def_id, substs) => { ExportedSymbol::Generic(def_id, args) => {
rustc_symbol_mangling::symbol_name_for_instance_in_crate( rustc_symbol_mangling::symbol_name_for_instance_in_crate(
tcx, tcx,
Instance::new(def_id, substs), Instance::new(def_id, args),
instantiating_crate, instantiating_crate,
) )
} }
@ -533,7 +533,7 @@ pub fn symbol_name_for_instance_in_crate<'tcx>(
tcx, tcx,
ty::Instance { ty::Instance {
def: ty::InstanceDef::ThreadLocalShim(def_id), def: ty::InstanceDef::ThreadLocalShim(def_id),
substs: ty::InternalSubsts::empty(), args: ty::GenericArgs::empty(),
}, },
instantiating_crate, instantiating_crate,
) )
@ -580,7 +580,7 @@ pub fn linking_symbol_name_for_instance_in_crate<'tcx>(
None None
} }
ExportedSymbol::NonGeneric(def_id) => Some(Instance::mono(tcx, def_id)), ExportedSymbol::NonGeneric(def_id) => Some(Instance::mono(tcx, def_id)),
ExportedSymbol::Generic(def_id, substs) => Some(Instance::new(def_id, substs)), ExportedSymbol::Generic(def_id, args) => Some(Instance::new(def_id, args)),
// DropGlue always use the Rust calling convention and thus follow the target's default // DropGlue always use the Rust calling convention and thus follow the target's default
// symbol decoration scheme. // symbol decoration scheme.
ExportedSymbol::DropGlue(..) => None, ExportedSymbol::DropGlue(..) => None,

View File

@ -499,7 +499,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
cx.tcx(), cx.tcx(),
ty::ParamEnv::reveal_all(), ty::ParamEnv::reveal_all(),
start_def_id, start_def_id,
cx.tcx().mk_substs(&[main_ret_ty.into()]), cx.tcx().mk_args(&[main_ret_ty.into()]),
) )
.unwrap() .unwrap()
.unwrap(), .unwrap(),

View File

@ -17,8 +17,8 @@ use rustc_hir::def_id::DefId;
use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData}; use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData};
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Mutability}; use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Mutability};
use rustc_middle::ty::layout::{IntegerExt, TyAndLayout}; use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
use rustc_middle::ty::{self, ExistentialProjection, ParamEnv, Ty, TyCtxt}; use rustc_middle::ty::{self, ExistentialProjection, ParamEnv, Ty, TyCtxt};
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
use rustc_target::abi::Integer; use rustc_target::abi::Integer;
use smallvec::SmallVec; use smallvec::SmallVec;
@ -77,7 +77,7 @@ fn push_debuginfo_type_name<'tcx>(
ty::Uint(uint_ty) => output.push_str(uint_ty.name_str()), ty::Uint(uint_ty) => output.push_str(uint_ty.name_str()),
ty::Float(float_ty) => output.push_str(float_ty.name_str()), ty::Float(float_ty) => output.push_str(float_ty.name_str()),
ty::Foreign(def_id) => push_item_name(tcx, def_id, qualified, output), ty::Foreign(def_id) => push_item_name(tcx, def_id, qualified, output),
ty::Adt(def, substs) => { ty::Adt(def, args) => {
// `layout_for_cpp_like_fallback` will be `Some` if we want to use the fallback encoding. // `layout_for_cpp_like_fallback` will be `Some` if we want to use the fallback encoding.
let layout_for_cpp_like_fallback = if cpp_like_debuginfo && def.is_enum() { let layout_for_cpp_like_fallback = if cpp_like_debuginfo && def.is_enum() {
match tcx.layout_of(ParamEnv::reveal_all().and(t)) { match tcx.layout_of(ParamEnv::reveal_all().and(t)) {
@ -106,14 +106,14 @@ fn push_debuginfo_type_name<'tcx>(
ty_and_layout, ty_and_layout,
&|output, visited| { &|output, visited| {
push_item_name(tcx, def.did(), true, output); push_item_name(tcx, def.did(), true, output);
push_generic_params_internal(tcx, substs, output, visited); push_generic_params_internal(tcx, args, output, visited);
}, },
output, output,
visited, visited,
); );
} else { } else {
push_item_name(tcx, def.did(), qualified, output); push_item_name(tcx, def.did(), qualified, output);
push_generic_params_internal(tcx, substs, output, visited); push_generic_params_internal(tcx, args, output, visited);
} }
} }
ty::Tuple(component_types) => { ty::Tuple(component_types) => {
@ -238,7 +238,7 @@ fn push_debuginfo_type_name<'tcx>(
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), principal); tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), principal);
push_item_name(tcx, principal.def_id, qualified, output); push_item_name(tcx, principal.def_id, qualified, output);
let principal_has_generic_params = let principal_has_generic_params =
push_generic_params_internal(tcx, principal.substs, output, visited); push_generic_params_internal(tcx, principal.args, output, visited);
let projection_bounds: SmallVec<[_; 4]> = trait_data let projection_bounds: SmallVec<[_; 4]> = trait_data
.projection_bounds() .projection_bounds()
@ -393,7 +393,7 @@ fn push_debuginfo_type_name<'tcx>(
// processing // processing
visited.remove(&t); visited.remove(&t);
} }
ty::Closure(def_id, substs) | ty::Generator(def_id, substs, ..) => { ty::Closure(def_id, args) | ty::Generator(def_id, args, ..) => {
// Name will be "{closure_env#0}<T1, T2, ...>", "{generator_env#0}<T1, T2, ...>", or // Name will be "{closure_env#0}<T1, T2, ...>", "{generator_env#0}<T1, T2, ...>", or
// "{async_fn_env#0}<T1, T2, ...>", etc. // "{async_fn_env#0}<T1, T2, ...>", etc.
// In the case of cpp-like debuginfo, the name additionally gets wrapped inside of // In the case of cpp-like debuginfo, the name additionally gets wrapped inside of
@ -403,13 +403,13 @@ fn push_debuginfo_type_name<'tcx>(
msvc_enum_fallback( msvc_enum_fallback(
ty_and_layout, ty_and_layout,
&|output, visited| { &|output, visited| {
push_closure_or_generator_name(tcx, def_id, substs, true, output, visited); push_closure_or_generator_name(tcx, def_id, args, true, output, visited);
}, },
output, output,
visited, visited,
); );
} else { } else {
push_closure_or_generator_name(tcx, def_id, substs, qualified, output, visited); push_closure_or_generator_name(tcx, def_id, args, qualified, output, visited);
} }
} }
// Type parameters from polymorphized functions. // Type parameters from polymorphized functions.
@ -516,7 +516,7 @@ pub fn compute_debuginfo_vtable_name<'tcx>(
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), trait_ref); tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), trait_ref);
push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name); push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name);
visited.clear(); visited.clear();
push_generic_params_internal(tcx, trait_ref.substs, &mut vtable_name, &mut visited); push_generic_params_internal(tcx, trait_ref.args, &mut vtable_name, &mut visited);
} else { } else {
vtable_name.push('_'); vtable_name.push('_');
} }
@ -609,21 +609,21 @@ fn push_unqualified_item_name(
fn push_generic_params_internal<'tcx>( fn push_generic_params_internal<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
substs: SubstsRef<'tcx>, args: GenericArgsRef<'tcx>,
output: &mut String, output: &mut String,
visited: &mut FxHashSet<Ty<'tcx>>, visited: &mut FxHashSet<Ty<'tcx>>,
) -> bool { ) -> bool {
if substs.non_erasable_generics().next().is_none() { if args.non_erasable_generics().next().is_none() {
return false; return false;
} }
debug_assert_eq!(substs, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substs)); debug_assert_eq!(args, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args));
let cpp_like_debuginfo = cpp_like_debuginfo(tcx); let cpp_like_debuginfo = cpp_like_debuginfo(tcx);
output.push('<'); output.push('<');
for type_parameter in substs.non_erasable_generics() { for type_parameter in args.non_erasable_generics() {
match type_parameter { match type_parameter {
GenericArgKind::Type(type_parameter) => { GenericArgKind::Type(type_parameter) => {
push_debuginfo_type_name(tcx, type_parameter, true, output, visited); push_debuginfo_type_name(tcx, type_parameter, true, output, visited);
@ -688,16 +688,20 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
.unwrap(); .unwrap();
} }
pub fn push_generic_params<'tcx>(tcx: TyCtxt<'tcx>, substs: SubstsRef<'tcx>, output: &mut String) { pub fn push_generic_params<'tcx>(
tcx: TyCtxt<'tcx>,
args: GenericArgsRef<'tcx>,
output: &mut String,
) {
let _prof = tcx.prof.generic_activity("compute_debuginfo_type_name"); let _prof = tcx.prof.generic_activity("compute_debuginfo_type_name");
let mut visited = FxHashSet::default(); let mut visited = FxHashSet::default();
push_generic_params_internal(tcx, substs, output, &mut visited); push_generic_params_internal(tcx, args, output, &mut visited);
} }
fn push_closure_or_generator_name<'tcx>( fn push_closure_or_generator_name<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
def_id: DefId, def_id: DefId,
substs: SubstsRef<'tcx>, args: GenericArgsRef<'tcx>,
qualified: bool, qualified: bool,
output: &mut String, output: &mut String,
visited: &mut FxHashSet<Ty<'tcx>>, visited: &mut FxHashSet<Ty<'tcx>>,
@ -731,10 +735,10 @@ fn push_closure_or_generator_name<'tcx>(
let enclosing_fn_def_id = tcx.typeck_root_def_id(def_id); let enclosing_fn_def_id = tcx.typeck_root_def_id(def_id);
let generics = tcx.generics_of(enclosing_fn_def_id); let generics = tcx.generics_of(enclosing_fn_def_id);
// Truncate the substs to the length of the above generics. This will cut off // Truncate the args to the length of the above generics. This will cut off
// anything closure- or generator-specific. // anything closure- or generator-specific.
let substs = substs.truncate_to(tcx, generics); let args = args.truncate_to(tcx, generics);
push_generic_params_internal(tcx, substs, output, visited); push_generic_params_internal(tcx, args, output, visited);
} }
fn push_close_angle_bracket(cpp_like_debuginfo: bool, output: &mut String) { fn push_close_angle_bracket(cpp_like_debuginfo: bool, output: &mut String) {

View File

@ -1,6 +1,6 @@
use crate::traits::*; use crate::traits::*;
use rustc_middle::ty::{self, subst::GenericArgKind, Ty}; use rustc_middle::ty::{self, GenericArgKind, Ty};
use rustc_session::config::Lto; use rustc_session::config::Lto;
use rustc_symbol_mangling::typeid_for_trait_ref; use rustc_symbol_mangling::typeid_for_trait_ref;
use rustc_target::abi::call::FnAbi; use rustc_target::abi::call::FnAbi;

View File

@ -491,7 +491,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// //
let virtual_drop = Instance { let virtual_drop = Instance {
def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0), def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
substs: drop_fn.substs, args: drop_fn.args,
}; };
debug!("ty = {:?}", ty); debug!("ty = {:?}", ty);
debug!("drop_fn = {:?}", drop_fn); debug!("drop_fn = {:?}", drop_fn);
@ -531,7 +531,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// SO THEN WE CAN USE THE ABOVE CODE. // SO THEN WE CAN USE THE ABOVE CODE.
let virtual_drop = Instance { let virtual_drop = Instance {
def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0), def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
substs: drop_fn.substs, args: drop_fn.args,
}; };
debug!("ty = {:?}", ty); debug!("ty = {:?}", ty);
debug!("drop_fn = {:?}", drop_fn); debug!("drop_fn = {:?}", drop_fn);
@ -687,7 +687,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// which mentions the offending type, even from a const context. // which mentions the offending type, even from a const context.
let panic_intrinsic = intrinsic.and_then(|s| ValidityRequirement::from_intrinsic(s)); let panic_intrinsic = intrinsic.and_then(|s| ValidityRequirement::from_intrinsic(s));
if let Some(requirement) = panic_intrinsic { if let Some(requirement) = panic_intrinsic {
let ty = instance.unwrap().substs.type_at(0); let ty = instance.unwrap().args.type_at(0);
let do_panic = !bx let do_panic = !bx
.tcx() .tcx()
@ -760,13 +760,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let callee = self.codegen_operand(bx, func); let callee = self.codegen_operand(bx, func);
let (instance, mut llfn) = match *callee.layout.ty.kind() { let (instance, mut llfn) = match *callee.layout.ty.kind() {
ty::FnDef(def_id, substs) => ( ty::FnDef(def_id, args) => (
Some( Some(
ty::Instance::expect_resolve( ty::Instance::expect_resolve(
bx.tcx(), bx.tcx(),
ty::ParamEnv::reveal_all(), ty::ParamEnv::reveal_all(),
def_id, def_id,
substs, args,
) )
.polymorphize(bx.tcx()), .polymorphize(bx.tcx()),
), ),
@ -1125,12 +1125,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
} }
mir::InlineAsmOperand::SymFn { ref value } => { mir::InlineAsmOperand::SymFn { ref value } => {
let literal = self.monomorphize(value.literal); let literal = self.monomorphize(value.literal);
if let ty::FnDef(def_id, substs) = *literal.ty().kind() { if let ty::FnDef(def_id, args) = *literal.ty().kind() {
let instance = ty::Instance::resolve_for_fn_ptr( let instance = ty::Instance::resolve_for_fn_ptr(
bx.tcx(), bx.tcx(),
ty::ParamEnv::reveal_all(), ty::ParamEnv::reveal_all(),
def_id, def_id,
substs, args,
) )
.unwrap(); .unwrap();
InlineAsmOperandRef::SymFn { instance } InlineAsmOperandRef::SymFn { instance }

View File

@ -64,7 +64,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
) { ) {
let callee_ty = instance.ty(bx.tcx(), ty::ParamEnv::reveal_all()); let callee_ty = instance.ty(bx.tcx(), ty::ParamEnv::reveal_all());
let ty::FnDef(def_id, substs) = *callee_ty.kind() else { let ty::FnDef(def_id, fn_args) = *callee_ty.kind() else {
bug!("expected fn item type, found {}", callee_ty); bug!("expected fn item type, found {}", callee_ty);
}; };
@ -87,7 +87,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
sym::va_start => bx.va_start(args[0].immediate()), sym::va_start => bx.va_start(args[0].immediate()),
sym::va_end => bx.va_end(args[0].immediate()), sym::va_end => bx.va_end(args[0].immediate()),
sym::size_of_val => { sym::size_of_val => {
let tp_ty = substs.type_at(0); let tp_ty = fn_args.type_at(0);
if let OperandValue::Pair(_, meta) = args[0].val { if let OperandValue::Pair(_, meta) = args[0].val {
let (llsize, _) = glue::size_and_align_of_dst(bx, tp_ty, Some(meta)); let (llsize, _) = glue::size_and_align_of_dst(bx, tp_ty, Some(meta));
llsize llsize
@ -96,7 +96,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
} }
} }
sym::min_align_of_val => { sym::min_align_of_val => {
let tp_ty = substs.type_at(0); let tp_ty = fn_args.type_at(0);
if let OperandValue::Pair(_, meta) = args[0].val { if let OperandValue::Pair(_, meta) = args[0].val {
let (_, llalign) = glue::size_and_align_of_dst(bx, tp_ty, Some(meta)); let (_, llalign) = glue::size_and_align_of_dst(bx, tp_ty, Some(meta));
llalign llalign
@ -136,7 +136,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
OperandRef::from_const(bx, value, ret_ty).immediate_or_packed_pair(bx) OperandRef::from_const(bx, value, ret_ty).immediate_or_packed_pair(bx)
} }
sym::arith_offset => { sym::arith_offset => {
let ty = substs.type_at(0); let ty = fn_args.type_at(0);
let layout = bx.layout_of(ty); let layout = bx.layout_of(ty);
let ptr = args[0].immediate(); let ptr = args[0].immediate();
let offset = args[1].immediate(); let offset = args[1].immediate();
@ -147,7 +147,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx, bx,
true, true,
false, false,
substs.type_at(0), fn_args.type_at(0),
args[1].immediate(), args[1].immediate(),
args[0].immediate(), args[0].immediate(),
args[2].immediate(), args[2].immediate(),
@ -158,7 +158,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
memset_intrinsic( memset_intrinsic(
bx, bx,
false, false,
substs.type_at(0), fn_args.type_at(0),
args[0].immediate(), args[0].immediate(),
args[1].immediate(), args[1].immediate(),
args[2].immediate(), args[2].immediate(),
@ -171,7 +171,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx, bx,
false, false,
true, true,
substs.type_at(0), fn_args.type_at(0),
args[0].immediate(), args[0].immediate(),
args[1].immediate(), args[1].immediate(),
args[2].immediate(), args[2].immediate(),
@ -183,7 +183,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx, bx,
true, true,
true, true,
substs.type_at(0), fn_args.type_at(0),
args[0].immediate(), args[0].immediate(),
args[1].immediate(), args[1].immediate(),
args[2].immediate(), args[2].immediate(),
@ -194,7 +194,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
memset_intrinsic( memset_intrinsic(
bx, bx,
true, true,
substs.type_at(0), fn_args.type_at(0),
args[0].immediate(), args[0].immediate(),
args[1].immediate(), args[1].immediate(),
args[2].immediate(), args[2].immediate(),
@ -307,7 +307,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let Some((success, failure)) = ordering.split_once('_') else { let Some((success, failure)) = ordering.split_once('_') else {
bx.sess().emit_fatal(errors::AtomicCompareExchange); bx.sess().emit_fatal(errors::AtomicCompareExchange);
}; };
let ty = substs.type_at(0); let ty = fn_args.type_at(0);
if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() { if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
let weak = instruction == "cxchgweak"; let weak = instruction == "cxchgweak";
let mut dst = args[0].immediate(); let mut dst = args[0].immediate();
@ -338,7 +338,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
} }
"load" => { "load" => {
let ty = substs.type_at(0); let ty = fn_args.type_at(0);
if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() { if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
let layout = bx.layout_of(ty); let layout = bx.layout_of(ty);
let size = layout.size; let size = layout.size;
@ -361,7 +361,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
} }
"store" => { "store" => {
let ty = substs.type_at(0); let ty = fn_args.type_at(0);
if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() { if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
let size = bx.layout_of(ty).size; let size = bx.layout_of(ty).size;
let mut val = args[1].immediate(); let mut val = args[1].immediate();
@ -407,7 +407,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
_ => bx.sess().emit_fatal(errors::UnknownAtomicOperation), _ => bx.sess().emit_fatal(errors::UnknownAtomicOperation),
}; };
let ty = substs.type_at(0); let ty = fn_args.type_at(0);
if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() { if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
let mut ptr = args[0].immediate(); let mut ptr = args[0].immediate();
let mut val = args[1].immediate(); let mut val = args[1].immediate();
@ -439,7 +439,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
} }
sym::ptr_offset_from | sym::ptr_offset_from_unsigned => { sym::ptr_offset_from | sym::ptr_offset_from_unsigned => {
let ty = substs.type_at(0); let ty = fn_args.type_at(0);
let pointee_size = bx.layout_of(ty).size; let pointee_size = bx.layout_of(ty).size;
let a = args[0].immediate(); let a = args[0].immediate();

View File

@ -159,7 +159,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
cx: &'a Bx::CodegenCx, cx: &'a Bx::CodegenCx,
instance: Instance<'tcx>, instance: Instance<'tcx>,
) { ) {
assert!(!instance.substs.has_infer()); assert!(!instance.args.has_infer());
let llfn = cx.get_fn(instance); let llfn = cx.get_fn(instance);

View File

@ -417,12 +417,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
} }
mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => { mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
match *operand.layout.ty.kind() { match *operand.layout.ty.kind() {
ty::FnDef(def_id, substs) => { ty::FnDef(def_id, args) => {
let instance = ty::Instance::resolve_for_fn_ptr( let instance = ty::Instance::resolve_for_fn_ptr(
bx.tcx(), bx.tcx(),
ty::ParamEnv::reveal_all(), ty::ParamEnv::reveal_all(),
def_id, def_id,
substs, args,
) )
.unwrap() .unwrap()
.polymorphize(bx.cx().tcx()); .polymorphize(bx.cx().tcx());
@ -433,11 +433,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
} }
mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)) => { mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)) => {
match *operand.layout.ty.kind() { match *operand.layout.ty.kind() {
ty::Closure(def_id, substs) => { ty::Closure(def_id, args) => {
let instance = Instance::resolve_closure( let instance = Instance::resolve_closure(
bx.cx().tcx(), bx.cx().tcx(),
def_id, def_id,
substs, args,
ty::ClosureKind::FnOnce, ty::ClosureKind::FnOnce,
) )
.expect("failed to normalize and resolve closure during codegen") .expect("failed to normalize and resolve closure during codegen")
@ -711,7 +711,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
{ {
let instance = ty::Instance { let instance = ty::Instance {
def: ty::InstanceDef::ThreadLocalShim(def_id), def: ty::InstanceDef::ThreadLocalShim(def_id),
substs: ty::InternalSubsts::empty(), args: ty::GenericArgs::empty(),
}; };
let fn_ptr = bx.get_fn_addr(instance); let fn_ptr = bx.get_fn_addr(instance);
let fn_abi = bx.fn_abi_of_instance(instance, ty::List::empty()); let fn_abi = bx.fn_abi_of_instance(instance, ty::List::empty());

View File

@ -64,7 +64,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
.typeck_body(anon_const.body) .typeck_body(anon_const.body)
.node_type(anon_const.hir_id); .node_type(anon_const.hir_id);
let instance = match ty.kind() { let instance = match ty.kind() {
&ty::FnDef(def_id, substs) => Instance::new(def_id, substs), &ty::FnDef(def_id, args) => Instance::new(def_id, args),
_ => span_bug!(*op_sp, "asm sym is not a function"), _ => span_bug!(*op_sp, "asm sym is not a function"),
}; };
@ -138,7 +138,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
fn to_raw_string(&self) -> String { fn to_raw_string(&self) -> String {
match *self { match *self {
MonoItem::Fn(instance) => { MonoItem::Fn(instance) => {
format!("Fn({:?}, {})", instance.def, instance.substs.as_ptr().addr()) format!("Fn({:?}, {})", instance.def, instance.args.as_ptr().addr())
} }
MonoItem::Static(id) => format!("Static({:?})", id), MonoItem::Static(id) => format!("Static({:?})", id),
MonoItem::GlobalAsm(id) => format!("GlobalAsm({:?})", id), MonoItem::GlobalAsm(id) => format!("GlobalAsm({:?})", id),

View File

@ -45,7 +45,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
"Unexpected DefKind: {:?}", "Unexpected DefKind: {:?}",
ecx.tcx.def_kind(cid.instance.def_id()) ecx.tcx.def_kind(cid.instance.def_id())
); );
let layout = ecx.layout_of(body.bound_return_ty().subst(tcx, cid.instance.substs))?; let layout = ecx.layout_of(body.bound_return_ty().instantiate(tcx, cid.instance.args))?;
assert!(layout.is_sized()); assert!(layout.is_sized());
let ret = ecx.allocate(layout, MemoryKind::Stack)?; let ret = ecx.allocate(layout, MemoryKind::Stack)?;
@ -245,10 +245,10 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
// Catch such calls and evaluate them instead of trying to load a constant's MIR. // Catch such calls and evaluate them instead of trying to load a constant's MIR.
if let ty::InstanceDef::Intrinsic(def_id) = key.value.instance.def { if let ty::InstanceDef::Intrinsic(def_id) = key.value.instance.def {
let ty = key.value.instance.ty(tcx, key.param_env); let ty = key.value.instance.ty(tcx, key.param_env);
let ty::FnDef(_, substs) = ty.kind() else { let ty::FnDef(_, args) = ty.kind() else {
bug!("intrinsic with type {:?}", ty); bug!("intrinsic with type {:?}", ty);
}; };
return eval_nullary_intrinsic(tcx, key.param_env, def_id, substs).map_err(|error| { return eval_nullary_intrinsic(tcx, key.param_env, def_id, args).map_err(|error| {
let span = tcx.def_span(def_id); let span = tcx.def_span(def_id);
super::report( super::report(
@ -328,10 +328,10 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
("static", String::new()) ("static", String::new())
} else { } else {
// If the current item has generics, we'd like to enrich the message with the // If the current item has generics, we'd like to enrich the message with the
// instance and its substs: to show the actual compile-time values, in addition to // instance and its args: to show the actual compile-time values, in addition to
// the expression, leading to the const eval error. // the expression, leading to the const eval error.
let instance = &key.value.instance; let instance = &key.value.instance;
if !instance.substs.is_empty() { if !instance.args.is_empty() {
let instance = with_no_trimmed_paths!(instance.to_string()); let instance = with_no_trimmed_paths!(instance.to_string());
("const_with_path", instance) ("const_with_path", instance)
} else { } else {

View File

@ -230,7 +230,7 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> {
*self.tcx, *self.tcx,
ty::ParamEnv::reveal_all(), ty::ParamEnv::reveal_all(),
const_def_id, const_def_id,
instance.substs, instance.args,
) )
.unwrap() .unwrap()
.unwrap(); .unwrap();

View File

@ -105,7 +105,7 @@ pub(crate) fn try_destructure_mir_constant_for_diagnostics<'tcx>(
let down = ecx.operand_downcast(&op, variant).ok()?; let down = ecx.operand_downcast(&op, variant).ok()?;
(def.variants()[variant].fields.len(), Some(variant), down) (def.variants()[variant].fields.len(), Some(variant), down)
} }
ty::Tuple(substs) => (substs.len(), None, op), ty::Tuple(args) => (args.len(), None, op),
_ => bug!("cannot destructure mir constant {:?}", val), _ => bug!("cannot destructure mir constant {:?}", val),
}; };

View File

@ -416,9 +416,9 @@ fn valtree_into_mplace<'tcx>(
debug!(?unsized_inner_ty); debug!(?unsized_inner_ty);
let inner_ty = match ty.kind() { let inner_ty = match ty.kind() {
ty::Adt(def, substs) => { ty::Adt(def, args) => {
let i = FieldIdx::from_usize(i); let i = FieldIdx::from_usize(i);
def.variant(FIRST_VARIANT).fields[i].ty(tcx, substs) def.variant(FIRST_VARIANT).fields[i].ty(tcx, args)
} }
ty::Tuple(inner_tys) => inner_tys[i], ty::Tuple(inner_tys) => inner_tys[i],
_ => bug!("unexpected unsized type {:?}", ty), _ => bug!("unexpected unsized type {:?}", ty),

View File

@ -75,12 +75,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// The src operand does not matter, just its type // The src operand does not matter, just its type
match *src.layout.ty.kind() { match *src.layout.ty.kind() {
ty::FnDef(def_id, substs) => { ty::FnDef(def_id, args) => {
let instance = ty::Instance::resolve_for_fn_ptr( let instance = ty::Instance::resolve_for_fn_ptr(
*self.tcx, *self.tcx,
self.param_env, self.param_env,
def_id, def_id,
substs, args,
) )
.ok_or_else(|| err_inval!(TooGeneric))?; .ok_or_else(|| err_inval!(TooGeneric))?;
@ -108,11 +108,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// The src operand does not matter, just its type // The src operand does not matter, just its type
match *src.layout.ty.kind() { match *src.layout.ty.kind() {
ty::Closure(def_id, substs) => { ty::Closure(def_id, args) => {
let instance = ty::Instance::resolve_closure( let instance = ty::Instance::resolve_closure(
*self.tcx, *self.tcx,
def_id, def_id,
substs, args,
ty::ClosureKind::FnOnce, ty::ClosureKind::FnOnce,
) )
.ok_or_else(|| err_inval!(TooGeneric))?; .ok_or_else(|| err_inval!(TooGeneric))?;

View File

@ -164,11 +164,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
ty::Adt(adt, _) => { ty::Adt(adt, _) => {
adt.discriminants(*self.tcx).find(|(_, var)| var.val == discr_bits) adt.discriminants(*self.tcx).find(|(_, var)| var.val == discr_bits)
} }
ty::Generator(def_id, substs, _) => { ty::Generator(def_id, args, _) => {
let substs = substs.as_generator(); let args = args.as_generator();
substs args.discriminants(def_id, *self.tcx).find(|(_, var)| var.val == discr_bits)
.discriminants(def_id, *self.tcx)
.find(|(_, var)| var.val == discr_bits)
} }
_ => span_bug!(self.cur_span(), "tagged layout for non-adt non-generator"), _ => span_bug!(self.cur_span(), "tagged layout for non-adt non-generator"),
} }

View File

@ -13,7 +13,7 @@ use rustc_middle::ty::layout::{
self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers, self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers,
TyAndLayout, TyAndLayout,
}; };
use rustc_middle::ty::{self, subst::SubstsRef, ParamEnv, Ty, TyCtxt, TypeFoldable}; use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt, TypeFoldable};
use rustc_mir_dataflow::storage::always_storage_live_locals; use rustc_mir_dataflow::storage::always_storage_live_locals;
use rustc_session::Limit; use rustc_session::Limit;
use rustc_span::Span; use rustc_span::Span;
@ -91,7 +91,7 @@ pub struct Frame<'mir, 'tcx, Prov: Provenance = AllocId, Extra = ()> {
/// The MIR for the function called on this frame. /// The MIR for the function called on this frame.
pub body: &'mir mir::Body<'tcx>, pub body: &'mir mir::Body<'tcx>,
/// The def_id and substs of the current function. /// The def_id and args of the current function.
pub instance: ty::Instance<'tcx>, pub instance: ty::Instance<'tcx>,
/// Extra data for the machine. /// Extra data for the machine.
@ -529,16 +529,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
.map_err(|_| err_inval!(TooGeneric)) .map_err(|_| err_inval!(TooGeneric))
} }
/// The `substs` are assumed to already be in our interpreter "universe" (param_env). /// The `args` are assumed to already be in our interpreter "universe" (param_env).
pub(super) fn resolve( pub(super) fn resolve(
&self, &self,
def: DefId, def: DefId,
substs: SubstsRef<'tcx>, args: GenericArgsRef<'tcx>,
) -> InterpResult<'tcx, ty::Instance<'tcx>> { ) -> InterpResult<'tcx, ty::Instance<'tcx>> {
trace!("resolve: {:?}, {:#?}", def, substs); trace!("resolve: {:?}, {:#?}", def, args);
trace!("param_env: {:#?}", self.param_env); trace!("param_env: {:#?}", self.param_env);
trace!("substs: {:#?}", substs); trace!("args: {:#?}", args);
match ty::Instance::resolve(*self.tcx, self.param_env, def, substs) { match ty::Instance::resolve(*self.tcx, self.param_env, def, args) {
Ok(Some(instance)) => Ok(instance), Ok(Some(instance)) => Ok(instance),
Ok(None) => throw_inval!(TooGeneric), Ok(None) => throw_inval!(TooGeneric),
@ -684,7 +684,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
return_to_block: StackPopCleanup, return_to_block: StackPopCleanup,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
trace!("body: {:#?}", body); trace!("body: {:#?}", body);
// First push a stack frame so we have access to the local substs // First push a stack frame so we have access to the local args
let pre_frame = Frame { let pre_frame = Frame {
body, body,
loc: Right(body.span), // Span used for errors caused during preamble. loc: Right(body.span), // Span used for errors caused during preamble.

View File

@ -12,7 +12,7 @@ use rustc_middle::mir::{
}; };
use rustc_middle::ty; use rustc_middle::ty;
use rustc_middle::ty::layout::{LayoutOf as _, ValidityRequirement}; use rustc_middle::ty::layout::{LayoutOf as _, ValidityRequirement};
use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{Ty, TyCtxt}; use rustc_middle::ty::{Ty, TyCtxt};
use rustc_span::symbol::{sym, Symbol}; use rustc_span::symbol::{sym, Symbol};
use rustc_target::abi::{Abi, Align, Primitive, Size}; use rustc_target::abi::{Abi, Align, Primitive, Size};
@ -56,9 +56,9 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
def_id: DefId, def_id: DefId,
substs: SubstsRef<'tcx>, args: GenericArgsRef<'tcx>,
) -> InterpResult<'tcx, ConstValue<'tcx>> { ) -> InterpResult<'tcx, ConstValue<'tcx>> {
let tp_ty = substs.type_at(0); let tp_ty = args.type_at(0);
let name = tcx.item_name(def_id); let name = tcx.item_name(def_id);
Ok(match name { Ok(match name {
sym::type_name => { sym::type_name => {
@ -123,7 +123,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
dest: &PlaceTy<'tcx, M::Provenance>, dest: &PlaceTy<'tcx, M::Provenance>,
ret: Option<mir::BasicBlock>, ret: Option<mir::BasicBlock>,
) -> InterpResult<'tcx, bool> { ) -> InterpResult<'tcx, bool> {
let substs = instance.substs; let instance_args = instance.args;
let intrinsic_name = self.tcx.item_name(instance.def_id()); let intrinsic_name = self.tcx.item_name(instance.def_id());
// First handle intrinsics without return place. // First handle intrinsics without return place.
@ -187,7 +187,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
| sym::ctlz_nonzero | sym::ctlz_nonzero
| sym::bswap | sym::bswap
| sym::bitreverse => { | sym::bitreverse => {
let ty = substs.type_at(0); let ty = instance_args.type_at(0);
let layout_of = self.layout_of(ty)?; let layout_of = self.layout_of(ty)?;
let val = self.read_scalar(&args[0])?; let val = self.read_scalar(&args[0])?;
let bits = val.to_bits(layout_of.size)?; let bits = val.to_bits(layout_of.size)?;
@ -237,7 +237,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
sym::rotate_left | sym::rotate_right => { sym::rotate_left | sym::rotate_right => {
// rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW)) // rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW))
// rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW)) // rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
let layout = self.layout_of(substs.type_at(0))?; let layout = self.layout_of(instance_args.type_at(0))?;
let val = self.read_scalar(&args[0])?; let val = self.read_scalar(&args[0])?;
let val_bits = val.to_bits(layout.size)?; let val_bits = val.to_bits(layout.size)?;
let raw_shift = self.read_scalar(&args[1])?; let raw_shift = self.read_scalar(&args[1])?;
@ -263,7 +263,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
sym::arith_offset => { sym::arith_offset => {
let ptr = self.read_pointer(&args[0])?; let ptr = self.read_pointer(&args[0])?;
let offset_count = self.read_target_isize(&args[1])?; let offset_count = self.read_target_isize(&args[1])?;
let pointee_ty = substs.type_at(0); let pointee_ty = instance_args.type_at(0);
let pointee_size = i64::try_from(self.layout_of(pointee_ty)?.size.bytes()).unwrap(); let pointee_size = i64::try_from(self.layout_of(pointee_ty)?.size.bytes()).unwrap();
let offset_bytes = offset_count.wrapping_mul(pointee_size); let offset_bytes = offset_count.wrapping_mul(pointee_size);
@ -368,7 +368,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
assert!(self.target_isize_min() <= dist && dist <= self.target_isize_max()); assert!(self.target_isize_min() <= dist && dist <= self.target_isize_max());
isize_layout isize_layout
}; };
let pointee_layout = self.layout_of(substs.type_at(0))?; let pointee_layout = self.layout_of(instance_args.type_at(0))?;
// If ret_layout is unsigned, we checked that so is the distance, so we are good. // If ret_layout is unsigned, we checked that so is the distance, so we are good.
let val = ImmTy::from_int(dist, ret_layout); let val = ImmTy::from_int(dist, ret_layout);
let size = ImmTy::from_int(pointee_layout.size.bytes(), ret_layout); let size = ImmTy::from_int(pointee_layout.size.bytes(), ret_layout);
@ -378,7 +378,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
sym::assert_inhabited sym::assert_inhabited
| sym::assert_zero_valid | sym::assert_zero_valid
| sym::assert_mem_uninitialized_valid => { | sym::assert_mem_uninitialized_valid => {
let ty = instance.substs.type_at(0); let ty = instance.args.type_at(0);
let requirement = ValidityRequirement::from_intrinsic(intrinsic_name).unwrap(); let requirement = ValidityRequirement::from_intrinsic(intrinsic_name).unwrap();
let should_panic = !self let should_panic = !self

View File

@ -96,7 +96,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let loc_ty = self let loc_ty = self
.tcx .tcx
.type_of(self.tcx.require_lang_item(LangItem::PanicLocation, None)) .type_of(self.tcx.require_lang_item(LangItem::PanicLocation, None))
.subst(*self.tcx, self.tcx.mk_substs(&[self.tcx.lifetimes.re_erased.into()])); .instantiate(*self.tcx, self.tcx.mk_args(&[self.tcx.lifetimes.re_erased.into()]));
let loc_layout = self.layout_of(loc_ty).unwrap(); let loc_layout = self.layout_of(loc_ty).unwrap();
let location = self.allocate(loc_layout, MemoryKind::CallerLocation).unwrap(); let location = self.allocate(loc_layout, MemoryKind::CallerLocation).unwrap();

View File

@ -590,7 +590,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
throw_inval!(AlreadyReported(reported.into())) throw_inval!(AlreadyReported(reported.into()))
} }
ty::ConstKind::Unevaluated(uv) => { ty::ConstKind::Unevaluated(uv) => {
let instance = self.resolve(uv.def, uv.substs)?; let instance = self.resolve(uv.def, uv.args)?;
let cid = GlobalId { instance, promoted: None }; let cid = GlobalId { instance, promoted: None };
self.ctfe_query(span, |tcx| { self.ctfe_query(span, |tcx| {
tcx.eval_to_valtree(self.param_env.with_const().and(cid)) tcx.eval_to_valtree(self.param_env.with_const().and(cid))
@ -619,7 +619,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
} }
mir::ConstantKind::Val(val, ty) => self.const_val_to_op(val, ty, layout), mir::ConstantKind::Val(val, ty) => self.const_val_to_op(val, ty, layout),
mir::ConstantKind::Unevaluated(uv, _) => { mir::ConstantKind::Unevaluated(uv, _) => {
let instance = self.resolve(uv.def, uv.substs)?; let instance = self.resolve(uv.def, uv.args)?;
Ok(self.eval_global(GlobalId { instance, promoted: uv.promoted }, span)?.into()) Ok(self.eval_global(GlobalId { instance, promoted: uv.promoted }, span)?.into())
} }
} }

View File

@ -135,8 +135,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let fn_val = self.get_ptr_fn(fn_ptr)?; let fn_val = self.get_ptr_fn(fn_ptr)?;
(fn_val, self.fn_abi_of_fn_ptr(fn_sig_binder, extra_args)?, false) (fn_val, self.fn_abi_of_fn_ptr(fn_sig_binder, extra_args)?, false)
} }
ty::FnDef(def_id, substs) => { ty::FnDef(def_id, args) => {
let instance = self.resolve(def_id, substs)?; let instance = self.resolve(def_id, args)?;
( (
FnVal::Instance(instance), FnVal::Instance(instance),
self.fn_abi_of_instance(instance, extra_args)?, self.fn_abi_of_instance(instance, extra_args)?,
@ -748,7 +748,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let trait_def_id = tcx.trait_of_item(def_id).unwrap(); let trait_def_id = tcx.trait_of_item(def_id).unwrap();
let virtual_trait_ref = let virtual_trait_ref =
ty::TraitRef::from_method(tcx, trait_def_id, instance.substs); ty::TraitRef::from_method(tcx, trait_def_id, instance.args);
let existential_trait_ref = let existential_trait_ref =
ty::ExistentialTraitRef::erase_self_ty(tcx, virtual_trait_ref); ty::ExistentialTraitRef::erase_self_ty(tcx, virtual_trait_ref);
let concrete_trait_ref = existential_trait_ref.with_self_ty(tcx, dyn_ty); let concrete_trait_ref = existential_trait_ref.with_self_ty(tcx, dyn_ty);
@ -757,7 +757,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
tcx, tcx,
self.param_env, self.param_env,
def_id, def_id,
instance.substs.rebase_onto(tcx, trait_def_id, concrete_trait_ref.substs), instance.args.rebase_onto(tcx, trait_def_id, concrete_trait_ref.args),
) )
.unwrap(); .unwrap();
assert_eq!(fn_inst, concrete_method); assert_eq!(fn_inst, concrete_method);

View File

@ -33,12 +33,12 @@ where
match *ty.kind() { match *ty.kind() {
ty::Param(_) => ControlFlow::Break(FoundParam), ty::Param(_) => ControlFlow::Break(FoundParam),
ty::Closure(def_id, substs) ty::Closure(def_id, args)
| ty::Generator(def_id, substs, ..) | ty::Generator(def_id, args, ..)
| ty::FnDef(def_id, substs) => { | ty::FnDef(def_id, args) => {
let instance = ty::InstanceDef::Item(def_id); let instance = ty::InstanceDef::Item(def_id);
let unused_params = self.tcx.unused_generic_params(instance); let unused_params = self.tcx.unused_generic_params(instance);
for (index, subst) in substs.into_iter().enumerate() { for (index, subst) in args.into_iter().enumerate() {
let index = index let index = index
.try_into() .try_into()
.expect("more generic parameters than can fit into a `u32`"); .expect("more generic parameters than can fit into a `u32`");

View File

@ -8,8 +8,8 @@ use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::{ImplSource, Obligation, ObligationCause}; use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
use rustc_middle::ty::{self, adjustment::PointerCoercion, Instance, InstanceDef, Ty, TyCtxt}; use rustc_middle::ty::{self, adjustment::PointerCoercion, Instance, InstanceDef, Ty, TyCtxt};
use rustc_middle::ty::{GenericArgKind, GenericArgs};
use rustc_middle::ty::{TraitRef, TypeVisitableExt}; use rustc_middle::ty::{TraitRef, TypeVisitableExt};
use rustc_mir_dataflow::{self, Analysis}; use rustc_mir_dataflow::{self, Analysis};
use rustc_span::{sym, Span, Symbol}; use rustc_span::{sym, Span, Symbol};
@ -701,8 +701,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
let fn_ty = func.ty(body, tcx); let fn_ty = func.ty(body, tcx);
let (mut callee, mut substs) = match *fn_ty.kind() { let (mut callee, mut fn_args) = match *fn_ty.kind() {
ty::FnDef(def_id, substs) => (def_id, substs), ty::FnDef(def_id, fn_args) => (def_id, fn_args),
ty::FnPtr(_) => { ty::FnPtr(_) => {
self.check_op(ops::FnCallIndirect); self.check_op(ops::FnCallIndirect);
@ -721,7 +721,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
let infcx = tcx.infer_ctxt().build(); let infcx = tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx); let ocx = ObligationCtxt::new(&infcx);
let predicates = tcx.predicates_of(callee).instantiate(tcx, substs); let predicates = tcx.predicates_of(callee).instantiate(tcx, fn_args);
let cause = ObligationCause::new( let cause = ObligationCause::new(
terminator.source_info.span, terminator.source_info.span,
self.body.source.def_id().expect_local(), self.body.source.def_id().expect_local(),
@ -746,7 +746,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
self.check_op(ops::FnCallNonConst { self.check_op(ops::FnCallNonConst {
caller, caller,
callee, callee,
substs, args: fn_args,
span: *fn_span, span: *fn_span,
call_source: *call_source, call_source: *call_source,
feature: Some(sym::const_trait_impl), feature: Some(sym::const_trait_impl),
@ -754,7 +754,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
return; return;
} }
let trait_ref = TraitRef::from_method(tcx, trait_id, substs); let trait_ref = TraitRef::from_method(tcx, trait_id, fn_args);
let trait_ref = trait_ref.with_constness(ty::BoundConstness::ConstIfConst); let trait_ref = trait_ref.with_constness(ty::BoundConstness::ConstIfConst);
let obligation = let obligation =
Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref); Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref);
@ -778,7 +778,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
if trait_ref.self_ty().is_closure() if trait_ref.self_ty().is_closure()
&& tcx.fn_trait_kind_from_def_id(trait_id).is_some() => && tcx.fn_trait_kind_from_def_id(trait_id).is_some() =>
{ {
let ty::Closure(closure_def_id, substs) = *trait_ref.self_ty().kind() let ty::Closure(closure_def_id, fn_args) = *trait_ref.self_ty().kind()
else { else {
unreachable!() unreachable!()
}; };
@ -786,7 +786,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
self.check_op(ops::FnCallNonConst { self.check_op(ops::FnCallNonConst {
caller, caller,
callee, callee,
substs, args: fn_args,
span: *fn_span, span: *fn_span,
call_source: *call_source, call_source: *call_source,
feature: None, feature: None,
@ -802,9 +802,9 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
.iter() .iter()
.find(|did| tcx.item_name(**did) == callee_name) .find(|did| tcx.item_name(**did) == callee_name)
{ {
// using internal substs is ok here, since this is only // using internal args is ok here, since this is only
// used for the `resolve` call below // used for the `resolve` call below
substs = InternalSubsts::identity_for_item(tcx, did); fn_args = GenericArgs::identity_for_item(tcx, did);
callee = did; callee = did;
} }
@ -812,7 +812,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
self.check_op(ops::FnCallNonConst { self.check_op(ops::FnCallNonConst {
caller, caller,
callee, callee,
substs, args: fn_args,
span: *fn_span, span: *fn_span,
call_source: *call_source, call_source: *call_source,
feature: None, feature: None,
@ -828,7 +828,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
&& tcx.has_attr(callee_trait, sym::const_trait) && tcx.has_attr(callee_trait, sym::const_trait)
&& Some(callee_trait) == tcx.trait_of_item(caller.to_def_id()) && Some(callee_trait) == tcx.trait_of_item(caller.to_def_id())
// Can only call methods when it's `<Self as TheTrait>::f`. // Can only call methods when it's `<Self as TheTrait>::f`.
&& tcx.types.self_param == substs.type_at(0) && tcx.types.self_param == fn_args.type_at(0)
{ {
nonconst_call_permission = true; nonconst_call_permission = true;
} }
@ -855,7 +855,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
self.check_op(ops::FnCallNonConst { self.check_op(ops::FnCallNonConst {
caller, caller,
callee, callee,
substs, args: fn_args,
span: *fn_span, span: *fn_span,
call_source: *call_source, call_source: *call_source,
feature: None, feature: None,
@ -868,7 +868,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
// Resolve a trait method call to its concrete implementation, which may be in a // Resolve a trait method call to its concrete implementation, which may be in a
// `const` trait impl. // `const` trait impl.
let instance = Instance::resolve(tcx, param_env, callee, substs); let instance = Instance::resolve(tcx, param_env, callee, fn_args);
debug!("Resolving ({:?}) -> {:?}", callee, instance); debug!("Resolving ({:?}) -> {:?}", callee, instance);
if let Ok(Some(func)) = instance { if let Ok(Some(func)) = instance {
if let InstanceDef::Item(def) = func.def { if let InstanceDef::Item(def) = func.def {
@ -915,7 +915,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
self.check_op(ops::FnCallNonConst { self.check_op(ops::FnCallNonConst {
caller, caller,
callee, callee,
substs, args: fn_args,
span: *fn_span, span: *fn_span,
call_source: *call_source, call_source: *call_source,
feature: None, feature: None,

View File

@ -68,11 +68,11 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> {
pub fn fn_sig(&self) -> PolyFnSig<'tcx> { pub fn fn_sig(&self) -> PolyFnSig<'tcx> {
let did = self.def_id().to_def_id(); let did = self.def_id().to_def_id();
if self.tcx.is_closure(did) { if self.tcx.is_closure(did) {
let ty = self.tcx.type_of(did).subst_identity(); let ty = self.tcx.type_of(did).instantiate_identity();
let ty::Closure(_, substs) = ty.kind() else { bug!("type_of closure not ty::Closure") }; let ty::Closure(_, args) = ty.kind() else { bug!("type_of closure not ty::Closure") };
substs.as_closure().sig() args.as_closure().sig()
} else { } else {
self.tcx.fn_sig(did).subst_identity() self.tcx.fn_sig(did).instantiate_identity()
} }
} }
} }

View File

@ -9,9 +9,9 @@ use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::{ImplSource, Obligation, ObligationCause}; use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
use rustc_middle::mir::{self, CallSource}; use rustc_middle::mir::{self, CallSource};
use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
use rustc_middle::ty::TraitRef; use rustc_middle::ty::TraitRef;
use rustc_middle::ty::{suggest_constraining_type_param, Adt, Closure, FnDef, FnPtr, Param, Ty}; use rustc_middle::ty::{suggest_constraining_type_param, Adt, Closure, FnDef, FnPtr, Param, Ty};
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
use rustc_middle::util::{call_kind, CallDesugaringKind, CallKind}; use rustc_middle::util::{call_kind, CallDesugaringKind, CallKind};
use rustc_session::parse::feature_err; use rustc_session::parse::feature_err;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
@ -98,7 +98,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallIndirect {
pub struct FnCallNonConst<'tcx> { pub struct FnCallNonConst<'tcx> {
pub caller: LocalDefId, pub caller: LocalDefId,
pub callee: DefId, pub callee: DefId,
pub substs: SubstsRef<'tcx>, pub args: GenericArgsRef<'tcx>,
pub span: Span, pub span: Span,
pub call_source: CallSource, pub call_source: CallSource,
pub feature: Option<Symbol>, pub feature: Option<Symbol>,
@ -110,11 +110,11 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
ccx: &ConstCx<'_, 'tcx>, ccx: &ConstCx<'_, 'tcx>,
_: Span, _: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let FnCallNonConst { caller, callee, substs, span, call_source, feature } = *self; let FnCallNonConst { caller, callee, args, span, call_source, feature } = *self;
let ConstCx { tcx, param_env, .. } = *ccx; let ConstCx { tcx, param_env, .. } = *ccx;
let diag_trait = |err, self_ty: Ty<'_>, trait_id| { let diag_trait = |err, self_ty: Ty<'_>, trait_id| {
let trait_ref = TraitRef::from_method(tcx, trait_id, substs); let trait_ref = TraitRef::from_method(tcx, trait_id, args);
match self_ty.kind() { match self_ty.kind() {
Param(param_ty) => { Param(param_ty) => {
@ -154,7 +154,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
}; };
let call_kind = let call_kind =
call_kind(tcx, ccx.param_env, callee, substs, span, call_source.from_hir_call(), None); call_kind(tcx, ccx.param_env, callee, args, span, call_source.from_hir_call(), None);
debug!(?call_kind); debug!(?call_kind);
@ -226,7 +226,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
let mut sugg = None; let mut sugg = None;
if Some(trait_id) == ccx.tcx.lang_items().eq_trait() { if Some(trait_id) == ccx.tcx.lang_items().eq_trait() {
match (substs[0].unpack(), substs[1].unpack()) { match (args[0].unpack(), args[1].unpack()) {
(GenericArgKind::Type(self_ty), GenericArgKind::Type(rhs_ty)) (GenericArgKind::Type(self_ty), GenericArgKind::Type(rhs_ty))
if self_ty == rhs_ty if self_ty == rhs_ty
&& self_ty.is_ref() && self_ty.is_ref()
@ -297,7 +297,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
.create_err(errors::NonConstFmtMacroCall { span, kind: ccx.const_kind() }), .create_err(errors::NonConstFmtMacroCall { span, kind: ccx.const_kind() }),
_ => ccx.tcx.sess.create_err(errors::NonConstFnCall { _ => ccx.tcx.sess.create_err(errors::NonConstFnCall {
span, span,
def_path_str: ccx.tcx.def_path_str_with_substs(callee, substs), def_path_str: ccx.tcx.def_path_str_with_args(callee, args),
kind: ccx.const_kind(), kind: ccx.const_kind(),
}), }),
}; };

View File

@ -7,7 +7,7 @@ use rustc_hir::LangItem;
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::mir; use rustc_middle::mir;
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty::{self, subst::SubstsRef, AdtDef, Ty}; use rustc_middle::ty::{self, AdtDef, GenericArgsRef, Ty};
use rustc_trait_selection::traits::{ use rustc_trait_selection::traits::{
self, ImplSource, Obligation, ObligationCause, ObligationCtxt, SelectionContext, self, ImplSource, Obligation, ObligationCause, ObligationCtxt, SelectionContext,
}; };
@ -72,7 +72,7 @@ pub trait Qualif {
fn in_adt_inherently<'tcx>( fn in_adt_inherently<'tcx>(
cx: &ConstCx<'_, 'tcx>, cx: &ConstCx<'_, 'tcx>,
adt: AdtDef<'tcx>, adt: AdtDef<'tcx>,
substs: SubstsRef<'tcx>, args: GenericArgsRef<'tcx>,
) -> bool; ) -> bool;
} }
@ -97,7 +97,7 @@ impl Qualif for HasMutInterior {
fn in_adt_inherently<'tcx>( fn in_adt_inherently<'tcx>(
_cx: &ConstCx<'_, 'tcx>, _cx: &ConstCx<'_, 'tcx>,
adt: AdtDef<'tcx>, adt: AdtDef<'tcx>,
_: SubstsRef<'tcx>, _: GenericArgsRef<'tcx>,
) -> bool { ) -> bool {
// Exactly one type, `UnsafeCell`, has the `HasMutInterior` qualif inherently. // Exactly one type, `UnsafeCell`, has the `HasMutInterior` qualif inherently.
// It arises structurally for all other types. // It arises structurally for all other types.
@ -127,7 +127,7 @@ impl Qualif for NeedsDrop {
fn in_adt_inherently<'tcx>( fn in_adt_inherently<'tcx>(
cx: &ConstCx<'_, 'tcx>, cx: &ConstCx<'_, 'tcx>,
adt: AdtDef<'tcx>, adt: AdtDef<'tcx>,
_: SubstsRef<'tcx>, _: GenericArgsRef<'tcx>,
) -> bool { ) -> bool {
adt.has_dtor(cx.tcx) adt.has_dtor(cx.tcx)
} }
@ -193,7 +193,7 @@ impl Qualif for NeedsNonConstDrop {
fn in_adt_inherently<'tcx>( fn in_adt_inherently<'tcx>(
cx: &ConstCx<'_, 'tcx>, cx: &ConstCx<'_, 'tcx>,
adt: AdtDef<'tcx>, adt: AdtDef<'tcx>,
_: SubstsRef<'tcx>, _: GenericArgsRef<'tcx>,
) -> bool { ) -> bool {
adt.has_non_const_dtor(cx.tcx) adt.has_non_const_dtor(cx.tcx)
} }
@ -221,9 +221,9 @@ impl Qualif for CustomEq {
fn in_adt_inherently<'tcx>( fn in_adt_inherently<'tcx>(
cx: &ConstCx<'_, 'tcx>, cx: &ConstCx<'_, 'tcx>,
def: AdtDef<'tcx>, def: AdtDef<'tcx>,
substs: SubstsRef<'tcx>, args: GenericArgsRef<'tcx>,
) -> bool { ) -> bool {
let ty = Ty::new_adt(cx.tcx, def, substs); let ty = Ty::new_adt(cx.tcx, def, args);
!ty.is_structural_eq_shallow(cx.tcx) !ty.is_structural_eq_shallow(cx.tcx)
} }
} }
@ -276,9 +276,9 @@ where
Rvalue::Aggregate(kind, operands) => { Rvalue::Aggregate(kind, operands) => {
// Return early if we know that the struct or enum being constructed is always // Return early if we know that the struct or enum being constructed is always
// qualified. // qualified.
if let AggregateKind::Adt(adt_did, _, substs, ..) = **kind { if let AggregateKind::Adt(adt_did, _, args, ..) = **kind {
let def = cx.tcx.adt_def(adt_did); let def = cx.tcx.adt_def(adt_did);
if Q::in_adt_inherently(cx, def, substs) { if Q::in_adt_inherently(cx, def, args) {
return true; return true;
} }
if def.is_union() && Q::in_any_value_of_ty(cx, rvalue.ty(cx.body, cx.tcx)) { if def.is_union() && Q::in_any_value_of_ty(cx, rvalue.ty(cx.body, cx.tcx)) {
@ -360,7 +360,7 @@ where
ConstantKind::Val(..) => None, ConstantKind::Val(..) => None,
}; };
if let Some(mir::UnevaluatedConst { def, substs: _, promoted }) = uneval { if let Some(mir::UnevaluatedConst { def, args: _, promoted }) = uneval {
// Use qualifs of the type for the promoted. Promoteds in MIR body should be possible // Use qualifs of the type for the promoted. Promoteds in MIR body should be possible
// only for `NeedsNonConstDrop` with precise drop checking. This is the only const // only for `NeedsNonConstDrop` with precise drop checking. This is the only const
// check performed after the promotion. Verify that with an assertion. // check performed after the promotion. Verify that with an assertion.

View File

@ -16,7 +16,7 @@ use rustc_hir as hir;
use rustc_middle::mir; use rustc_middle::mir;
use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::GenericArgs;
use rustc_middle::ty::{self, List, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{self, List, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::Span; use rustc_span::Span;
@ -841,8 +841,8 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
let mut promoted_operand = |ty, span| { let mut promoted_operand = |ty, span| {
promoted.span = span; promoted.span = span;
promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span); promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span);
let substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def)); let args = tcx.erase_regions(GenericArgs::identity_for_item(tcx, def));
let uneval = mir::UnevaluatedConst { def, substs, promoted: Some(promoted_id) }; let uneval = mir::UnevaluatedConst { def, args, promoted: Some(promoted_id) };
Operand::Constant(Box::new(Constant { Operand::Constant(Box::new(Constant {
span, span,

View File

@ -358,8 +358,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}; };
let kind = match parent_ty.ty.kind() { let kind = match parent_ty.ty.kind() {
&ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => { &ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
self.tcx.type_of(def_id).subst(self.tcx, substs).kind() self.tcx.type_of(def_id).instantiate(self.tcx, args).kind()
} }
kind => kind, kind => kind,
}; };
@ -372,23 +372,23 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}; };
check_equal(self, location, *f_ty); check_equal(self, location, *f_ty);
} }
ty::Adt(adt_def, substs) => { ty::Adt(adt_def, args) => {
let var = parent_ty.variant_index.unwrap_or(FIRST_VARIANT); let var = parent_ty.variant_index.unwrap_or(FIRST_VARIANT);
let Some(field) = adt_def.variant(var).fields.get(f) else { let Some(field) = adt_def.variant(var).fields.get(f) else {
fail_out_of_bounds(self, location); fail_out_of_bounds(self, location);
return; return;
}; };
check_equal(self, location, field.ty(self.tcx, substs)); check_equal(self, location, field.ty(self.tcx, args));
} }
ty::Closure(_, substs) => { ty::Closure(_, args) => {
let substs = substs.as_closure(); let args = args.as_closure();
let Some(f_ty) = substs.upvar_tys().nth(f.as_usize()) else { let Some(f_ty) = args.upvar_tys().nth(f.as_usize()) else {
fail_out_of_bounds(self, location); fail_out_of_bounds(self, location);
return; return;
}; };
check_equal(self, location, f_ty); check_equal(self, location, f_ty);
} }
&ty::Generator(def_id, substs, _) => { &ty::Generator(def_id, args, _) => {
let f_ty = if let Some(var) = parent_ty.variant_index { let f_ty = if let Some(var) = parent_ty.variant_index {
let gen_body = if def_id == self.body.source.def_id() { let gen_body = if def_id == self.body.source.def_id() {
self.body self.body
@ -419,8 +419,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
f_ty.ty f_ty.ty
} else { } else {
let Some(f_ty) = substs.as_generator().prefix_tys().nth(f.index()) let Some(f_ty) = args.as_generator().prefix_tys().nth(f.index()) else {
else {
fail_out_of_bounds(self, location); fail_out_of_bounds(self, location);
return; return;
}; };
@ -735,7 +734,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty); current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty);
} }
ty::Adt(adt_def, substs) => { ty::Adt(adt_def, args) => {
if adt_def.is_enum() { if adt_def.is_enum() {
self.fail( self.fail(
location, location,
@ -749,7 +748,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
return; return;
}; };
let f_ty = field.ty(self.tcx, substs); let f_ty = field.ty(self.tcx, args);
current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty); current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty);
} }
_ => { _ => {

View File

@ -4,8 +4,7 @@ use rustc_hir::definitions::DisambiguatedDefPathData;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, self,
print::{PrettyPrinter, Print, Printer}, print::{PrettyPrinter, Print, Printer},
subst::{GenericArg, GenericArgKind}, GenericArg, GenericArgKind, Ty, TyCtxt,
Ty, TyCtxt,
}; };
use std::fmt::Write; use std::fmt::Write;
@ -56,11 +55,11 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
} }
// Types with identity (print the module path). // Types with identity (print the module path).
ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), substs) ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), args)
| ty::FnDef(def_id, substs) | ty::FnDef(def_id, args)
| ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, substs, .. }) | ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. })
| ty::Closure(def_id, substs) | ty::Closure(def_id, args)
| ty::Generator(def_id, substs, _) => self.print_def_path(def_id, substs), | ty::Generator(def_id, args, _) => self.print_def_path(def_id, args),
ty::Foreign(def_id) => self.print_def_path(def_id, &[]), ty::Foreign(def_id) => self.print_def_path(def_id, &[]),
ty::Alias(ty::Weak, _) => bug!("type_name: unexpected weak projection"), ty::Alias(ty::Weak, _) => bug!("type_name: unexpected weak projection"),

View File

@ -812,7 +812,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
TEST, rustc_error, Normal, TEST, rustc_error, Normal,
template!(Word, List: "delay_span_bug_from_inside_query"), WarnFollowingWordOnly template!(Word, List: "delay_span_bug_from_inside_query"), WarnFollowingWordOnly
), ),
rustc_attr!(TEST, rustc_dump_user_substs, Normal, template!(Word), WarnFollowing), rustc_attr!(TEST, rustc_dump_user_args, Normal, template!(Word), WarnFollowing),
rustc_attr!(TEST, rustc_evaluate_where_clauses, Normal, template!(Word), WarnFollowing), rustc_attr!(TEST, rustc_evaluate_where_clauses, Normal, template!(Word), WarnFollowing),
rustc_attr!( rustc_attr!(
TEST, rustc_if_this_changed, Normal, template!(Word, List: "DepNode"), DuplicatesOk TEST, rustc_if_this_changed, Normal, template!(Word, List: "DepNode"), DuplicatesOk

View File

@ -341,8 +341,8 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
// If we have an method return type bound, then we need to substitute // If we have an method return type bound, then we need to substitute
// the method's early bound params with suitable late-bound params. // the method's early bound params with suitable late-bound params.
let mut num_bound_vars = candidate.bound_vars().len(); let mut num_bound_vars = candidate.bound_vars().len();
let substs = let args =
candidate.skip_binder().substs.extend_to(tcx, assoc_item.def_id, |param, _| { candidate.skip_binder().args.extend_to(tcx, assoc_item.def_id, |param, _| {
let subst = match param.kind { let subst = match param.kind {
ty::GenericParamDefKind::Lifetime => ty::Region::new_late_bound( ty::GenericParamDefKind::Lifetime => ty::Region::new_late_bound(
tcx, tcx,
@ -422,7 +422,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
// params (and trait ref's late bound params). This logic is very similar to // params (and trait ref's late bound params). This logic is very similar to
// `Predicate::subst_supertrait`, and it's no coincidence why. // `Predicate::subst_supertrait`, and it's no coincidence why.
let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output); let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output);
let subst_output = ty::EarlyBinder::bind(shifted_output).subst(tcx, substs); let subst_output = ty::EarlyBinder::bind(shifted_output).instantiate(tcx, args);
let bound_vars = tcx.late_bound_vars(binding.hir_id); let bound_vars = tcx.late_bound_vars(binding.hir_id);
ty::Binder::bind_with_vars(subst_output, bound_vars) ty::Binder::bind_with_vars(subst_output, bound_vars)
@ -438,16 +438,16 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
infer_args: false, infer_args: false,
}; };
let substs_trait_ref_and_assoc_item = self.create_substs_for_associated_item( let args_trait_ref_and_assoc_item = self.create_args_for_associated_item(
path_span, path_span,
assoc_item.def_id, assoc_item.def_id,
&item_segment, &item_segment,
trait_ref.substs, trait_ref.args,
); );
debug!(?substs_trait_ref_and_assoc_item); debug!(?args_trait_ref_and_assoc_item);
tcx.mk_alias_ty(assoc_item.def_id, substs_trait_ref_and_assoc_item) tcx.mk_alias_ty(assoc_item.def_id, args_trait_ref_and_assoc_item)
}) })
}; };
@ -533,7 +533,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
tcx, tcx,
reported, reported,
tcx.type_of(assoc_item_def_id) tcx.type_of(assoc_item_def_id)
.subst(tcx, projection_ty.skip_binder().substs), .instantiate(tcx, projection_ty.skip_binder().args),
) )
.into(), .into(),
_ => unreachable!(), _ => unreachable!(),

View File

@ -247,7 +247,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
"the candidate".into() "the candidate".into()
}; };
let impl_ty = tcx.at(span).type_of(impl_).subst_identity(); let impl_ty = tcx.at(span).type_of(impl_).instantiate_identity();
let note = format!("{title} is defined in an impl for the type `{impl_ty}`"); let note = format!("{title} is defined in an impl for the type `{impl_ty}`");
if let Some(span) = note_span { if let Some(span) = note_span {
@ -295,7 +295,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let type_candidates = candidates let type_candidates = candidates
.iter() .iter()
.take(limit) .take(limit)
.map(|&(impl_, _)| format!("- `{}`", tcx.at(span).type_of(impl_).subst_identity())) .map(|&(impl_, _)| {
format!("- `{}`", tcx.at(span).type_of(impl_).instantiate_identity())
})
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join("\n"); .join("\n");
let additional_types = if candidates.len() > limit { let additional_types = if candidates.len() > limit {
@ -356,13 +358,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// `<Foo as Iterator>::Item = String`. // `<Foo as Iterator>::Item = String`.
let projection_ty = pred.skip_binder().projection_ty; let projection_ty = pred.skip_binder().projection_ty;
let substs_with_infer_self = tcx.mk_substs_from_iter( let args_with_infer_self = tcx.mk_args_from_iter(
std::iter::once(Ty::new_var(tcx, ty::TyVid::from_u32(0)).into()) std::iter::once(Ty::new_var(tcx, ty::TyVid::from_u32(0)).into())
.chain(projection_ty.substs.iter().skip(1)), .chain(projection_ty.args.iter().skip(1)),
); );
let quiet_projection_ty = let quiet_projection_ty =
tcx.mk_alias_ty(projection_ty.def_id, substs_with_infer_self); tcx.mk_alias_ty(projection_ty.def_id, args_with_infer_self);
let term = pred.skip_binder().term; let term = pred.skip_binder().term;

View File

@ -11,7 +11,7 @@ use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::GenericArg; use rustc_hir::GenericArg;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, subst, subst::SubstsRef, GenericParamDef, GenericParamDefKind, IsSuggestable, Ty, TyCtxt, self, GenericArgsRef, GenericParamDef, GenericParamDefKind, IsSuggestable, Ty, TyCtxt,
}; };
use rustc_session::lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS; use rustc_session::lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS;
use rustc_span::{symbol::kw, Span}; use rustc_span::{symbol::kw, Span};
@ -76,7 +76,7 @@ fn generic_arg_mismatch_err(
Res::Def(DefKind::TyParam, src_def_id) => { Res::Def(DefKind::TyParam, src_def_id) => {
if let Some(param_local_id) = param.def_id.as_local() { if let Some(param_local_id) = param.def_id.as_local() {
let param_name = tcx.hir().ty_param_name(param_local_id); let param_name = tcx.hir().ty_param_name(param_local_id);
let param_type = tcx.type_of(param.def_id).subst_identity(); let param_type = tcx.type_of(param.def_id).instantiate_identity();
if param_type.is_suggestable(tcx, false) { if param_type.is_suggestable(tcx, false) {
err.span_suggestion( err.span_suggestion(
tcx.def_span(src_def_id), tcx.def_span(src_def_id),
@ -146,14 +146,14 @@ fn generic_arg_mismatch_err(
/// ///
/// To start, we are given the `def_id` of the thing we are /// To start, we are given the `def_id` of the thing we are
/// creating the substitutions for, and a partial set of /// creating the substitutions for, and a partial set of
/// substitutions `parent_substs`. In general, the substitutions /// substitutions `parent_args`. In general, the substitutions
/// for an item begin with substitutions for all the "parents" of /// for an item begin with substitutions for all the "parents" of
/// that item -- e.g., for a method it might include the /// that item -- e.g., for a method it might include the
/// parameters from the impl. /// parameters from the impl.
/// ///
/// Therefore, the method begins by walking down these parents, /// Therefore, the method begins by walking down these parents,
/// starting with the outermost parent and proceed inwards until /// starting with the outermost parent and proceed inwards until
/// it reaches `def_id`. For each parent `P`, it will check `parent_substs` /// it reaches `def_id`. For each parent `P`, it will check `parent_args`
/// first to see if the parent's substitutions are listed in there. If so, /// first to see if the parent's substitutions are listed in there. If so,
/// we can append those and move on. Otherwise, it invokes the /// we can append those and move on. Otherwise, it invokes the
/// three callback functions: /// three callback functions:
@ -168,15 +168,15 @@ fn generic_arg_mismatch_err(
/// instantiate a `GenericArg`. /// instantiate a `GenericArg`.
/// - `inferred_kind`: if no parameter was provided, and inference is enabled, then /// - `inferred_kind`: if no parameter was provided, and inference is enabled, then
/// creates a suitable inference variable. /// creates a suitable inference variable.
pub fn create_substs_for_generic_args<'tcx, 'a>( pub fn create_args_for_parent_generic_args<'tcx, 'a>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
def_id: DefId, def_id: DefId,
parent_substs: &[subst::GenericArg<'tcx>], parent_args: &[ty::GenericArg<'tcx>],
has_self: bool, has_self: bool,
self_ty: Option<Ty<'tcx>>, self_ty: Option<Ty<'tcx>>,
arg_count: &GenericArgCountResult, arg_count: &GenericArgCountResult,
ctx: &mut impl CreateSubstsForGenericArgsCtxt<'a, 'tcx>, ctx: &mut impl CreateSubstsForGenericArgsCtxt<'a, 'tcx>,
) -> SubstsRef<'tcx> { ) -> GenericArgsRef<'tcx> {
// Collect the segments of the path; we need to substitute arguments // Collect the segments of the path; we need to substitute arguments
// for parameters throughout the entire path (wherever there are // for parameters throughout the entire path (wherever there are
// generic parameters). // generic parameters).
@ -191,27 +191,27 @@ pub fn create_substs_for_generic_args<'tcx, 'a>(
// We manually build up the substitution, rather than using convenience // We manually build up the substitution, rather than using convenience
// methods in `subst.rs`, so that we can iterate over the arguments and // methods in `subst.rs`, so that we can iterate over the arguments and
// parameters in lock-step linearly, instead of trying to match each pair. // parameters in lock-step linearly, instead of trying to match each pair.
let mut substs: SmallVec<[subst::GenericArg<'tcx>; 8]> = SmallVec::with_capacity(count); let mut args: SmallVec<[ty::GenericArg<'tcx>; 8]> = SmallVec::with_capacity(count);
// Iterate over each segment of the path. // Iterate over each segment of the path.
while let Some((def_id, defs)) = stack.pop() { while let Some((def_id, defs)) = stack.pop() {
let mut params = defs.params.iter().peekable(); let mut params = defs.params.iter().peekable();
// If we have already computed substitutions for parents, we can use those directly. // If we have already computed substitutions for parents, we can use those directly.
while let Some(&param) = params.peek() { while let Some(&param) = params.peek() {
if let Some(&kind) = parent_substs.get(param.index as usize) { if let Some(&kind) = parent_args.get(param.index as usize) {
substs.push(kind); args.push(kind);
params.next(); params.next();
} else { } else {
break; break;
} }
} }
// `Self` is handled first, unless it's been handled in `parent_substs`. // `Self` is handled first, unless it's been handled in `parent_args`.
if has_self { if has_self {
if let Some(&param) = params.peek() { if let Some(&param) = params.peek() {
if param.index == 0 { if param.index == 0 {
if let GenericParamDefKind::Type { .. } = param.kind { if let GenericParamDefKind::Type { .. } = param.kind {
substs.push( args.push(
self_ty self_ty
.map(|ty| ty.into()) .map(|ty| ty.into())
.unwrap_or_else(|| ctx.inferred_kind(None, param, true)), .unwrap_or_else(|| ctx.inferred_kind(None, param, true)),
@ -226,7 +226,7 @@ pub fn create_substs_for_generic_args<'tcx, 'a>(
let (generic_args, infer_args) = ctx.args_for_def_id(def_id); let (generic_args, infer_args) = ctx.args_for_def_id(def_id);
let args_iter = generic_args.iter().flat_map(|generic_args| generic_args.args.iter()); let args_iter = generic_args.iter().flat_map(|generic_args| generic_args.args.iter());
let mut args = args_iter.clone().peekable(); let mut args_iter = args_iter.clone().peekable();
// If we encounter a type or const when we expect a lifetime, we infer the lifetimes. // If we encounter a type or const when we expect a lifetime, we infer the lifetimes.
// If we later encounter a lifetime, we know that the arguments were provided in the // If we later encounter a lifetime, we know that the arguments were provided in the
@ -239,7 +239,7 @@ pub fn create_substs_for_generic_args<'tcx, 'a>(
// provided, matching them with the generic parameters we expect. // provided, matching them with the generic parameters we expect.
// Mismatches can occur as a result of elided lifetimes, or for malformed // Mismatches can occur as a result of elided lifetimes, or for malformed
// input. We try to handle both sensibly. // input. We try to handle both sensibly.
match (args.peek(), params.peek()) { match (args_iter.peek(), params.peek()) {
(Some(&arg), Some(&param)) => { (Some(&arg), Some(&param)) => {
match (arg, &param.kind, arg_count.explicit_late_bound) { match (arg, &param.kind, arg_count.explicit_late_bound) {
(GenericArg::Lifetime(_), GenericParamDefKind::Lifetime, _) (GenericArg::Lifetime(_), GenericParamDefKind::Lifetime, _)
@ -253,8 +253,8 @@ pub fn create_substs_for_generic_args<'tcx, 'a>(
GenericParamDefKind::Const { .. }, GenericParamDefKind::Const { .. },
_, _,
) => { ) => {
substs.push(ctx.provided_kind(param, arg)); args.push(ctx.provided_kind(param, arg));
args.next(); args_iter.next();
params.next(); params.next();
} }
( (
@ -264,7 +264,7 @@ pub fn create_substs_for_generic_args<'tcx, 'a>(
) => { ) => {
// We expected a lifetime argument, but got a type or const // We expected a lifetime argument, but got a type or const
// argument. That means we're inferring the lifetimes. // argument. That means we're inferring the lifetimes.
substs.push(ctx.inferred_kind(None, param, infer_args)); args.push(ctx.inferred_kind(None, param, infer_args));
force_infer_lt = Some((arg, param)); force_infer_lt = Some((arg, param));
params.next(); params.next();
} }
@ -273,7 +273,7 @@ pub fn create_substs_for_generic_args<'tcx, 'a>(
// the presence of explicit late bounds. This is most likely // the presence of explicit late bounds. This is most likely
// due to the presence of the explicit bound so we're just going to // due to the presence of the explicit bound so we're just going to
// ignore it. // ignore it.
args.next(); args_iter.next();
} }
(_, _, _) => { (_, _, _) => {
// We expected one kind of parameter, but the user provided // We expected one kind of parameter, but the user provided
@ -327,7 +327,7 @@ pub fn create_substs_for_generic_args<'tcx, 'a>(
// errors. In this case, we're simply going to ignore the argument // errors. In this case, we're simply going to ignore the argument
// and any following arguments. The rest of the parameters will be // and any following arguments. The rest of the parameters will be
// inferred. // inferred.
while args.next().is_some() {} while args_iter.next().is_some() {}
} }
} }
} }
@ -360,7 +360,7 @@ pub fn create_substs_for_generic_args<'tcx, 'a>(
(None, Some(&param)) => { (None, Some(&param)) => {
// If there are fewer arguments than parameters, it means // If there are fewer arguments than parameters, it means
// we're inferring the remaining arguments. // we're inferring the remaining arguments.
substs.push(ctx.inferred_kind(Some(&substs), param, infer_args)); args.push(ctx.inferred_kind(Some(&args), param, infer_args));
params.next(); params.next();
} }
@ -369,7 +369,7 @@ pub fn create_substs_for_generic_args<'tcx, 'a>(
} }
} }
tcx.mk_substs(&substs) tcx.mk_args(&args)
} }
/// Checks that the correct number of generic arguments have been provided. /// Checks that the correct number of generic arguments have been provided.

View File

@ -9,7 +9,7 @@ mod lint;
mod object_safety; mod object_safety;
use crate::astconv::errors::prohibit_assoc_ty_binding; use crate::astconv::errors::prohibit_assoc_ty_binding;
use crate::astconv::generics::{check_generic_arg_count, create_substs_for_generic_args}; use crate::astconv::generics::{check_generic_arg_count, create_args_for_parent_generic_args};
use crate::bounds::Bounds; use crate::bounds::Bounds;
use crate::collect::HirPlaceholderCollector; use crate::collect::HirPlaceholderCollector;
use crate::errors::{AmbiguousLifetimeBound, TypeofReservedKeywordUsed}; use crate::errors::{AmbiguousLifetimeBound, TypeofReservedKeywordUsed};
@ -29,9 +29,10 @@ use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt}; use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
use rustc_infer::traits::ObligationCause; use rustc_infer::traits::ObligationCause;
use rustc_middle::middle::stability::AllowUnstable; use rustc_middle::middle::stability::AllowUnstable;
use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef};
use rustc_middle::ty::GenericParamDefKind; use rustc_middle::ty::GenericParamDefKind;
use rustc_middle::ty::{self, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{
self, Const, GenericArgKind, GenericArgsRef, IsSuggestable, Ty, TyCtxt, TypeVisitableExt,
};
use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_span::symbol::{kw, Ident, Symbol};
@ -220,14 +221,14 @@ pub trait CreateSubstsForGenericArgsCtxt<'a, 'tcx> {
&mut self, &mut self,
param: &ty::GenericParamDef, param: &ty::GenericParamDef,
arg: &GenericArg<'_>, arg: &GenericArg<'_>,
) -> subst::GenericArg<'tcx>; ) -> ty::GenericArg<'tcx>;
fn inferred_kind( fn inferred_kind(
&mut self, &mut self,
substs: Option<&[subst::GenericArg<'tcx>]>, args: Option<&[ty::GenericArg<'tcx>]>,
param: &ty::GenericParamDef, param: &ty::GenericParamDef,
infer_args: bool, infer_args: bool,
) -> subst::GenericArg<'tcx>; ) -> ty::GenericArg<'tcx>;
} }
impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
@ -291,13 +292,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
/// Given a path `path` that refers to an item `I` with the declared generics `decl_generics`, /// Given a path `path` that refers to an item `I` with the declared generics `decl_generics`,
/// returns an appropriate set of substitutions for this particular reference to `I`. /// returns an appropriate set of substitutions for this particular reference to `I`.
pub fn ast_path_substs_for_ty( pub fn ast_path_args_for_ty(
&self, &self,
span: Span, span: Span,
def_id: DefId, def_id: DefId,
item_segment: &hir::PathSegment<'_>, item_segment: &hir::PathSegment<'_>,
) -> SubstsRef<'tcx> { ) -> GenericArgsRef<'tcx> {
let (substs, _) = self.create_substs_for_ast_path( let (args, _) = self.create_args_for_ast_path(
span, span,
def_id, def_id,
&[], &[],
@ -311,7 +312,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
prohibit_assoc_ty_binding(self.tcx(), b.span, Some((item_segment, span))); prohibit_assoc_ty_binding(self.tcx(), b.span, Some((item_segment, span)));
} }
substs args
} }
/// Given the type/lifetime/const arguments provided to some path (along with /// Given the type/lifetime/const arguments provided to some path (along with
@ -330,7 +331,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
/// 2. The path in question is the path to the trait `std::ops::Index`, /// 2. The path in question is the path to the trait `std::ops::Index`,
/// which will have been resolved to a `def_id` /// which will have been resolved to a `def_id`
/// 3. The `generic_args` contains info on the `<...>` contents. The `usize` type /// 3. The `generic_args` contains info on the `<...>` contents. The `usize` type
/// parameters are returned in the `SubstsRef`, the associated type bindings like /// parameters are returned in the `GenericArgsRef`, the associated type bindings like
/// `Output = u32` are returned from `create_assoc_bindings_for_generic_args`. /// `Output = u32` are returned from `create_assoc_bindings_for_generic_args`.
/// ///
/// Note that the type listing given here is *exactly* what the user provided. /// Note that the type listing given here is *exactly* what the user provided.
@ -341,22 +342,22 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
/// <Vec<u8> as Iterable<u8>>::Iter::<'a> /// <Vec<u8> as Iterable<u8>>::Iter::<'a>
/// ``` /// ```
/// ///
/// We have the parent substs are the substs for the parent trait: /// We have the parent args are the args for the parent trait:
/// `[Vec<u8>, u8]` and `generic_args` are the arguments for the associated /// `[Vec<u8>, u8]` and `generic_args` are the arguments for the associated
/// type itself: `['a]`. The returned `SubstsRef` concatenates these two /// type itself: `['a]`. The returned `GenericArgsRef` concatenates these two
/// lists: `[Vec<u8>, u8, 'a]`. /// lists: `[Vec<u8>, u8, 'a]`.
#[instrument(level = "debug", skip(self, span), ret)] #[instrument(level = "debug", skip(self, span), ret)]
fn create_substs_for_ast_path<'a>( fn create_args_for_ast_path<'a>(
&self, &self,
span: Span, span: Span,
def_id: DefId, def_id: DefId,
parent_substs: &[subst::GenericArg<'tcx>], parent_args: &[ty::GenericArg<'tcx>],
seg: &hir::PathSegment<'_>, seg: &hir::PathSegment<'_>,
generic_args: &'a hir::GenericArgs<'_>, generic_args: &'a hir::GenericArgs<'_>,
infer_args: bool, infer_args: bool,
self_ty: Option<Ty<'tcx>>, self_ty: Option<Ty<'tcx>>,
constness: ty::BoundConstness, constness: ty::BoundConstness,
) -> (SubstsRef<'tcx>, GenericArgCountResult) { ) -> (GenericArgsRef<'tcx>, GenericArgCountResult) {
// If the type is parameterized by this region, then replace this // If the type is parameterized by this region, then replace this
// region with the current anon region binding (in other words, // region with the current anon region binding (in other words,
// whatever & would get replaced with). // whatever & would get replaced with).
@ -369,7 +370,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
if generics.parent.is_some() { if generics.parent.is_some() {
// The parent is a trait so it should have at least one subst // The parent is a trait so it should have at least one subst
// for the `Self` type. // for the `Self` type.
assert!(!parent_substs.is_empty()) assert!(!parent_args.is_empty())
} else { } else {
// This item (presumably a trait) needs a self-type. // This item (presumably a trait) needs a self-type.
assert!(self_ty.is_some()); assert!(self_ty.is_some());
@ -395,7 +396,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// here and so associated type bindings will be handled regardless of whether there are any // here and so associated type bindings will be handled regardless of whether there are any
// non-`Self` generic parameters. // non-`Self` generic parameters.
if generics.params.is_empty() { if generics.params.is_empty() {
return (tcx.mk_substs(parent_substs), arg_count); return (tcx.mk_args(parent_args), arg_count);
} }
struct SubstsForAstPathCtxt<'a, 'tcx> { struct SubstsForAstPathCtxt<'a, 'tcx> {
@ -421,7 +422,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
&mut self, &mut self,
param: &ty::GenericParamDef, param: &ty::GenericParamDef,
arg: &GenericArg<'_>, arg: &GenericArg<'_>,
) -> subst::GenericArg<'tcx> { ) -> ty::GenericArg<'tcx> {
let tcx = self.astconv.tcx(); let tcx = self.astconv.tcx();
let mut handle_ty_args = |has_default, ty: &hir::Ty<'_>| { let mut handle_ty_args = |has_default, ty: &hir::Ty<'_>| {
@ -483,10 +484,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
fn inferred_kind( fn inferred_kind(
&mut self, &mut self,
substs: Option<&[subst::GenericArg<'tcx>]>, args: Option<&[ty::GenericArg<'tcx>]>,
param: &ty::GenericParamDef, param: &ty::GenericParamDef,
infer_args: bool, infer_args: bool,
) -> subst::GenericArg<'tcx> { ) -> ty::GenericArg<'tcx> {
let tcx = self.astconv.tcx(); let tcx = self.astconv.tcx();
match param.kind { match param.kind {
GenericParamDefKind::Lifetime => self GenericParamDefKind::Lifetime => self
@ -506,15 +507,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
GenericParamDefKind::Type { has_default, .. } => { GenericParamDefKind::Type { has_default, .. } => {
if !infer_args && has_default { if !infer_args && has_default {
// No type parameter provided, but a default exists. // No type parameter provided, but a default exists.
let substs = substs.unwrap(); let args = args.unwrap();
if substs.iter().any(|arg| match arg.unpack() { if args.iter().any(|arg| match arg.unpack() {
GenericArgKind::Type(ty) => ty.references_error(), GenericArgKind::Type(ty) => ty.references_error(),
_ => false, _ => false,
}) { }) {
// Avoid ICE #86756 when type error recovery goes awry. // Avoid ICE #86756 when type error recovery goes awry.
return Ty::new_misc_error(tcx).into(); return Ty::new_misc_error(tcx).into();
} }
tcx.at(self.span).type_of(param.def_id).subst(tcx, substs).into() tcx.at(self.span).type_of(param.def_id).instantiate(tcx, args).into()
} else if infer_args { } else if infer_args {
self.astconv.ty_infer(Some(param), self.span).into() self.astconv.ty_infer(Some(param), self.span).into()
} else { } else {
@ -532,7 +533,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
return ty::Const::new_error(tcx, guar, ty).into(); return ty::Const::new_error(tcx, guar, ty).into();
} }
if !infer_args && has_default { if !infer_args && has_default {
tcx.const_param_default(param.def_id).subst(tcx, substs.unwrap()).into() tcx.const_param_default(param.def_id)
.instantiate(tcx, args.unwrap())
.into()
} else { } else {
if infer_args { if infer_args {
self.astconv.ct_infer(ty, Some(param), self.span).into() self.astconv.ct_infer(ty, Some(param), self.span).into()
@ -546,7 +549,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
} }
} }
let mut substs_ctx = SubstsForAstPathCtxt { let mut args_ctx = SubstsForAstPathCtxt {
astconv: self, astconv: self,
def_id, def_id,
span, span,
@ -554,14 +557,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
inferred_params: vec![], inferred_params: vec![],
infer_args, infer_args,
}; };
let substs = create_substs_for_generic_args( let args = create_args_for_parent_generic_args(
tcx, tcx,
def_id, def_id,
parent_substs, parent_args,
self_ty.is_some(), self_ty.is_some(),
self_ty, self_ty,
&arg_count, &arg_count,
&mut substs_ctx, &mut args_ctx,
); );
if let ty::BoundConstness::ConstIfConst = constness if let ty::BoundConstness::ConstIfConst = constness
@ -570,7 +573,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
tcx.sess.emit_err(crate::errors::ConstBoundForNonConstTrait { span } ); tcx.sess.emit_err(crate::errors::ConstBoundForNonConstTrait { span } );
} }
(substs, arg_count) (args, arg_count)
} }
fn create_assoc_bindings_for_generic_args<'a>( fn create_assoc_bindings_for_generic_args<'a>(
@ -617,21 +620,21 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
assoc_bindings assoc_bindings
} }
pub fn create_substs_for_associated_item( pub fn create_args_for_associated_item(
&self, &self,
span: Span, span: Span,
item_def_id: DefId, item_def_id: DefId,
item_segment: &hir::PathSegment<'_>, item_segment: &hir::PathSegment<'_>,
parent_substs: SubstsRef<'tcx>, parent_args: GenericArgsRef<'tcx>,
) -> SubstsRef<'tcx> { ) -> GenericArgsRef<'tcx> {
debug!( debug!(
"create_substs_for_associated_item(span: {:?}, item_def_id: {:?}, item_segment: {:?}", "create_args_for_associated_item(span: {:?}, item_def_id: {:?}, item_segment: {:?}",
span, item_def_id, item_segment span, item_def_id, item_segment
); );
let (args, _) = self.create_substs_for_ast_path( let (args, _) = self.create_args_for_ast_path(
span, span,
item_def_id, item_def_id,
parent_substs, parent_args,
item_segment, item_segment,
item_segment.args(), item_segment.args(),
item_segment.infer_args, item_segment.infer_args,
@ -687,7 +690,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
only_self_bounds: OnlySelfBounds, only_self_bounds: OnlySelfBounds,
) -> GenericArgCountResult { ) -> GenericArgCountResult {
let (substs, arg_count) = self.create_substs_for_ast_path( let (generic_args, arg_count) = self.create_args_for_ast_path(
trait_ref_span, trait_ref_span,
trait_def_id, trait_def_id,
&[], &[],
@ -704,8 +707,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let assoc_bindings = self.create_assoc_bindings_for_generic_args(args); let assoc_bindings = self.create_assoc_bindings_for_generic_args(args);
let poly_trait_ref = let poly_trait_ref = ty::Binder::bind_with_vars(
ty::Binder::bind_with_vars(ty::TraitRef::new(tcx, trait_def_id, substs), bound_vars); ty::TraitRef::new(tcx, trait_def_id, generic_args),
bound_vars,
);
debug!(?poly_trait_ref, ?assoc_bindings); debug!(?poly_trait_ref, ?assoc_bindings);
bounds.push_trait_bound(tcx, poly_trait_ref, span, constness, polarity); bounds.push_trait_bound(tcx, poly_trait_ref, span, constness, polarity);
@ -846,7 +851,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
is_impl: bool, is_impl: bool,
constness: ty::BoundConstness, constness: ty::BoundConstness,
) -> ty::TraitRef<'tcx> { ) -> ty::TraitRef<'tcx> {
let (substs, _) = self.create_substs_for_ast_trait_ref( let (generic_args, _) = self.create_args_for_ast_trait_ref(
span, span,
trait_def_id, trait_def_id,
self_ty, self_ty,
@ -857,11 +862,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
if let Some(b) = trait_segment.args().bindings.first() { if let Some(b) = trait_segment.args().bindings.first() {
prohibit_assoc_ty_binding(self.tcx(), b.span, Some((trait_segment, span))); prohibit_assoc_ty_binding(self.tcx(), b.span, Some((trait_segment, span)));
} }
ty::TraitRef::new(self.tcx(), trait_def_id, substs) ty::TraitRef::new(self.tcx(), trait_def_id, generic_args)
} }
#[instrument(level = "debug", skip(self, span))] #[instrument(level = "debug", skip(self, span))]
fn create_substs_for_ast_trait_ref<'a>( fn create_args_for_ast_trait_ref<'a>(
&self, &self,
span: Span, span: Span,
trait_def_id: DefId, trait_def_id: DefId,
@ -869,10 +874,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
trait_segment: &'a hir::PathSegment<'a>, trait_segment: &'a hir::PathSegment<'a>,
is_impl: bool, is_impl: bool,
constness: ty::BoundConstness, constness: ty::BoundConstness,
) -> (SubstsRef<'tcx>, GenericArgCountResult) { ) -> (GenericArgsRef<'tcx>, GenericArgCountResult) {
self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, is_impl); self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, is_impl);
self.create_substs_for_ast_path( self.create_args_for_ast_path(
span, span,
trait_def_id, trait_def_id,
&[], &[],
@ -902,7 +907,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
did: DefId, did: DefId,
item_segment: &hir::PathSegment<'_>, item_segment: &hir::PathSegment<'_>,
) -> Ty<'tcx> { ) -> Ty<'tcx> {
let substs = self.ast_path_substs_for_ty(span, did, item_segment); let args = self.ast_path_args_for_ty(span, did, item_segment);
let ty = self.tcx().at(span).type_of(did); let ty = self.tcx().at(span).type_of(did);
if matches!(self.tcx().def_kind(did), DefKind::TyAlias) if matches!(self.tcx().def_kind(did), DefKind::TyAlias)
@ -911,10 +916,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// Type aliases referring to types that contain opaque types (but aren't just directly // Type aliases referring to types that contain opaque types (but aren't just directly
// referencing a single opaque type) get encoded as a type alias that normalization will // referencing a single opaque type) get encoded as a type alias that normalization will
// then actually instantiate the where bounds of. // then actually instantiate the where bounds of.
let alias_ty = self.tcx().mk_alias_ty(did, substs); let alias_ty = self.tcx().mk_alias_ty(did, args);
Ty::new_alias(self.tcx(), ty::Weak, alias_ty) Ty::new_alias(self.tcx(), ty::Weak, alias_ty)
} else { } else {
ty.subst(self.tcx(), substs) ty.instantiate(self.tcx(), args)
} }
} }
@ -1383,7 +1388,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}; };
self.one_bound_for_assoc_type( self.one_bound_for_assoc_type(
|| traits::supertraits(tcx, ty::Binder::dummy(trait_ref.subst_identity())), || {
traits::supertraits(
tcx,
ty::Binder::dummy(trait_ref.instantiate_identity()),
)
},
kw::SelfUpper, kw::SelfUpper,
assoc_ident, assoc_ident,
span, span,
@ -1620,8 +1630,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let ocx = ObligationCtxt::new(&infcx); let ocx = ObligationCtxt::new(&infcx);
ocx.register_obligations(obligations.clone()); ocx.register_obligations(obligations.clone());
let impl_substs = infcx.fresh_substs_for_item(span, impl_); let impl_args = infcx.fresh_args_for_item(span, impl_);
let impl_ty = tcx.type_of(impl_).subst(tcx, impl_substs); let impl_ty = tcx.type_of(impl_).instantiate(tcx, impl_args);
let impl_ty = ocx.normalize(&cause, param_env, impl_ty); let impl_ty = ocx.normalize(&cause, param_env, impl_ty);
// Check that the self types can be related. // Check that the self types can be related.
@ -1633,7 +1643,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
} }
// Check whether the impl imposes obligations we have to worry about. // Check whether the impl imposes obligations we have to worry about.
let impl_bounds = tcx.predicates_of(impl_).instantiate(tcx, impl_substs); let impl_bounds = tcx.predicates_of(impl_).instantiate(tcx, impl_args);
let impl_bounds = ocx.normalize(&cause, param_env, impl_bounds); let impl_bounds = ocx.normalize(&cause, param_env, impl_bounds);
let impl_obligations = traits::predicates_for_generics( let impl_obligations = traits::predicates_for_generics(
|_, _| cause.clone(), |_, _| cause.clone(),
@ -1665,18 +1675,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
if let Some((impl_, (assoc_item, def_scope))) = applicable_candidates.pop() { if let Some((impl_, (assoc_item, def_scope))) = applicable_candidates.pop() {
self.check_assoc_ty(assoc_item, name, def_scope, block, span); self.check_assoc_ty(assoc_item, name, def_scope, block, span);
// FIXME(fmease): Currently creating throwaway `parent_substs` to please // FIXME(fmease): Currently creating throwaway `parent_args` to please
// `create_substs_for_associated_item`. Modify the latter instead (or sth. similar) to // `create_args_for_associated_item`. Modify the latter instead (or sth. similar) to
// not require the parent substs logic. // not require the parent args logic.
let parent_substs = InternalSubsts::identity_for_item(tcx, impl_); let parent_args = ty::GenericArgs::identity_for_item(tcx, impl_);
let substs = let args = self.create_args_for_associated_item(span, assoc_item, segment, parent_args);
self.create_substs_for_associated_item(span, assoc_item, segment, parent_substs); let args = tcx.mk_args_from_iter(
let substs = tcx.mk_substs_from_iter(
std::iter::once(ty::GenericArg::from(self_ty)) std::iter::once(ty::GenericArg::from(self_ty))
.chain(substs.into_iter().skip(parent_substs.len())), .chain(args.into_iter().skip(parent_args.len())),
); );
let ty = Ty::new_alias(tcx, ty::Inherent, tcx.mk_alias_ty(assoc_item, substs)); let ty = Ty::new_alias(tcx, ty::Inherent, tcx.mk_alias_ty(assoc_item, args));
return Ok(Some((ty, assoc_item))); return Ok(Some((ty, assoc_item)));
} }
@ -1780,9 +1789,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
.any(|impl_def_id| { .any(|impl_def_id| {
let trait_ref = tcx.impl_trait_ref(impl_def_id); let trait_ref = tcx.impl_trait_ref(impl_def_id);
trait_ref.is_some_and(|trait_ref| { trait_ref.is_some_and(|trait_ref| {
let impl_ = trait_ref.subst( let impl_ = trait_ref.instantiate(
tcx, tcx,
infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id), infcx.fresh_args_for_item(DUMMY_SP, impl_def_id),
); );
let value = tcx.fold_regions(qself_ty, |_, _| tcx.lifetimes.re_erased); let value = tcx.fold_regions(qself_ty, |_, _| tcx.lifetimes.re_erased);
// FIXME: Don't bother dealing with non-lifetime binders here... // FIXME: Don't bother dealing with non-lifetime binders here...
@ -1848,7 +1857,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
&& tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative && tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative
}) })
.filter_map(|impl_def_id| tcx.impl_trait_ref(impl_def_id)) .filter_map(|impl_def_id| tcx.impl_trait_ref(impl_def_id))
.map(|impl_| impl_.subst_identity().self_ty()) .map(|impl_| impl_.instantiate_identity().self_ty())
// We don't care about blanket impls. // We don't care about blanket impls.
.filter(|self_ty| !self_ty.has_non_region_param()) .filter(|self_ty| !self_ty.has_non_region_param())
.map(|self_ty| tcx.erase_regions(self_ty).to_string()) .map(|self_ty| tcx.erase_regions(self_ty).to_string())
@ -1877,16 +1886,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
constness, constness,
); );
let item_substs = self.create_substs_for_associated_item( let item_args =
span, self.create_args_for_associated_item(span, item_def_id, item_segment, trait_ref.args);
item_def_id,
item_segment,
trait_ref.substs,
);
debug!("qpath_to_ty: trait_ref={:?}", trait_ref); debug!("qpath_to_ty: trait_ref={:?}", trait_ref);
Ty::new_projection(tcx, item_def_id, item_substs) Ty::new_projection(tcx, item_def_id, item_args)
} }
pub fn prohibit_generics<'a>( pub fn prohibit_generics<'a>(
@ -2148,8 +2153,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
self.prohibit_generics(item_segment.1.iter(), |err| { self.prohibit_generics(item_segment.1.iter(), |err| {
err.note("`impl Trait` types can't have type parameters"); err.note("`impl Trait` types can't have type parameters");
}); });
let substs = self.ast_path_substs_for_ty(span, did, item_segment.0); let args = self.ast_path_args_for_ty(span, did, item_segment.0);
Ty::new_opaque(tcx, did, substs) Ty::new_opaque(tcx, did, args)
} }
Res::Def( Res::Def(
DefKind::Enum DefKind::Enum
@ -2233,7 +2238,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// `Self` in impl (we know the concrete type). // `Self` in impl (we know the concrete type).
assert_eq!(opt_self_ty, None); assert_eq!(opt_self_ty, None);
// Try to evaluate any array length constants. // Try to evaluate any array length constants.
let ty = tcx.at(span).type_of(def_id).subst_identity(); let ty = tcx.at(span).type_of(def_id).instantiate_identity();
let span_of_impl = tcx.span_of_impl(def_id); let span_of_impl = tcx.span_of_impl(def_id);
self.prohibit_generics(path.segments.iter(), |err| { self.prohibit_generics(path.segments.iter(), |err| {
let def_id = match *ty.kind() { let def_id = match *ty.kind() {
@ -2471,7 +2476,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
} }
&hir::TyKind::Path(hir::QPath::LangItem(lang_item, span, _)) => { &hir::TyKind::Path(hir::QPath::LangItem(lang_item, span, _)) => {
let def_id = tcx.require_lang_item(lang_item, Some(span)); let def_id = tcx.require_lang_item(lang_item, Some(span));
let (substs, _) = self.create_substs_for_ast_path( let (args, _) = self.create_args_for_ast_path(
span, span,
def_id, def_id,
&[], &[],
@ -2481,7 +2486,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
None, None,
ty::BoundConstness::NotConst, ty::BoundConstness::NotConst,
); );
tcx.at(span).type_of(def_id).subst(tcx, substs) tcx.at(span).type_of(def_id).instantiate(tcx, args)
} }
hir::TyKind::Array(ty, length) => { hir::TyKind::Array(ty, length) => {
let length = match length { let length = match length {
@ -2494,7 +2499,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
Ty::new_array_with_const_len(tcx, self.ast_ty_to_ty(ty), length) Ty::new_array_with_const_len(tcx, self.ast_ty_to_ty(ty), length)
} }
hir::TyKind::Typeof(e) => { hir::TyKind::Typeof(e) => {
let ty_erased = tcx.type_of(e.def_id).subst_identity(); let ty_erased = tcx.type_of(e.def_id).instantiate_identity();
let ty = tcx.fold_regions(ty_erased, |r, _| { let ty = tcx.fold_regions(ty_erased, |r, _| {
if r.is_erased() { tcx.lifetimes.re_static } else { r } if r.is_erased() { tcx.lifetimes.re_static } else { r }
}); });
@ -2536,7 +2541,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let generics = tcx.generics_of(def_id); let generics = tcx.generics_of(def_id);
debug!("impl_trait_ty_to_ty: generics={:?}", generics); debug!("impl_trait_ty_to_ty: generics={:?}", generics);
let substs = InternalSubsts::for_item(tcx, def_id, |param, _| { let args = ty::GenericArgs::for_item(tcx, def_id, |param, _| {
// We use `generics.count() - lifetimes.len()` here instead of `generics.parent_count` // We use `generics.count() - lifetimes.len()` here instead of `generics.parent_count`
// since return-position impl trait in trait squashes all of the generics from its source fn // since return-position impl trait in trait squashes all of the generics from its source fn
// into its own generics, so the opaque's "own" params isn't always just lifetimes. // into its own generics, so the opaque's "own" params isn't always just lifetimes.
@ -2550,12 +2555,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
tcx.mk_param_from_def(param) tcx.mk_param_from_def(param)
} }
}); });
debug!("impl_trait_ty_to_ty: substs={:?}", substs); debug!("impl_trait_ty_to_ty: args={:?}", args);
if in_trait { if in_trait {
Ty::new_projection(tcx, def_id, substs) Ty::new_projection(tcx, def_id, args)
} else { } else {
Ty::new_opaque(tcx, def_id, substs) Ty::new_opaque(tcx, def_id, args)
} }
} }
@ -2720,9 +2725,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
trait_ref.def_id, trait_ref.def_id,
)?; )?;
let fn_sig = tcx.fn_sig(assoc.def_id).subst( let fn_sig = tcx.fn_sig(assoc.def_id).instantiate(
tcx, tcx,
trait_ref.substs.extend_to(tcx, assoc.def_id, |param, _| tcx.mk_param_from_def(param)), trait_ref.args.extend_to(tcx, assoc.def_id, |param, _| tcx.mk_param_from_def(param)),
); );
let fn_sig = tcx.liberate_late_bound_regions(fn_hir_id.expect_owner().to_def_id(), fn_sig); let fn_sig = tcx.liberate_late_bound_regions(fn_hir_id.expect_owner().to_def_id(), fn_sig);

View File

@ -262,8 +262,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let mut missing_type_params = vec![]; let mut missing_type_params = vec![];
let mut references_self = false; let mut references_self = false;
let generics = tcx.generics_of(trait_ref.def_id); let generics = tcx.generics_of(trait_ref.def_id);
let substs: Vec<_> = trait_ref let args: Vec<_> = trait_ref
.substs .args
.iter() .iter()
.enumerate() .enumerate()
.skip(1) // Remove `Self` for `ExistentialPredicate`. .skip(1) // Remove `Self` for `ExistentialPredicate`.
@ -279,7 +279,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
arg arg
}) })
.collect(); .collect();
let substs = tcx.mk_substs(&substs); let args = tcx.mk_args(&args);
let span = i.bottom().1; let span = i.bottom().1;
let empty_generic_args = hir_trait_bounds.iter().any(|hir_bound| { let empty_generic_args = hir_trait_bounds.iter().any(|hir_bound| {
@ -310,7 +310,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
err.emit(); err.emit();
} }
ty::ExistentialTraitRef { def_id: trait_ref.def_id, substs } ty::ExistentialTraitRef { def_id: trait_ref.def_id, args }
}) })
}); });
@ -325,7 +325,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// Like for trait refs, verify that `dummy_self` did not leak inside default type // Like for trait refs, verify that `dummy_self` did not leak inside default type
// parameters. // parameters.
let references_self = b.projection_ty.substs.iter().skip(1).any(|arg| { let references_self = b.projection_ty.args.iter().skip(1).any(|arg| {
if arg.walk().any(|arg| arg == dummy_self.into()) { if arg.walk().any(|arg| arg == dummy_self.into()) {
return true; return true;
} }
@ -336,9 +336,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
span, span,
"trait object projection bounds reference `Self`", "trait object projection bounds reference `Self`",
); );
let substs: Vec<_> = b let args: Vec<_> = b
.projection_ty .projection_ty
.substs .args
.iter() .iter()
.map(|arg| { .map(|arg| {
if arg.walk().any(|arg| arg == dummy_self.into()) { if arg.walk().any(|arg| arg == dummy_self.into()) {
@ -347,7 +347,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
arg arg
}) })
.collect(); .collect();
b.projection_ty.substs = tcx.mk_substs(&substs); b.projection_ty.args = tcx.mk_args(&args);
} }
ty::ExistentialProjection::erase_self_ty(tcx, b) ty::ExistentialProjection::erase_self_ty(tcx, b)

View File

@ -20,8 +20,8 @@ use rustc_middle::hir::nested_filter;
use rustc_middle::middle::stability::EvalResult; use rustc_middle::middle::stability::EvalResult;
use rustc_middle::traits::DefiningAnchor; use rustc_middle::traits::DefiningAnchor;
use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES}; use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::util::{Discr, IntTypeExt}; use rustc_middle::ty::util::{Discr, IntTypeExt};
use rustc_middle::ty::GenericArgKind;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, AdtDef, ParamEnv, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, self, AdtDef, ParamEnv, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
}; };
@ -96,8 +96,8 @@ fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) {
/// Check that the fields of the `union` do not need dropping. /// Check that the fields of the `union` do not need dropping.
fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool { fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool {
let item_type = tcx.type_of(item_def_id).subst_identity(); let item_type = tcx.type_of(item_def_id).instantiate_identity();
if let ty::Adt(def, substs) = item_type.kind() { if let ty::Adt(def, args) = item_type.kind() {
assert!(def.is_union()); assert!(def.is_union());
fn allowed_union_field<'tcx>( fn allowed_union_field<'tcx>(
@ -128,7 +128,7 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
let param_env = tcx.param_env(item_def_id); let param_env = tcx.param_env(item_def_id);
for field in &def.non_enum_variant().fields { for field in &def.non_enum_variant().fields {
let field_ty = tcx.normalize_erasing_regions(param_env, field.ty(tcx, substs)); let field_ty = tcx.normalize_erasing_regions(param_env, field.ty(tcx, args));
if !allowed_union_field(field_ty, tcx, param_env) { if !allowed_union_field(field_ty, tcx, param_env) {
let (field_span, ty_span) = match tcx.hir().get_if_local(field.did) { let (field_span, ty_span) = match tcx.hir().get_if_local(field.did) {
@ -163,7 +163,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 // 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 // have UB during initialization if they are uninhabited, but there also seems to be no good
// reason to allow any statics to be uninhabited. // reason to allow any statics to be uninhabited.
let ty = tcx.type_of(def_id).subst_identity(); let ty = tcx.type_of(def_id).instantiate_identity();
let span = tcx.def_span(def_id); let span = tcx.def_span(def_id);
let layout = match tcx.layout_of(ParamEnv::reveal_all().and(ty)) { let layout = match tcx.layout_of(ParamEnv::reveal_all().and(ty)) {
Ok(l) => l, Ok(l) => l,
@ -212,16 +212,16 @@ fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) {
return; return;
} }
let substs = InternalSubsts::identity_for_item(tcx, item.owner_id); let args = GenericArgs::identity_for_item(tcx, item.owner_id);
let span = tcx.def_span(item.owner_id.def_id); let span = tcx.def_span(item.owner_id.def_id);
if !tcx.features().impl_trait_projections { if !tcx.features().impl_trait_projections {
check_opaque_for_inheriting_lifetimes(tcx, item.owner_id.def_id, span); check_opaque_for_inheriting_lifetimes(tcx, item.owner_id.def_id, span);
} }
if tcx.type_of(item.owner_id.def_id).subst_identity().references_error() { if tcx.type_of(item.owner_id.def_id).instantiate_identity().references_error() {
return; return;
} }
if check_opaque_for_cycles(tcx, item.owner_id.def_id, substs, span, &origin).is_err() { if check_opaque_for_cycles(tcx, item.owner_id.def_id, args, span, &origin).is_err() {
return; return;
} }
@ -305,8 +305,8 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
.. ..
}) = item.kind }) = item.kind
{ {
let substs = InternalSubsts::identity_for_item(tcx, def_id); let args = GenericArgs::identity_for_item(tcx, def_id);
let opaque_identity_ty = Ty::new_opaque(tcx, def_id.to_def_id(), substs); let opaque_identity_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
let mut visitor = ProhibitOpaqueVisitor { let mut visitor = ProhibitOpaqueVisitor {
opaque_identity_ty, opaque_identity_ty,
parent_count: tcx.generics_of(def_id).parent_count as u32, parent_count: tcx.generics_of(def_id).parent_count as u32,
@ -316,7 +316,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
}; };
let prohibit_opaque = tcx let prohibit_opaque = tcx
.explicit_item_bounds(def_id) .explicit_item_bounds(def_id)
.subst_identity_iter_copied() .instantiate_identity_iter_copied()
.try_for_each(|(predicate, _)| predicate.visit_with(&mut visitor)); .try_for_each(|(predicate, _)| predicate.visit_with(&mut visitor));
if let Some(ty) = prohibit_opaque.break_value() { if let Some(ty) = prohibit_opaque.break_value() {
@ -355,11 +355,11 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
pub(super) fn check_opaque_for_cycles<'tcx>( pub(super) fn check_opaque_for_cycles<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
def_id: LocalDefId, def_id: LocalDefId,
substs: SubstsRef<'tcx>, args: GenericArgsRef<'tcx>,
span: Span, span: Span,
origin: &hir::OpaqueTyOrigin, origin: &hir::OpaqueTyOrigin,
) -> Result<(), ErrorGuaranteed> { ) -> Result<(), ErrorGuaranteed> {
if tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs).is_err() { if tcx.try_expand_impl_trait_type(def_id.to_def_id(), args).is_err() {
let reported = match origin { let reported = match origin {
hir::OpaqueTyOrigin::AsyncFn(..) => async_opaque_type_cycle_error(tcx, span), hir::OpaqueTyOrigin::AsyncFn(..) => async_opaque_type_cycle_error(tcx, span),
_ => opaque_type_cycle_error(tcx, def_id, span), _ => opaque_type_cycle_error(tcx, def_id, span),
@ -404,16 +404,16 @@ fn check_opaque_meets_bounds<'tcx>(
.build(); .build();
let ocx = ObligationCtxt::new(&infcx); let ocx = ObligationCtxt::new(&infcx);
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id()); let args = GenericArgs::identity_for_item(tcx, def_id.to_def_id());
let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), substs); let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
// `ReErased` regions appear in the "parent_substs" of closures/generators. // `ReErased` regions appear in the "parent_args" of closures/generators.
// We're ignoring them here and replacing them with fresh region variables. // We're ignoring them here and replacing them with fresh region variables.
// See tests in ui/type-alias-impl-trait/closure_{parent_substs,wf_outlives}.rs. // See tests in ui/type-alias-impl-trait/closure_{parent_args,wf_outlives}.rs.
// //
// FIXME: Consider wrapping the hidden type in an existential `Binder` and instantiating it // FIXME: Consider wrapping the hidden type in an existential `Binder` and instantiating it
// here rather than using ReErased. // here rather than using ReErased.
let hidden_ty = tcx.type_of(def_id.to_def_id()).subst(tcx, substs); let hidden_ty = tcx.type_of(def_id.to_def_id()).instantiate(tcx, args);
let hidden_ty = tcx.fold_regions(hidden_ty, |re, _dbi| match re.kind() { let hidden_ty = tcx.fold_regions(hidden_ty, |re, _dbi| match re.kind() {
ty::ReErased => infcx.next_region_var(RegionVariableOrigin::MiscVariable(span)), ty::ReErased => infcx.next_region_var(RegionVariableOrigin::MiscVariable(span)),
_ => re, _ => re,
@ -472,7 +472,7 @@ fn check_opaque_meets_bounds<'tcx>(
fn is_enum_of_nonnullable_ptr<'tcx>( fn is_enum_of_nonnullable_ptr<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
adt_def: AdtDef<'tcx>, adt_def: AdtDef<'tcx>,
substs: SubstsRef<'tcx>, args: GenericArgsRef<'tcx>,
) -> bool { ) -> bool {
if adt_def.repr().inhibit_enum_layout_opt() { if adt_def.repr().inhibit_enum_layout_opt() {
return false; return false;
@ -484,14 +484,14 @@ fn is_enum_of_nonnullable_ptr<'tcx>(
let (([], [field]) | ([field], [])) = (&var_one.fields.raw[..], &var_two.fields.raw[..]) else { let (([], [field]) | ([field], [])) = (&var_one.fields.raw[..], &var_two.fields.raw[..]) else {
return false; return false;
}; };
matches!(field.ty(tcx, substs).kind(), ty::FnPtr(..) | ty::Ref(..)) matches!(field.ty(tcx, args).kind(), ty::FnPtr(..) | ty::Ref(..))
} }
fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) { fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) {
if tcx.codegen_fn_attrs(def_id).import_linkage.is_some() { if tcx.codegen_fn_attrs(def_id).import_linkage.is_some() {
if match tcx.type_of(def_id).subst_identity().kind() { if match tcx.type_of(def_id).instantiate_identity().kind() {
ty::RawPtr(_) => false, ty::RawPtr(_) => false,
ty::Adt(adt_def, substs) => !is_enum_of_nonnullable_ptr(tcx, *adt_def, *substs), ty::Adt(adt_def, args) => !is_enum_of_nonnullable_ptr(tcx, *adt_def, *args),
_ => true, _ => true,
} { } {
tcx.sess.emit_err(LinkageType { span: tcx.def_span(def_id) }); tcx.sess.emit_err(LinkageType { span: tcx.def_span(def_id) });
@ -525,7 +525,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
check_impl_items_against_trait( check_impl_items_against_trait(
tcx, tcx,
id.owner_id.def_id, id.owner_id.def_id,
impl_trait_ref.subst_identity(), impl_trait_ref.instantiate_identity(),
); );
check_on_unimplemented(tcx, id); check_on_unimplemented(tcx, id);
} }
@ -541,13 +541,13 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
fn_maybe_err(tcx, assoc_item.ident(tcx).span, abi); fn_maybe_err(tcx, assoc_item.ident(tcx).span, abi);
} }
ty::AssocKind::Type if assoc_item.defaultness(tcx).has_value() => { ty::AssocKind::Type if assoc_item.defaultness(tcx).has_value() => {
let trait_substs = let trait_args =
InternalSubsts::identity_for_item(tcx, id.owner_id); GenericArgs::identity_for_item(tcx, id.owner_id);
let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds( let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds(
tcx, tcx,
assoc_item, assoc_item,
assoc_item, assoc_item,
ty::TraitRef::new(tcx, id.owner_id.to_def_id(), trait_substs), ty::TraitRef::new(tcx, id.owner_id.to_def_id(), trait_args),
); );
} }
_ => {} _ => {}
@ -572,7 +572,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
} }
} }
DefKind::TyAlias => { DefKind::TyAlias => {
let pty_ty = tcx.type_of(id.owner_id).subst_identity(); let pty_ty = tcx.type_of(id.owner_id).instantiate_identity();
let generics = tcx.generics_of(id.owner_id); let generics = tcx.generics_of(id.owner_id);
check_type_params_are_used(tcx, &generics, pty_ty); check_type_params_are_used(tcx, &generics, pty_ty);
} }
@ -886,8 +886,8 @@ fn check_impl_items_against_trait<'tcx>(
} }
pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) { pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
let t = tcx.type_of(def_id).subst_identity(); let t = tcx.type_of(def_id).instantiate_identity();
if let ty::Adt(def, substs) = t.kind() if let ty::Adt(def, args) = t.kind()
&& def.is_struct() && def.is_struct()
{ {
let fields = &def.non_enum_variant().fields; let fields = &def.non_enum_variant().fields;
@ -895,8 +895,8 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit(); struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
return; return;
} }
let e = fields[FieldIdx::from_u32(0)].ty(tcx, substs); let e = fields[FieldIdx::from_u32(0)].ty(tcx, args);
if !fields.iter().all(|f| f.ty(tcx, substs) == e) { if !fields.iter().all(|f| f.ty(tcx, args) == e) {
struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous") struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
.span_label(sp, "SIMD elements must have the same type") .span_label(sp, "SIMD elements must have the same type")
.emit(); .emit();
@ -1003,7 +1003,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) {
if first { if first {
format!( format!(
"`{}` contains a field of type `{}`", "`{}` contains a field of type `{}`",
tcx.type_of(def.did()).subst_identity(), tcx.type_of(def.did()).instantiate_identity(),
ident ident
) )
} else { } else {
@ -1025,7 +1025,7 @@ pub(super) fn check_packed_inner(
def_id: DefId, def_id: DefId,
stack: &mut Vec<DefId>, stack: &mut Vec<DefId>,
) -> Option<Vec<(DefId, Span)>> { ) -> Option<Vec<(DefId, Span)>> {
if let ty::Adt(def, substs) = tcx.type_of(def_id).subst_identity().kind() { if let ty::Adt(def, args) = tcx.type_of(def_id).instantiate_identity().kind() {
if def.is_struct() || def.is_union() { if def.is_struct() || def.is_union() {
if def.repr().align.is_some() { if def.repr().align.is_some() {
return Some(vec![(def.did(), DUMMY_SP)]); return Some(vec![(def.did(), DUMMY_SP)]);
@ -1033,7 +1033,7 @@ pub(super) fn check_packed_inner(
stack.push(def_id); stack.push(def_id);
for field in &def.non_enum_variant().fields { for field in &def.non_enum_variant().fields {
if let ty::Adt(def, _) = field.ty(tcx, substs).kind() if let ty::Adt(def, _) = field.ty(tcx, args).kind()
&& !stack.contains(&def.did()) && !stack.contains(&def.did())
&& let Some(mut defs) = check_packed_inner(tcx, def.did(), stack) && let Some(mut defs) = check_packed_inner(tcx, def.did(), stack)
{ {
@ -1072,7 +1072,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
// For each field, figure out if it's known to be a ZST and align(1), with "known" // For each field, figure out if it's known to be a ZST and align(1), with "known"
// respecting #[non_exhaustive] attributes. // respecting #[non_exhaustive] attributes.
let field_infos = adt.all_fields().map(|field| { let field_infos = adt.all_fields().map(|field| {
let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did)); let ty = field.ty(tcx, GenericArgs::identity_for_item(tcx, field.did));
let param_env = tcx.param_env(field.did); let param_env = tcx.param_env(field.did);
let layout = tcx.layout_of(param_env.and(ty)); let layout = tcx.layout_of(param_env.and(ty));
// We are currently checking the type this field came from, so it must be local // We are currently checking the type this field came from, so it must be local
@ -1086,7 +1086,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
fn check_non_exhaustive<'tcx>( fn check_non_exhaustive<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
t: Ty<'tcx>, t: Ty<'tcx>,
) -> ControlFlow<(&'static str, DefId, SubstsRef<'tcx>, bool)> { ) -> ControlFlow<(&'static str, DefId, GenericArgsRef<'tcx>, bool)> {
match t.kind() { match t.kind() {
ty::Tuple(list) => list.iter().try_for_each(|t| check_non_exhaustive(tcx, t)), ty::Tuple(list) => list.iter().try_for_each(|t| check_non_exhaustive(tcx, t)),
ty::Array(ty, _) => check_non_exhaustive(tcx, *ty), ty::Array(ty, _) => check_non_exhaustive(tcx, *ty),
@ -1140,7 +1140,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
.span_label(span, "has alignment larger than 1") .span_label(span, "has alignment larger than 1")
.emit(); .emit();
} }
if incompat && let Some((descr, def_id, substs, non_exhaustive)) = non_exhaustive { if incompat && let Some((descr, def_id, args, non_exhaustive)) = non_exhaustive {
tcx.struct_span_lint_hir( tcx.struct_span_lint_hir(
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS, REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS,
tcx.hir().local_def_id_to_hir_id(adt.did().expect_local()), tcx.hir().local_def_id_to_hir_id(adt.did().expect_local()),
@ -1152,7 +1152,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
} else { } else {
"contains private fields" "contains private fields"
}; };
let field_ty = tcx.def_path_str_with_substs(def_id, substs); let field_ty = tcx.def_path_str_with_args(def_id, args);
lint lint
.note(format!("this {descr} contains `{field_ty}`, which {note}, \ .note(format!("this {descr} contains `{field_ty}`, which {note}, \
and makes it not a breaking change to become non-zero-sized in the future.")) and makes it not a breaking change to become non-zero-sized in the future."))

View File

@ -16,7 +16,7 @@ use rustc_infer::traits::util;
use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::util::ExplicitSelf; use rustc_middle::ty::util::ExplicitSelf;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, InternalSubsts, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, self, GenericArgs, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
}; };
use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt}; use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt};
use rustc_span::{Span, DUMMY_SP}; use rustc_span::{Span, DUMMY_SP};
@ -96,15 +96,15 @@ fn check_method_is_structurally_compatible<'tcx>(
/// For this we have to show that, assuming the bounds of the impl hold, the /// For this we have to show that, assuming the bounds of the impl hold, the
/// bounds of `trait_m` imply the bounds of `impl_m`. /// bounds of `trait_m` imply the bounds of `impl_m`.
/// ///
/// We start out with `trait_to_impl_substs`, that maps the trait /// We start out with `trait_to_impl_args`, that maps the trait
/// type parameters to impl type parameters. This is taken from the /// type parameters to impl type parameters. This is taken from the
/// impl trait reference: /// impl trait reference:
/// ///
/// ```rust,ignore (pseudo-Rust) /// ```rust,ignore (pseudo-Rust)
/// trait_to_impl_substs = {'t => 'j, T => &'i U, Self => Foo} /// trait_to_impl_args = {'t => 'j, T => &'i U, Self => Foo}
/// ``` /// ```
/// ///
/// We create a mapping `dummy_substs` that maps from the impl type /// We create a mapping `dummy_args` that maps from the impl type
/// parameters to fresh types and regions. For type parameters, /// parameters to fresh types and regions. For type parameters,
/// this is the identity transform, but we could as well use any /// this is the identity transform, but we could as well use any
/// placeholder types. For regions, we convert from bound to free /// placeholder types. For regions, we convert from bound to free
@ -112,10 +112,10 @@ fn check_method_is_structurally_compatible<'tcx>(
/// declared on the impl or used in type parameter bounds). /// declared on the impl or used in type parameter bounds).
/// ///
/// ```rust,ignore (pseudo-Rust) /// ```rust,ignore (pseudo-Rust)
/// impl_to_placeholder_substs = {'i => 'i0, U => U0, N => N0 } /// impl_to_placeholder_args = {'i => 'i0, U => U0, N => N0 }
/// ``` /// ```
/// ///
/// Now we can apply `placeholder_substs` to the type of the impl method /// Now we can apply `placeholder_args` to the type of the impl method
/// to yield a new function type in terms of our fresh, placeholder /// to yield a new function type in terms of our fresh, placeholder
/// types: /// types:
/// ///
@ -125,13 +125,13 @@ fn check_method_is_structurally_compatible<'tcx>(
/// ///
/// We now want to extract and substitute the type of the *trait* /// We now want to extract and substitute the type of the *trait*
/// method and compare it. To do so, we must create a compound /// method and compare it. To do so, we must create a compound
/// substitution by combining `trait_to_impl_substs` and /// substitution by combining `trait_to_impl_args` and
/// `impl_to_placeholder_substs`, and also adding a mapping for the method /// `impl_to_placeholder_args`, and also adding a mapping for the method
/// type parameters. We extend the mapping to also include /// type parameters. We extend the mapping to also include
/// the method parameters. /// the method parameters.
/// ///
/// ```rust,ignore (pseudo-Rust) /// ```rust,ignore (pseudo-Rust)
/// trait_to_placeholder_substs = { T => &'i0 U0, Self => Foo, M => N0 } /// trait_to_placeholder_args = { T => &'i0 U0, Self => Foo, M => N0 }
/// ``` /// ```
/// ///
/// Applying this to the trait method type yields: /// Applying this to the trait method type yields:
@ -148,8 +148,8 @@ fn check_method_is_structurally_compatible<'tcx>(
/// satisfied by the implementation's method. /// satisfied by the implementation's method.
/// ///
/// We do this by creating a parameter environment which contains a /// We do this by creating a parameter environment which contains a
/// substitution corresponding to `impl_to_placeholder_substs`. We then build /// substitution corresponding to `impl_to_placeholder_args`. We then build
/// `trait_to_placeholder_substs` and use it to convert the predicates contained /// `trait_to_placeholder_args` and use it to convert the predicates contained
/// in the `trait_m` generics to the placeholder form. /// in the `trait_m` generics to the placeholder form.
/// ///
/// Finally we register each of these predicates as an obligation and check that /// Finally we register each of these predicates as an obligation and check that
@ -162,7 +162,7 @@ fn compare_method_predicate_entailment<'tcx>(
impl_trait_ref: ty::TraitRef<'tcx>, impl_trait_ref: ty::TraitRef<'tcx>,
check_implied_wf: CheckImpliedWfMode, check_implied_wf: CheckImpliedWfMode,
) -> Result<(), ErrorGuaranteed> { ) -> Result<(), ErrorGuaranteed> {
let trait_to_impl_substs = impl_trait_ref.substs; let trait_to_impl_args = impl_trait_ref.args;
// This node-id should be used for the `body_id` field on each // This node-id should be used for the `body_id` field on each
// `ObligationCause` (and the `FnCtxt`). // `ObligationCause` (and the `FnCtxt`).
@ -182,12 +182,12 @@ fn compare_method_predicate_entailment<'tcx>(
); );
// Create mapping from impl to placeholder. // Create mapping from impl to placeholder.
let impl_to_placeholder_substs = InternalSubsts::identity_for_item(tcx, impl_m.def_id); let impl_to_placeholder_args = GenericArgs::identity_for_item(tcx, impl_m.def_id);
// Create mapping from trait to placeholder. // Create mapping from trait to placeholder.
let trait_to_placeholder_substs = let trait_to_placeholder_args =
impl_to_placeholder_substs.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_substs); impl_to_placeholder_args.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_args);
debug!("compare_impl_method: trait_to_placeholder_substs={:?}", trait_to_placeholder_substs); debug!("compare_impl_method: trait_to_placeholder_args={:?}", trait_to_placeholder_args);
let impl_m_predicates = tcx.predicates_of(impl_m.def_id); let impl_m_predicates = tcx.predicates_of(impl_m.def_id);
let trait_m_predicates = tcx.predicates_of(trait_m.def_id); let trait_m_predicates = tcx.predicates_of(trait_m.def_id);
@ -211,7 +211,7 @@ fn compare_method_predicate_entailment<'tcx>(
// if all constraints hold. // if all constraints hold.
hybrid_preds.predicates.extend( hybrid_preds.predicates.extend(
trait_m_predicates trait_m_predicates
.instantiate_own(tcx, trait_to_placeholder_substs) .instantiate_own(tcx, trait_to_placeholder_args)
.map(|(predicate, _)| predicate), .map(|(predicate, _)| predicate),
); );
@ -231,7 +231,7 @@ fn compare_method_predicate_entailment<'tcx>(
debug!("compare_impl_method: caller_bounds={:?}", param_env.caller_bounds()); debug!("compare_impl_method: caller_bounds={:?}", param_env.caller_bounds());
let impl_m_own_bounds = impl_m_predicates.instantiate_own(tcx, impl_to_placeholder_substs); let impl_m_own_bounds = impl_m_predicates.instantiate_own(tcx, impl_to_placeholder_args);
for (predicate, span) in impl_m_own_bounds { for (predicate, span) in impl_m_own_bounds {
let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id); let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id);
let predicate = ocx.normalize(&normalize_cause, param_env, predicate); let predicate = ocx.normalize(&normalize_cause, param_env, predicate);
@ -269,7 +269,7 @@ fn compare_method_predicate_entailment<'tcx>(
let unnormalized_impl_sig = infcx.instantiate_binder_with_fresh_vars( let unnormalized_impl_sig = infcx.instantiate_binder_with_fresh_vars(
impl_m_span, impl_m_span,
infer::HigherRankedType, infer::HigherRankedType,
tcx.fn_sig(impl_m.def_id).subst_identity(), tcx.fn_sig(impl_m.def_id).instantiate_identity(),
); );
let unnormalized_impl_fty = Ty::new_fn_ptr(tcx, ty::Binder::dummy(unnormalized_impl_sig)); let unnormalized_impl_fty = Ty::new_fn_ptr(tcx, ty::Binder::dummy(unnormalized_impl_sig));
@ -277,7 +277,7 @@ fn compare_method_predicate_entailment<'tcx>(
let impl_sig = ocx.normalize(&norm_cause, param_env, unnormalized_impl_sig); let impl_sig = ocx.normalize(&norm_cause, param_env, unnormalized_impl_sig);
debug!("compare_impl_method: impl_fty={:?}", impl_sig); debug!("compare_impl_method: impl_fty={:?}", impl_sig);
let trait_sig = tcx.fn_sig(trait_m.def_id).subst(tcx, trait_to_placeholder_substs); let trait_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_placeholder_args);
let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_sig); let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_sig);
// Next, add all inputs and output as well-formed tys. Importantly, // Next, add all inputs and output as well-formed tys. Importantly,
@ -615,14 +615,14 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
let impl_m = tcx.opt_associated_item(impl_m_def_id.to_def_id()).unwrap(); let impl_m = tcx.opt_associated_item(impl_m_def_id.to_def_id()).unwrap();
let trait_m = tcx.opt_associated_item(impl_m.trait_item_def_id.unwrap()).unwrap(); let trait_m = tcx.opt_associated_item(impl_m.trait_item_def_id.unwrap()).unwrap();
let impl_trait_ref = let impl_trait_ref =
tcx.impl_trait_ref(impl_m.impl_container(tcx).unwrap()).unwrap().subst_identity(); tcx.impl_trait_ref(impl_m.impl_container(tcx).unwrap()).unwrap().instantiate_identity();
let param_env = tcx.param_env(impl_m_def_id); let param_env = tcx.param_env(impl_m_def_id);
// First, check a few of the same things as `compare_impl_method`, // First, check a few of the same things as `compare_impl_method`,
// just so we don't ICE during substitution later. // just so we don't ICE during substitution later.
check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?; check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?;
let trait_to_impl_substs = impl_trait_ref.substs; let trait_to_impl_args = impl_trait_ref.args;
let impl_m_hir_id = tcx.hir().local_def_id_to_hir_id(impl_m_def_id); let impl_m_hir_id = tcx.hir().local_def_id_to_hir_id(impl_m_def_id);
let return_span = tcx.hir().fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span(); let return_span = tcx.hir().fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span();
@ -637,11 +637,11 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
); );
// Create mapping from impl to placeholder. // Create mapping from impl to placeholder.
let impl_to_placeholder_substs = InternalSubsts::identity_for_item(tcx, impl_m.def_id); let impl_to_placeholder_args = GenericArgs::identity_for_item(tcx, impl_m.def_id);
// Create mapping from trait to placeholder. // Create mapping from trait to placeholder.
let trait_to_placeholder_substs = let trait_to_placeholder_args =
impl_to_placeholder_substs.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_substs); impl_to_placeholder_args.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_args);
let infcx = &tcx.infer_ctxt().build(); let infcx = &tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(infcx); let ocx = ObligationCtxt::new(infcx);
@ -651,7 +651,10 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
let impl_sig = ocx.normalize( let impl_sig = ocx.normalize(
&norm_cause, &norm_cause,
param_env, param_env,
tcx.liberate_late_bound_regions(impl_m.def_id, tcx.fn_sig(impl_m.def_id).subst_identity()), tcx.liberate_late_bound_regions(
impl_m.def_id,
tcx.fn_sig(impl_m.def_id).instantiate_identity(),
),
); );
impl_sig.error_reported()?; impl_sig.error_reported()?;
let impl_return_ty = impl_sig.output(); let impl_return_ty = impl_sig.output();
@ -665,7 +668,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
.instantiate_binder_with_fresh_vars( .instantiate_binder_with_fresh_vars(
return_span, return_span,
infer::HigherRankedType, infer::HigherRankedType,
tcx.fn_sig(trait_m.def_id).subst(tcx, trait_to_placeholder_substs), tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_placeholder_args),
) )
.fold_with(&mut collector); .fold_with(&mut collector);
@ -758,47 +761,47 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
ocx.resolve_regions_and_report_errors(impl_m_def_id, &outlives_env)?; ocx.resolve_regions_and_report_errors(impl_m_def_id, &outlives_env)?;
let mut collected_tys = FxHashMap::default(); let mut collected_tys = FxHashMap::default();
for (def_id, (ty, substs)) in collected_types { for (def_id, (ty, args)) in collected_types {
match infcx.fully_resolve((ty, substs)) { match infcx.fully_resolve((ty, args)) {
Ok((ty, substs)) => { Ok((ty, args)) => {
// `ty` contains free regions that we created earlier while liberating the // `ty` contains free regions that we created earlier while liberating the
// trait fn signature. However, projection normalization expects `ty` to // trait fn signature. However, projection normalization expects `ty` to
// contains `def_id`'s early-bound regions. // contains `def_id`'s early-bound regions.
let id_substs = InternalSubsts::identity_for_item(tcx, def_id); let id_args = GenericArgs::identity_for_item(tcx, def_id);
debug!(?id_substs, ?substs); debug!(?id_args, ?args);
let map: FxHashMap<_, _> = std::iter::zip(substs, id_substs) let map: FxHashMap<_, _> = std::iter::zip(args, id_args)
.skip(tcx.generics_of(trait_m.def_id).count()) .skip(tcx.generics_of(trait_m.def_id).count())
.filter_map(|(a, b)| Some((a.as_region()?, b.as_region()?))) .filter_map(|(a, b)| Some((a.as_region()?, b.as_region()?)))
.collect(); .collect();
debug!(?map); debug!(?map);
// NOTE(compiler-errors): RPITITs, like all other RPITs, have early-bound // NOTE(compiler-errors): RPITITs, like all other RPITs, have early-bound
// region substs that are synthesized during AST lowering. These are substs // region args that are synthesized during AST lowering. These are args
// that are appended to the parent substs (trait and trait method). However, // that are appended to the parent args (trait and trait method). However,
// we're trying to infer the unsubstituted type value of the RPITIT inside // we're trying to infer the unsubstituted type value of the RPITIT inside
// the *impl*, so we can later use the impl's method substs to normalize // the *impl*, so we can later use the impl's method args to normalize
// an RPITIT to a concrete type (`confirm_impl_trait_in_trait_candidate`). // an RPITIT to a concrete type (`confirm_impl_trait_in_trait_candidate`).
// //
// Due to the design of RPITITs, during AST lowering, we have no idea that // Due to the design of RPITITs, during AST lowering, we have no idea that
// an impl method corresponds to a trait method with RPITITs in it. Therefore, // an impl method corresponds to a trait method with RPITITs in it. Therefore,
// we don't have a list of early-bound region substs for the RPITIT in the impl. // we don't have a list of early-bound region args for the RPITIT in the impl.
// Since early region parameters are index-based, we can't just rebase these // Since early region parameters are index-based, we can't just rebase these
// (trait method) early-bound region substs onto the impl, and there's no // (trait method) early-bound region args onto the impl, and there's no
// guarantee that the indices from the trait substs and impl substs line up. // guarantee that the indices from the trait args and impl args line up.
// So to fix this, we subtract the number of trait substs and add the number of // So to fix this, we subtract the number of trait args and add the number of
// impl substs to *renumber* these early-bound regions to their corresponding // impl args to *renumber* these early-bound regions to their corresponding
// indices in the impl's substitutions list. // indices in the impl's substitutions list.
// //
// Also, we only need to account for a difference in trait and impl substs, // Also, we only need to account for a difference in trait and impl args,
// since we previously enforce that the trait method and impl method have the // since we previously enforce that the trait method and impl method have the
// same generics. // same generics.
let num_trait_substs = trait_to_impl_substs.len(); let num_trait_args = trait_to_impl_args.len();
let num_impl_substs = tcx.generics_of(impl_m.container_id(tcx)).params.len(); let num_impl_args = tcx.generics_of(impl_m.container_id(tcx)).params.len();
let ty = match ty.try_fold_with(&mut RemapHiddenTyRegions { let ty = match ty.try_fold_with(&mut RemapHiddenTyRegions {
tcx, tcx,
map, map,
num_trait_substs, num_trait_args,
num_impl_substs, num_impl_args,
def_id, def_id,
impl_def_id: impl_m.container_id(tcx), impl_def_id: impl_m.container_id(tcx),
ty, ty,
@ -824,7 +827,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
struct ImplTraitInTraitCollector<'a, 'tcx> { struct ImplTraitInTraitCollector<'a, 'tcx> {
ocx: &'a ObligationCtxt<'a, 'tcx>, ocx: &'a ObligationCtxt<'a, 'tcx>,
types: FxHashMap<DefId, (Ty<'tcx>, ty::SubstsRef<'tcx>)>, types: FxHashMap<DefId, (Ty<'tcx>, ty::GenericArgsRef<'tcx>)>,
span: Span, span: Span,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
body_id: LocalDefId, body_id: LocalDefId,
@ -853,8 +856,8 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> {
if let Some((ty, _)) = self.types.get(&proj.def_id) { if let Some((ty, _)) = self.types.get(&proj.def_id) {
return *ty; return *ty;
} }
//FIXME(RPITIT): Deny nested RPITIT in substs too //FIXME(RPITIT): Deny nested RPITIT in args too
if proj.substs.has_escaping_bound_vars() { if proj.args.has_escaping_bound_vars() {
bug!("FIXME(RPITIT): error here"); bug!("FIXME(RPITIT): error here");
} }
// Replace with infer var // Replace with infer var
@ -862,9 +865,9 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> {
span: self.span, span: self.span,
kind: TypeVariableOriginKind::MiscVariable, kind: TypeVariableOriginKind::MiscVariable,
}); });
self.types.insert(proj.def_id, (infer_ty, proj.substs)); self.types.insert(proj.def_id, (infer_ty, proj.args));
// Recurse into bounds // Recurse into bounds
for (pred, pred_span) in self.interner().explicit_item_bounds(proj.def_id).subst_iter_copied(self.interner(), proj.substs) { for (pred, pred_span) in self.interner().explicit_item_bounds(proj.def_id).arg_iter_copied(self.interner(), proj.args) {
let pred = pred.fold_with(self); let pred = pred.fold_with(self);
let pred = self.ocx.normalize( let pred = self.ocx.normalize(
&ObligationCause::misc(self.span, self.body_id), &ObligationCause::misc(self.span, self.body_id),
@ -893,8 +896,8 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> {
struct RemapHiddenTyRegions<'tcx> { struct RemapHiddenTyRegions<'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
map: FxHashMap<ty::Region<'tcx>, ty::Region<'tcx>>, map: FxHashMap<ty::Region<'tcx>, ty::Region<'tcx>>,
num_trait_substs: usize, num_trait_args: usize,
num_impl_substs: usize, num_impl_args: usize,
def_id: DefId, def_id: DefId,
impl_def_id: DefId, impl_def_id: DefId,
ty: Ty<'tcx>, ty: Ty<'tcx>,
@ -909,16 +912,16 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
} }
fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
if let ty::Alias(ty::Opaque, ty::AliasTy { substs, def_id, .. }) = *t.kind() { if let ty::Alias(ty::Opaque, ty::AliasTy { args, def_id, .. }) = *t.kind() {
let mut mapped_substs = Vec::with_capacity(substs.len()); let mut mapped_args = Vec::with_capacity(args.len());
for (arg, v) in std::iter::zip(substs, self.tcx.variances_of(def_id)) { for (arg, v) in std::iter::zip(args, self.tcx.variances_of(def_id)) {
mapped_substs.push(match (arg.unpack(), v) { mapped_args.push(match (arg.unpack(), v) {
// Skip uncaptured opaque substs // Skip uncaptured opaque args
(ty::GenericArgKind::Lifetime(_), ty::Bivariant) => arg, (ty::GenericArgKind::Lifetime(_), ty::Bivariant) => arg,
_ => arg.try_fold_with(self)?, _ => arg.try_fold_with(self)?,
}); });
} }
Ok(Ty::new_opaque(self.tcx, def_id, self.tcx.mk_substs(&mapped_substs))) Ok(Ty::new_opaque(self.tcx, def_id, self.tcx.mk_args(&mapped_args)))
} else { } else {
t.try_super_fold_with(self) t.try_super_fold_with(self)
} }
@ -975,7 +978,7 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
ty::EarlyBoundRegion { ty::EarlyBoundRegion {
def_id: e.def_id, def_id: e.def_id,
name: e.name, name: e.name,
index: (e.index as usize - self.num_trait_substs + self.num_impl_substs) as u32, index: (e.index as usize - self.num_trait_args + self.num_impl_args) as u32,
}, },
)) ))
} }
@ -1214,7 +1217,7 @@ fn compare_self_type<'tcx>(
ty::ImplContainer => impl_trait_ref.self_ty(), ty::ImplContainer => impl_trait_ref.self_ty(),
ty::TraitContainer => tcx.types.self_param, ty::TraitContainer => tcx.types.self_param,
}; };
let self_arg_ty = tcx.fn_sig(method.def_id).subst_identity().input(0); let self_arg_ty = tcx.fn_sig(method.def_id).instantiate_identity().input(0);
let param_env = ty::ParamEnv::reveal_all(); let param_env = ty::ParamEnv::reveal_all();
let infcx = tcx.infer_ctxt().build(); let infcx = tcx.infer_ctxt().build();
@ -1738,7 +1741,7 @@ fn compare_generic_param_kinds<'tcx>(
format!( format!(
"{} const parameter of type `{}`", "{} const parameter of type `{}`",
prefix, prefix,
tcx.type_of(param.def_id).subst_identity() tcx.type_of(param.def_id).instantiate_identity()
) )
} }
Type { .. } => format!("{} type parameter", prefix), Type { .. } => format!("{} type parameter", prefix),
@ -1769,7 +1772,7 @@ pub(super) fn compare_impl_const_raw(
let impl_const_item = tcx.associated_item(impl_const_item_def); let impl_const_item = tcx.associated_item(impl_const_item_def);
let trait_const_item = tcx.associated_item(trait_const_item_def); let trait_const_item = tcx.associated_item(trait_const_item_def);
let impl_trait_ref = let impl_trait_ref =
tcx.impl_trait_ref(impl_const_item.container_id(tcx)).unwrap().subst_identity(); tcx.impl_trait_ref(impl_const_item.container_id(tcx)).unwrap().instantiate_identity();
debug!("compare_const_impl(impl_trait_ref={:?})", impl_trait_ref); debug!("compare_const_impl(impl_trait_ref={:?})", impl_trait_ref);
let impl_c_span = tcx.def_span(impl_const_item_def.to_def_id()); let impl_c_span = tcx.def_span(impl_const_item_def.to_def_id());
@ -1783,13 +1786,13 @@ pub(super) fn compare_impl_const_raw(
// because we shouldn't really have to deal with lifetimes or // because we shouldn't really have to deal with lifetimes or
// predicates. In fact some of this should probably be put into // predicates. In fact some of this should probably be put into
// shared functions because of DRY violations... // shared functions because of DRY violations...
let trait_to_impl_substs = impl_trait_ref.substs; let trait_to_impl_args = impl_trait_ref.args;
// Create a parameter environment that represents the implementation's // Create a parameter environment that represents the implementation's
// method. // method.
// Compute placeholder form of impl and trait const tys. // Compute placeholder form of impl and trait const tys.
let impl_ty = tcx.type_of(impl_const_item_def.to_def_id()).subst_identity(); let impl_ty = tcx.type_of(impl_const_item_def.to_def_id()).instantiate_identity();
let trait_ty = tcx.type_of(trait_const_item_def).subst(tcx, trait_to_impl_substs); let trait_ty = tcx.type_of(trait_const_item_def).instantiate(tcx, trait_to_impl_args);
let mut cause = ObligationCause::new( let mut cause = ObligationCause::new(
impl_c_span, impl_c_span,
impl_const_item_def, impl_const_item_def,
@ -1885,16 +1888,16 @@ fn compare_type_predicate_entailment<'tcx>(
trait_ty: ty::AssocItem, trait_ty: ty::AssocItem,
impl_trait_ref: ty::TraitRef<'tcx>, impl_trait_ref: ty::TraitRef<'tcx>,
) -> Result<(), ErrorGuaranteed> { ) -> Result<(), ErrorGuaranteed> {
let impl_substs = InternalSubsts::identity_for_item(tcx, impl_ty.def_id); let impl_args = GenericArgs::identity_for_item(tcx, impl_ty.def_id);
let trait_to_impl_substs = let trait_to_impl_args =
impl_substs.rebase_onto(tcx, impl_ty.container_id(tcx), impl_trait_ref.substs); impl_args.rebase_onto(tcx, impl_ty.container_id(tcx), impl_trait_ref.args);
let impl_ty_predicates = tcx.predicates_of(impl_ty.def_id); let impl_ty_predicates = tcx.predicates_of(impl_ty.def_id);
let trait_ty_predicates = tcx.predicates_of(trait_ty.def_id); let trait_ty_predicates = tcx.predicates_of(trait_ty.def_id);
check_region_bounds_on_impl_item(tcx, impl_ty, trait_ty, false)?; check_region_bounds_on_impl_item(tcx, impl_ty, trait_ty, false)?;
let impl_ty_own_bounds = impl_ty_predicates.instantiate_own(tcx, impl_substs); let impl_ty_own_bounds = impl_ty_predicates.instantiate_own(tcx, impl_args);
if impl_ty_own_bounds.len() == 0 { if impl_ty_own_bounds.len() == 0 {
// Nothing to check. // Nothing to check.
return Ok(()); return Ok(());
@ -1904,7 +1907,7 @@ fn compare_type_predicate_entailment<'tcx>(
// `ObligationCause` (and the `FnCtxt`). This is what // `ObligationCause` (and the `FnCtxt`). This is what
// `regionck_item` expects. // `regionck_item` expects.
let impl_ty_def_id = impl_ty.def_id.expect_local(); let impl_ty_def_id = impl_ty.def_id.expect_local();
debug!("compare_type_predicate_entailment: trait_to_impl_substs={:?}", trait_to_impl_substs); debug!("compare_type_predicate_entailment: trait_to_impl_args={:?}", trait_to_impl_args);
// The predicates declared by the impl definition, the trait and the // The predicates declared by the impl definition, the trait and the
// associated type in the trait are assumed. // associated type in the trait are assumed.
@ -1912,7 +1915,7 @@ fn compare_type_predicate_entailment<'tcx>(
let mut hybrid_preds = impl_predicates.instantiate_identity(tcx); let mut hybrid_preds = impl_predicates.instantiate_identity(tcx);
hybrid_preds.predicates.extend( hybrid_preds.predicates.extend(
trait_ty_predicates trait_ty_predicates
.instantiate_own(tcx, trait_to_impl_substs) .instantiate_own(tcx, trait_to_impl_args)
.map(|(predicate, _)| predicate), .map(|(predicate, _)| predicate),
); );
@ -1990,9 +1993,9 @@ pub(super) fn check_type_bounds<'tcx>(
// } // }
// //
// - `impl_trait_ref` would be `<(A, B) as Foo<u32>>` // - `impl_trait_ref` would be `<(A, B) as Foo<u32>>`
// - `normalize_impl_ty_substs` would be `[A, B, ^0.0]` (`^0.0` here is the bound var with db 0 and index 0) // - `normalize_impl_ty_args` would be `[A, B, ^0.0]` (`^0.0` here is the bound var with db 0 and index 0)
// - `normalize_impl_ty` would be `Wrapper<A, B, ^0.0>` // - `normalize_impl_ty` would be `Wrapper<A, B, ^0.0>`
// - `rebased_substs` would be `[(A, B), u32, ^0.0]`, combining the substs from // - `rebased_args` would be `[(A, B), u32, ^0.0]`, combining the args from
// the *trait* with the generic associated type parameters (as bound vars). // the *trait* with the generic associated type parameters (as bound vars).
// //
// A note regarding the use of bound vars here: // A note regarding the use of bound vars here:
@ -2022,9 +2025,11 @@ pub(super) fn check_type_bounds<'tcx>(
// the trait (notably, that X: Eq and T: Family). // the trait (notably, that X: Eq and T: Family).
let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> = let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> =
smallvec::SmallVec::with_capacity(tcx.generics_of(impl_ty.def_id).params.len()); smallvec::SmallVec::with_capacity(tcx.generics_of(impl_ty.def_id).params.len());
// Extend the impl's identity substs with late-bound GAT vars // Extend the impl's identity args with late-bound GAT vars
let normalize_impl_ty_substs = ty::InternalSubsts::identity_for_item(tcx, container_id) let normalize_impl_ty_args = ty::GenericArgs::identity_for_item(tcx, container_id).extend_to(
.extend_to(tcx, impl_ty.def_id, |param, _| match param.kind { tcx,
impl_ty.def_id,
|param, _| match param.kind {
GenericParamDefKind::Type { .. } => { GenericParamDefKind::Type { .. } => {
let kind = ty::BoundTyKind::Param(param.def_id, param.name); let kind = ty::BoundTyKind::Param(param.def_id, param.name);
let bound_var = ty::BoundVariableKind::Ty(kind); let bound_var = ty::BoundVariableKind::Ty(kind);
@ -2060,7 +2065,8 @@ pub(super) fn check_type_bounds<'tcx>(
) )
.into() .into()
} }
}); },
);
// When checking something like // When checking something like
// //
// trait X { type Y: PartialEq<<Self as X>::Y> } // trait X { type Y: PartialEq<<Self as X>::Y> }
@ -2070,15 +2076,14 @@ pub(super) fn check_type_bounds<'tcx>(
// we want <T as X>::Y to normalize to S. This is valid because we are // we want <T as X>::Y to normalize to S. This is valid because we are
// checking the default value specifically here. Add this equality to the // checking the default value specifically here. Add this equality to the
// ParamEnv for normalization specifically. // ParamEnv for normalization specifically.
let normalize_impl_ty = tcx.type_of(impl_ty.def_id).subst(tcx, normalize_impl_ty_substs); let normalize_impl_ty = tcx.type_of(impl_ty.def_id).instantiate(tcx, normalize_impl_ty_args);
let rebased_substs = let rebased_args = normalize_impl_ty_args.rebase_onto(tcx, container_id, impl_trait_ref.args);
normalize_impl_ty_substs.rebase_onto(tcx, container_id, impl_trait_ref.substs);
let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars); let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars);
let normalize_param_env = { let normalize_param_env = {
let mut predicates = param_env.caller_bounds().iter().collect::<Vec<_>>(); let mut predicates = param_env.caller_bounds().iter().collect::<Vec<_>>();
match normalize_impl_ty.kind() { match normalize_impl_ty.kind() {
ty::Alias(ty::Projection, proj) ty::Alias(ty::Projection, proj)
if proj.def_id == trait_ty.def_id && proj.substs == rebased_substs => if proj.def_id == trait_ty.def_id && proj.args == rebased_args =>
{ {
// Don't include this predicate if the projected type is // Don't include this predicate if the projected type is
// exactly the same as the projection. This can occur in // exactly the same as the projection. This can occur in
@ -2089,7 +2094,7 @@ pub(super) fn check_type_bounds<'tcx>(
_ => predicates.push( _ => predicates.push(
ty::Binder::bind_with_vars( ty::Binder::bind_with_vars(
ty::ProjectionPredicate { ty::ProjectionPredicate {
projection_ty: tcx.mk_alias_ty(trait_ty.def_id, rebased_substs), projection_ty: tcx.mk_alias_ty(trait_ty.def_id, rebased_args),
term: normalize_impl_ty.into(), term: normalize_impl_ty.into(),
}, },
bound_vars, bound_vars,
@ -2102,8 +2107,8 @@ pub(super) fn check_type_bounds<'tcx>(
debug!(?normalize_param_env); debug!(?normalize_param_env);
let impl_ty_def_id = impl_ty.def_id.expect_local(); let impl_ty_def_id = impl_ty.def_id.expect_local();
let impl_ty_substs = InternalSubsts::identity_for_item(tcx, impl_ty.def_id); let impl_ty_args = GenericArgs::identity_for_item(tcx, impl_ty.def_id);
let rebased_substs = impl_ty_substs.rebase_onto(tcx, container_id, impl_trait_ref.substs); let rebased_args = impl_ty_args.rebase_onto(tcx, container_id, impl_trait_ref.args);
let infcx = tcx.infer_ctxt().build(); let infcx = tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx); let ocx = ObligationCtxt::new(&infcx);
@ -2144,7 +2149,7 @@ pub(super) fn check_type_bounds<'tcx>(
let obligations: Vec<_> = tcx let obligations: Vec<_> = tcx
.explicit_item_bounds(trait_ty.def_id) .explicit_item_bounds(trait_ty.def_id)
.subst_iter_copied(tcx, rebased_substs) .arg_iter_copied(tcx, rebased_args)
.map(|(concrete_ty_bound, span)| { .map(|(concrete_ty_bound, span)| {
debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound); debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound);
traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound) traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound)

View File

@ -5,8 +5,8 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{struct_span_err, ErrorGuaranteed}; use rustc_errors::{struct_span_err, ErrorGuaranteed};
use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::outlives::env::OutlivesEnvironment;
use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt}; use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt};
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::util::CheckRegions; use rustc_middle::ty::util::CheckRegions;
use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::ty::{self, TyCtxt};
use rustc_trait_selection::traits::{self, ObligationCtxt}; use rustc_trait_selection::traits::{self, ObligationCtxt};
@ -44,21 +44,21 @@ pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), Erro
})); }));
} }
} }
let dtor_self_type = tcx.type_of(drop_impl_did).subst_identity(); let dtor_self_type = tcx.type_of(drop_impl_did).instantiate_identity();
match dtor_self_type.kind() { match dtor_self_type.kind() {
ty::Adt(adt_def, adt_to_impl_substs) => { ty::Adt(adt_def, adt_to_impl_args) => {
ensure_drop_params_and_item_params_correspond( ensure_drop_params_and_item_params_correspond(
tcx, tcx,
drop_impl_did.expect_local(), drop_impl_did.expect_local(),
adt_def.did(), adt_def.did(),
adt_to_impl_substs, adt_to_impl_args,
)?; )?;
ensure_drop_predicates_are_implied_by_item_defn( ensure_drop_predicates_are_implied_by_item_defn(
tcx, tcx,
drop_impl_did.expect_local(), drop_impl_did.expect_local(),
adt_def.did().expect_local(), adt_def.did().expect_local(),
adt_to_impl_substs, adt_to_impl_args,
) )
} }
_ => { _ => {
@ -79,9 +79,9 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
drop_impl_did: LocalDefId, drop_impl_did: LocalDefId,
self_type_did: DefId, self_type_did: DefId,
adt_to_impl_substs: SubstsRef<'tcx>, adt_to_impl_args: GenericArgsRef<'tcx>,
) -> Result<(), ErrorGuaranteed> { ) -> Result<(), ErrorGuaranteed> {
let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_substs, CheckRegions::OnlyEarlyBound) let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_args, CheckRegions::OnlyEarlyBound)
else { else {
return Ok(()); return Ok(());
}; };
@ -115,12 +115,12 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
drop_impl_def_id: LocalDefId, drop_impl_def_id: LocalDefId,
adt_def_id: LocalDefId, adt_def_id: LocalDefId,
adt_to_impl_substs: SubstsRef<'tcx>, adt_to_impl_args: GenericArgsRef<'tcx>,
) -> Result<(), ErrorGuaranteed> { ) -> Result<(), ErrorGuaranteed> {
let infcx = tcx.infer_ctxt().build(); let infcx = tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx); let ocx = ObligationCtxt::new(&infcx);
// Take the param-env of the adt and substitute the substs that show up in // Take the param-env of the adt and substitute the args that show up in
// the implementation's self type. This gives us the assumptions that the // the implementation's self type. This gives us the assumptions that the
// self ty of the implementation is allowed to know just from it being a // self ty of the implementation is allowed to know just from it being a
// well-formed adt, since that's all we're allowed to assume while proving // well-formed adt, since that's all we're allowed to assume while proving
@ -130,7 +130,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
// substituting it with free params, so no additional param-env normalization // substituting it with free params, so no additional param-env normalization
// can occur on top of what has been done in the param_env query itself. // can occur on top of what has been done in the param_env query itself.
let param_env = ty::EarlyBinder::bind(tcx.param_env(adt_def_id)) let param_env = ty::EarlyBinder::bind(tcx.param_env(adt_def_id))
.subst(tcx, adt_to_impl_substs) .instantiate(tcx, adt_to_impl_args)
.with_constness(tcx.constness(drop_impl_def_id)); .with_constness(tcx.constness(drop_impl_def_id));
for (pred, span) in tcx.predicates_of(drop_impl_def_id).instantiate_identity(tcx) { for (pred, span) in tcx.predicates_of(drop_impl_def_id).instantiate_identity(tcx) {

View File

@ -60,7 +60,7 @@ fn equate_intrinsic_type<'tcx>(
tcx, tcx,
&cause, &cause,
ty::ParamEnv::empty(), // FIXME: do all intrinsics have an empty param env? ty::ParamEnv::empty(), // FIXME: do all intrinsics have an empty param env?
Ty::new_fn_ptr(tcx, tcx.fn_sig(it.owner_id).subst_identity()), Ty::new_fn_ptr(tcx, tcx.fn_sig(it.owner_id).instantiate_identity()),
fty, fty,
); );
} }
@ -155,7 +155,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
ty::INNERMOST, ty::INNERMOST,
ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrEnv }, ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrEnv },
); );
let va_list_ty = tcx.type_of(did).subst(tcx, &[region.into()]); let va_list_ty = tcx.type_of(did).instantiate(tcx, &[region.into()]);
(Ty::new_ref(tcx, env_region, ty::TypeAndMut { ty: va_list_ty, mutbl }), va_list_ty) (Ty::new_ref(tcx, env_region, ty::TypeAndMut { ty: va_list_ty, mutbl }), va_list_ty)
}) })
}; };
@ -238,7 +238,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
ty: Ty::new_adt( ty: Ty::new_adt(
tcx, tcx,
tcx.adt_def(option_def_id), tcx.adt_def(option_def_id),
tcx.mk_substs_from_iter([ty::GenericArg::from(p0)].into_iter()), tcx.mk_args_from_iter([ty::GenericArg::from(p0)].into_iter()),
), ),
mutbl: hir::Mutability::Not, mutbl: hir::Mutability::Not,
}, },
@ -412,7 +412,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
ty::Region::new_late_bound(tcx, ty::INNERMOST, br), ty::Region::new_late_bound(tcx, ty::INNERMOST, br),
param(0), param(0),
)], )],
Ty::new_projection(tcx, discriminant_def_id, tcx.mk_substs(&[param(0).into()])), Ty::new_projection(tcx, discriminant_def_id, tcx.mk_args(&[param(0).into()])),
) )
} }

View File

@ -81,9 +81,9 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
ty::RawPtr(ty::TypeAndMut { ty, mutbl: _ }) if self.is_thin_ptr_ty(ty) => { ty::RawPtr(ty::TypeAndMut { ty, mutbl: _ }) if self.is_thin_ptr_ty(ty) => {
Some(asm_ty_isize) Some(asm_ty_isize)
} }
ty::Adt(adt, substs) if adt.repr().simd() => { ty::Adt(adt, args) if adt.repr().simd() => {
let fields = &adt.non_enum_variant().fields; let fields = &adt.non_enum_variant().fields;
let elem_ty = fields[FieldIdx::from_u32(0)].ty(self.tcx, substs); let elem_ty = fields[FieldIdx::from_u32(0)].ty(self.tcx, args);
let (size, ty) = match elem_ty.kind() { let (size, ty) = match elem_ty.kind() {
ty::Array(ty, len) => { ty::Array(ty, len) => {
@ -423,7 +423,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
// Check that sym actually points to a function. Later passes // Check that sym actually points to a function. Later passes
// depend on this. // depend on this.
hir::InlineAsmOperand::SymFn { anon_const } => { hir::InlineAsmOperand::SymFn { anon_const } => {
let ty = self.tcx.type_of(anon_const.def_id).subst_identity(); let ty = self.tcx.type_of(anon_const.def_id).instantiate_identity();
match ty.kind() { match ty.kind() {
ty::Never | ty::Error(_) => {} ty::Never | ty::Error(_) => {}
ty::FnDef(..) => {} ty::FnDef(..) => {}

View File

@ -38,7 +38,7 @@ can be broken down into several distinct phases:
While type checking a function, the intermediate types for the While type checking a function, the intermediate types for the
expressions, blocks, and so forth contained within the function are expressions, blocks, and so forth contained within the function are
stored in `fcx.node_types` and `fcx.node_substs`. These types stored in `fcx.node_types` and `fcx.node_args`. These types
may contain unresolved type variables. After type checking is may contain unresolved type variables. After type checking is
complete, the functions in the writeback module are used to take the complete, the functions in the writeback module are used to take the
types from this table, resolve them, and then write them into their types from this table, resolve them, and then write them into their
@ -80,7 +80,7 @@ use rustc_hir::intravisit::Visitor;
use rustc_index::bit_set::BitSet; use rustc_index::bit_set::BitSet;
use rustc_middle::query::Providers; use rustc_middle::query::Providers;
use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty::{InternalSubsts, SubstsRef}; use rustc_middle::ty::{GenericArgs, GenericArgsRef};
use rustc_session::parse::feature_err; use rustc_session::parse::feature_err;
use rustc_span::source_map::DUMMY_SP; use rustc_span::source_map::DUMMY_SP;
use rustc_span::symbol::{kw, Ident}; use rustc_span::symbol::{kw, Ident};
@ -211,7 +211,7 @@ fn missing_items_err(
let snippet = suggestion_signature( let snippet = suggestion_signature(
tcx, tcx,
trait_item, trait_item,
tcx.impl_trait_ref(impl_def_id).unwrap().subst_identity(), tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity(),
); );
let code = format!("{}{}\n{}", padding, snippet, padding); let code = format!("{}{}\n{}", padding, snippet, padding);
if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) { if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
@ -408,7 +408,7 @@ fn fn_sig_suggestion<'tcx>(
let asyncness = if tcx.asyncness(assoc.def_id).is_async() { let asyncness = if tcx.asyncness(assoc.def_id).is_async() {
output = if let ty::Alias(_, alias_ty) = *output.kind() { output = if let ty::Alias(_, alias_ty) = *output.kind() {
tcx.explicit_item_bounds(alias_ty.def_id) tcx.explicit_item_bounds(alias_ty.def_id)
.subst_iter_copied(tcx, alias_ty.substs) .arg_iter_copied(tcx, alias_ty.args)
.find_map(|(bound, _)| bound.as_projection_clause()?.no_bound_vars()?.term.ty()) .find_map(|(bound, _)| bound.as_projection_clause()?.no_bound_vars()?.term.ty())
.unwrap_or_else(|| { .unwrap_or_else(|| {
span_bug!( span_bug!(
@ -461,10 +461,10 @@ fn suggestion_signature<'tcx>(
assoc: ty::AssocItem, assoc: ty::AssocItem,
impl_trait_ref: ty::TraitRef<'tcx>, impl_trait_ref: ty::TraitRef<'tcx>,
) -> String { ) -> String {
let substs = ty::InternalSubsts::identity_for_item(tcx, assoc.def_id).rebase_onto( let args = ty::GenericArgs::identity_for_item(tcx, assoc.def_id).rebase_onto(
tcx, tcx,
assoc.container_id(tcx), assoc.container_id(tcx),
impl_trait_ref.with_self_ty(tcx, tcx.types.self_param).substs, impl_trait_ref.with_self_ty(tcx, tcx.types.self_param).args,
); );
match assoc.kind { match assoc.kind {
@ -472,21 +472,21 @@ fn suggestion_signature<'tcx>(
tcx, tcx,
tcx.liberate_late_bound_regions( tcx.liberate_late_bound_regions(
assoc.def_id, assoc.def_id,
tcx.fn_sig(assoc.def_id).subst(tcx, substs), tcx.fn_sig(assoc.def_id).instantiate(tcx, args),
), ),
assoc.ident(tcx), assoc.ident(tcx),
tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs), tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args),
assoc, assoc,
), ),
ty::AssocKind::Type => { ty::AssocKind::Type => {
let (generics, where_clauses) = bounds_from_generic_predicates( let (generics, where_clauses) = bounds_from_generic_predicates(
tcx, tcx,
tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs), tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args),
); );
format!("type {}{generics} = /* Type */{where_clauses};", assoc.name) format!("type {}{generics} = /* Type */{where_clauses};", assoc.name)
} }
ty::AssocKind::Const => { ty::AssocKind::Const => {
let ty = tcx.type_of(assoc.def_id).subst_identity(); let ty = tcx.type_of(assoc.def_id).instantiate_identity();
let val = ty_kind_suggestion(ty).unwrap_or("todo!()"); let val = ty_kind_suggestion(ty).unwrap_or("todo!()");
format!("const {}: {} = {};", assoc.name, ty, val) format!("const {}: {} = {};", assoc.name, ty, val)
} }

View File

@ -18,7 +18,7 @@ use rustc_middle::ty::{
self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
TypeVisitable, TypeVisitableExt, TypeVisitor, TypeVisitable, TypeVisitableExt, TypeVisitor,
}; };
use rustc_middle::ty::{GenericArgKind, InternalSubsts}; use rustc_middle::ty::{GenericArgKind, GenericArgs};
use rustc_session::parse::feature_err; use rustc_session::parse::feature_err;
use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP}; use rustc_span::{Span, DUMMY_SP};
@ -290,7 +290,7 @@ fn check_trait_item(tcx: TyCtxt<'_>, trait_item: &hir::TraitItem<'_>) {
/// Require that the user writes where clauses on GATs for the implicit /// Require that the user writes where clauses on GATs for the implicit
/// outlives bounds involving trait parameters in trait functions and /// outlives bounds involving trait parameters in trait functions and
/// lifetimes passed as GAT substs. See `self-outlives-lint` test. /// lifetimes passed as GAT args. See `self-outlives-lint` test.
/// ///
/// We use the following trait as an example throughout this function: /// We use the following trait as an example throughout this function:
/// ```rust,ignore (this code fails due to this lint) /// ```rust,ignore (this code fails due to this lint)
@ -314,7 +314,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
for gat_item in associated_items { for gat_item in associated_items {
let gat_def_id = gat_item.id.owner_id; let gat_def_id = gat_item.id.owner_id;
let gat_item = tcx.associated_item(gat_def_id); let gat_item = tcx.associated_item(gat_def_id);
// If this item is not an assoc ty, or has no substs, then it's not a GAT // If this item is not an assoc ty, or has no args, then it's not a GAT
if gat_item.kind != ty::AssocKind::Type { if gat_item.kind != ty::AssocKind::Type {
continue; continue;
} }
@ -345,7 +345,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
// `Self::Iter<'a>` is a GAT we want to gather any potential missing bounds from. // `Self::Iter<'a>` is a GAT we want to gather any potential missing bounds from.
let sig: ty::FnSig<'_> = tcx.liberate_late_bound_regions( let sig: ty::FnSig<'_> = tcx.liberate_late_bound_regions(
item_def_id.to_def_id(), item_def_id.to_def_id(),
tcx.fn_sig(item_def_id).subst_identity(), tcx.fn_sig(item_def_id).instantiate_identity(),
); );
gather_gat_bounds( gather_gat_bounds(
tcx, tcx,
@ -374,7 +374,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
param_env, param_env,
item_def_id, item_def_id,
tcx.explicit_item_bounds(item_def_id) tcx.explicit_item_bounds(item_def_id)
.subst_identity_iter_copied() .instantiate_identity_iter_copied()
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
&FxIndexSet::default(), &FxIndexSet::default(),
gat_def_id.def_id, gat_def_id.def_id,
@ -737,7 +737,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GATSubstCollector<'tcx> {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
match t.kind() { match t.kind() {
ty::Alias(ty::Projection, p) if p.def_id == self.gat => { ty::Alias(ty::Projection, p) if p.def_id == self.gat => {
for (idx, subst) in p.substs.iter().enumerate() { for (idx, subst) in p.args.iter().enumerate() {
match subst.unpack() { match subst.unpack() {
GenericArgKind::Lifetime(lt) if !lt.is_late_bound() => { GenericArgKind::Lifetime(lt) if !lt.is_late_bound() => {
self.regions.insert((lt, idx)); self.regions.insert((lt, idx));
@ -836,7 +836,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
// Const parameters are well formed if their type is structural match. // Const parameters are well formed if their type is structural match.
hir::GenericParamKind::Const { ty: hir_ty, default: _ } => { hir::GenericParamKind::Const { ty: hir_ty, default: _ } => {
let ty = tcx.type_of(param.def_id).subst_identity(); let ty = tcx.type_of(param.def_id).instantiate_identity();
if tcx.features().adt_const_params { if tcx.features().adt_const_params {
enter_wf_checking_ctxt(tcx, hir_ty.span, param.def_id, |wfcx| { enter_wf_checking_ctxt(tcx, hir_ty.span, param.def_id, |wfcx| {
@ -910,17 +910,17 @@ fn check_associated_item(
let self_ty = match item.container { let self_ty = match item.container {
ty::TraitContainer => tcx.types.self_param, ty::TraitContainer => tcx.types.self_param,
ty::ImplContainer => tcx.type_of(item.container_id(tcx)).subst_identity(), ty::ImplContainer => tcx.type_of(item.container_id(tcx)).instantiate_identity(),
}; };
match item.kind { match item.kind {
ty::AssocKind::Const => { ty::AssocKind::Const => {
let ty = tcx.type_of(item.def_id).subst_identity(); let ty = tcx.type_of(item.def_id).instantiate_identity();
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty); let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
wfcx.register_wf_obligation(span, loc, ty.into()); wfcx.register_wf_obligation(span, loc, ty.into());
} }
ty::AssocKind::Fn => { ty::AssocKind::Fn => {
let sig = tcx.fn_sig(item.def_id).subst_identity(); let sig = tcx.fn_sig(item.def_id).instantiate_identity();
let hir_sig = sig_if_method.expect("bad signature for method"); let hir_sig = sig_if_method.expect("bad signature for method");
check_fn_or_method( check_fn_or_method(
wfcx, wfcx,
@ -936,7 +936,7 @@ fn check_associated_item(
check_associated_type_bounds(wfcx, item, span) check_associated_type_bounds(wfcx, item, span)
} }
if item.defaultness(tcx).has_value() { if item.defaultness(tcx).has_value() {
let ty = tcx.type_of(item.def_id).subst_identity(); let ty = tcx.type_of(item.def_id).instantiate_identity();
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty); let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
wfcx.register_wf_obligation(span, loc, ty.into()); wfcx.register_wf_obligation(span, loc, ty.into());
} }
@ -969,7 +969,11 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b
let field_id = field.did.expect_local(); let field_id = field.did.expect_local();
let hir::FieldDef { ty: hir_ty, .. } = let hir::FieldDef { ty: hir_ty, .. } =
tcx.hir().get_by_def_id(field_id).expect_field(); tcx.hir().get_by_def_id(field_id).expect_field();
let ty = wfcx.normalize(hir_ty.span, None, tcx.type_of(field.did).subst_identity()); let ty = wfcx.normalize(
hir_ty.span,
None,
tcx.type_of(field.did).instantiate_identity(),
);
wfcx.register_wf_obligation( wfcx.register_wf_obligation(
hir_ty.span, hir_ty.span,
Some(WellFormedLoc::Ty(field_id)), Some(WellFormedLoc::Ty(field_id)),
@ -981,7 +985,7 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b
// intermediate types must be sized. // intermediate types must be sized.
let needs_drop_copy = || { let needs_drop_copy = || {
packed && { packed && {
let ty = tcx.type_of(variant.tail().did).subst_identity(); let ty = tcx.type_of(variant.tail().did).instantiate_identity();
let ty = tcx.erase_regions(ty); let ty = tcx.erase_regions(ty);
if ty.has_infer() { if ty.has_infer() {
tcx.sess tcx.sess
@ -1003,7 +1007,11 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b
let field_id = field.did.expect_local(); let field_id = field.did.expect_local();
let hir::FieldDef { ty: hir_ty, .. } = let hir::FieldDef { ty: hir_ty, .. } =
tcx.hir().get_by_def_id(field_id).expect_field(); tcx.hir().get_by_def_id(field_id).expect_field();
let ty = wfcx.normalize(hir_ty.span, None, tcx.type_of(field.did).subst_identity()); let ty = wfcx.normalize(
hir_ty.span,
None,
tcx.type_of(field.did).instantiate_identity(),
);
wfcx.register_bound( wfcx.register_bound(
traits::ObligationCause::new( traits::ObligationCause::new(
hir_ty.span, hir_ty.span,
@ -1083,16 +1091,17 @@ fn check_associated_type_bounds(wfcx: &WfCheckingCtxt<'_, '_>, item: ty::AssocIt
let bounds = wfcx.tcx().explicit_item_bounds(item.def_id); let bounds = wfcx.tcx().explicit_item_bounds(item.def_id);
debug!("check_associated_type_bounds: bounds={:?}", bounds); debug!("check_associated_type_bounds: bounds={:?}", bounds);
let wf_obligations = bounds.subst_identity_iter_copied().flat_map(|(bound, bound_span)| { let wf_obligations =
let normalized_bound = wfcx.normalize(span, None, bound); bounds.instantiate_identity_iter_copied().flat_map(|(bound, bound_span)| {
traits::wf::predicate_obligations( let normalized_bound = wfcx.normalize(span, None, bound);
wfcx.infcx, traits::wf::predicate_obligations(
wfcx.param_env, wfcx.infcx,
wfcx.body_def_id, wfcx.param_env,
normalized_bound.as_predicate(), wfcx.body_def_id,
bound_span, normalized_bound.as_predicate(),
) bound_span,
}); )
});
wfcx.register_obligations(wf_obligations); wfcx.register_obligations(wf_obligations);
} }
@ -1105,7 +1114,7 @@ fn check_item_fn(
decl: &hir::FnDecl<'_>, decl: &hir::FnDecl<'_>,
) { ) {
enter_wf_checking_ctxt(tcx, span, def_id, |wfcx| { enter_wf_checking_ctxt(tcx, span, def_id, |wfcx| {
let sig = tcx.fn_sig(def_id).subst_identity(); let sig = tcx.fn_sig(def_id).instantiate_identity();
check_fn_or_method(wfcx, ident.span, sig, decl, def_id); check_fn_or_method(wfcx, ident.span, sig, decl, def_id);
}) })
} }
@ -1125,7 +1134,7 @@ fn check_item_type(
debug!("check_item_type: {:?}", item_id); debug!("check_item_type: {:?}", item_id);
enter_wf_checking_ctxt(tcx, ty_span, item_id, |wfcx| { enter_wf_checking_ctxt(tcx, ty_span, item_id, |wfcx| {
let ty = tcx.type_of(item_id).subst_identity(); let ty = tcx.type_of(item_id).instantiate_identity();
let item_ty = wfcx.normalize(ty_span, Some(WellFormedLoc::Ty(item_id)), ty); let item_ty = wfcx.normalize(ty_span, Some(WellFormedLoc::Ty(item_id)), ty);
let forbid_unsized = match unsized_handling { let forbid_unsized = match unsized_handling {
@ -1178,7 +1187,7 @@ fn check_impl<'tcx>(
// `#[rustc_reservation_impl]` impls are not real impls and // `#[rustc_reservation_impl]` impls are not real impls and
// therefore don't need to be WF (the trait's `Self: Trait` predicate // therefore don't need to be WF (the trait's `Self: Trait` predicate
// won't hold). // won't hold).
let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap().subst_identity(); let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap().instantiate_identity();
let trait_ref = wfcx.normalize( let trait_ref = wfcx.normalize(
ast_trait_ref.path.span, ast_trait_ref.path.span,
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)), Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
@ -1211,7 +1220,7 @@ fn check_impl<'tcx>(
wfcx.register_obligations(obligations); wfcx.register_obligations(obligations);
} }
None => { None => {
let self_ty = tcx.type_of(item.owner_id).subst_identity(); let self_ty = tcx.type_of(item.owner_id).instantiate_identity();
let self_ty = wfcx.normalize( let self_ty = wfcx.normalize(
item.span, item.span,
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)), Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
@ -1256,7 +1265,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
match param.kind { match param.kind {
GenericParamDefKind::Type { .. } => { GenericParamDefKind::Type { .. } => {
if is_our_default(param) { if is_our_default(param) {
let ty = tcx.type_of(param.def_id).subst_identity(); let ty = tcx.type_of(param.def_id).instantiate_identity();
// Ignore dependent defaults -- that is, where the default of one type // 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 // 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. // be sure if it will error or not as user might always specify the other.
@ -1272,10 +1281,10 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
GenericParamDefKind::Const { .. } => { GenericParamDefKind::Const { .. } => {
if is_our_default(param) { if is_our_default(param) {
// FIXME(const_generics_defaults): This // FIXME(const_generics_defaults): This
// is incorrect when dealing with unused substs, for example // is incorrect when dealing with unused args, for example
// for `struct Foo<const N: usize, const M: usize = { 1 - 2 }>` // for `struct Foo<const N: usize, const M: usize = { 1 - 2 }>`
// we should eagerly error. // we should eagerly error.
let default_ct = tcx.const_param_default(param.def_id).subst_identity(); let default_ct = tcx.const_param_default(param.def_id).instantiate_identity();
if !default_ct.has_param() { if !default_ct.has_param() {
wfcx.register_wf_obligation( wfcx.register_wf_obligation(
tcx.def_span(param.def_id), tcx.def_span(param.def_id),
@ -1298,7 +1307,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
// For more examples see tests `defaults-well-formedness.rs` and `type-check-defaults.rs`. // For more examples see tests `defaults-well-formedness.rs` and `type-check-defaults.rs`.
// //
// First we build the defaulted substitution. // First we build the defaulted substitution.
let substs = InternalSubsts::for_item(tcx, def_id.to_def_id(), |param, _| { let args = GenericArgs::for_item(tcx, def_id.to_def_id(), |param, _| {
match param.kind { match param.kind {
GenericParamDefKind::Lifetime => { GenericParamDefKind::Lifetime => {
// All regions are identity. // All regions are identity.
@ -1308,7 +1317,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
GenericParamDefKind::Type { .. } => { GenericParamDefKind::Type { .. } => {
// If the param has a default, ... // If the param has a default, ...
if is_our_default(param) { if is_our_default(param) {
let default_ty = tcx.type_of(param.def_id).subst_identity(); let default_ty = tcx.type_of(param.def_id).instantiate_identity();
// ... and it's not a dependent default, ... // ... and it's not a dependent default, ...
if !default_ty.has_param() { if !default_ty.has_param() {
// ... then substitute it with the default. // ... then substitute it with the default.
@ -1321,7 +1330,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
GenericParamDefKind::Const { .. } => { GenericParamDefKind::Const { .. } => {
// If the param has a default, ... // If the param has a default, ...
if is_our_default(param) { if is_our_default(param) {
let default_ct = tcx.const_param_default(param.def_id).subst_identity(); let default_ct = tcx.const_param_default(param.def_id).instantiate_identity();
// ... and it's not a dependent default, ... // ... and it's not a dependent default, ...
if !default_ct.has_param() { if !default_ct.has_param() {
// ... then substitute it with the default. // ... then substitute it with the default.
@ -1366,7 +1375,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
} }
let mut param_count = CountParams::default(); let mut param_count = CountParams::default();
let has_region = pred.visit_with(&mut param_count).is_break(); let has_region = pred.visit_with(&mut param_count).is_break();
let substituted_pred = ty::EarlyBinder::bind(pred).subst(tcx, substs); let substituted_pred = ty::EarlyBinder::bind(pred).instantiate(tcx, args);
// Don't check non-defaulted params, dependent defaults (including lifetimes) // Don't check non-defaulted params, dependent defaults (including lifetimes)
// or preds with multiple params. // or preds with multiple params.
if substituted_pred.has_non_region_param() || param_count.params.len() > 1 || has_region if substituted_pred.has_non_region_param() || param_count.params.len() > 1 || has_region
@ -1529,7 +1538,7 @@ fn check_return_position_impl_trait_in_trait_bounds<'tcx>(
// strategy, we can't just call `check_associated_item` on the new RPITITs, // strategy, we can't just call `check_associated_item` on the new RPITITs,
// because tests like `tests/ui/async-await/in-trait/implied-bounds.rs` will fail. // because tests like `tests/ui/async-await/in-trait/implied-bounds.rs` will fail.
// That's because we need to check that the bounds of the RPITIT hold using // That's because we need to check that the bounds of the RPITIT hold using
// the special substs that we create during opaque type lowering, otherwise we're // the special args that we create during opaque type lowering, otherwise we're
// getting a bunch of early bound and free regions mixed up... Haven't looked too // getting a bunch of early bound and free regions mixed up... Haven't looked too
// deep into this, though. // deep into this, though.
struct ImplTraitInTraitFinder<'a, 'tcx> { struct ImplTraitInTraitFinder<'a, 'tcx> {
@ -1558,7 +1567,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
}); });
for (bound, bound_span) in tcx for (bound, bound_span) in tcx
.explicit_item_bounds(opaque_ty.def_id) .explicit_item_bounds(opaque_ty.def_id)
.subst_iter_copied(tcx, opaque_ty.substs) .arg_iter_copied(tcx, opaque_ty.args)
{ {
let bound = self.wfcx.normalize(bound_span, None, bound); let bound = self.wfcx.normalize(bound_span, None, bound);
self.wfcx.register_obligations(traits::wf::predicate_obligations( self.wfcx.register_obligations(traits::wf::predicate_obligations(
@ -1569,7 +1578,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
bound_span, bound_span,
)); ));
// Set the debruijn index back to innermost here, since we already eagerly // Set the debruijn index back to innermost here, since we already eagerly
// shifted the substs that we use to generate these bounds. This is unfortunately // shifted the args that we use to generate these bounds. This is unfortunately
// subtly different behavior than the `ImplTraitInTraitFinder` we use in `param_env`, // subtly different behavior than the `ImplTraitInTraitFinder` we use in `param_env`,
// but that function doesn't actually need to normalize the bound it's visiting // but that function doesn't actually need to normalize the bound it's visiting
// (whereas we have to do so here)... // (whereas we have to do so here)...
@ -1601,7 +1610,7 @@ fn check_method_receiver<'tcx>(
let span = fn_sig.decl.inputs[0].span; let span = fn_sig.decl.inputs[0].span;
let sig = tcx.fn_sig(method.def_id).subst_identity(); let sig = tcx.fn_sig(method.def_id).instantiate_identity();
let sig = tcx.liberate_late_bound_regions(method.def_id, sig); let sig = tcx.liberate_late_bound_regions(method.def_id, sig);
let sig = wfcx.normalize(span, None, sig); let sig = wfcx.normalize(span, None, sig);
@ -1773,9 +1782,9 @@ fn check_variances_for_type_defn<'tcx>(
item: &hir::Item<'tcx>, item: &hir::Item<'tcx>,
hir_generics: &hir::Generics<'_>, hir_generics: &hir::Generics<'_>,
) { ) {
let identity_substs = ty::InternalSubsts::identity_for_item(tcx, item.owner_id); let identity_args = ty::GenericArgs::identity_for_item(tcx, item.owner_id);
for field in tcx.adt_def(item.owner_id).all_fields() { for field in tcx.adt_def(item.owner_id).all_fields() {
if field.ty(tcx, identity_substs).references_error() { if field.ty(tcx, identity_args).references_error() {
return; return;
} }
} }

View File

@ -57,7 +57,7 @@ impl<'tcx> Checker<'tcx> {
fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) { fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
// Destructors only work on local ADT types. // Destructors only work on local ADT types.
match tcx.type_of(impl_did).subst_identity().kind() { match tcx.type_of(impl_did).instantiate_identity().kind() {
ty::Adt(def, _) if def.did().is_local() => return, ty::Adt(def, _) if def.did().is_local() => return,
ty::Error(_) => return, ty::Error(_) => return,
_ => {} _ => {}
@ -71,7 +71,7 @@ fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) { fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
debug!("visit_implementation_of_copy: impl_did={:?}", impl_did); debug!("visit_implementation_of_copy: impl_did={:?}", impl_did);
let self_type = tcx.type_of(impl_did).subst_identity(); let self_type = tcx.type_of(impl_did).instantiate_identity();
debug!("visit_implementation_of_copy: self_type={:?} (bound)", self_type); debug!("visit_implementation_of_copy: self_type={:?} (bound)", self_type);
let param_env = tcx.param_env(impl_did); let param_env = tcx.param_env(impl_did);
@ -100,7 +100,7 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
} }
fn visit_implementation_of_const_param_ty(tcx: TyCtxt<'_>, impl_did: LocalDefId) { fn visit_implementation_of_const_param_ty(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
let self_type = tcx.type_of(impl_did).subst_identity(); let self_type = tcx.type_of(impl_did).instantiate_identity();
assert!(!self_type.has_escaping_bound_vars()); assert!(!self_type.has_escaping_bound_vars());
let param_env = tcx.param_env(impl_did); let param_env = tcx.param_env(impl_did);
@ -139,13 +139,13 @@ 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 dispatch_from_dyn_trait = tcx.require_lang_item(LangItem::DispatchFromDyn, Some(span));
let source = tcx.type_of(impl_did).subst_identity(); let source = tcx.type_of(impl_did).instantiate_identity();
assert!(!source.has_escaping_bound_vars()); assert!(!source.has_escaping_bound_vars());
let target = { let target = {
let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().subst_identity(); let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().instantiate_identity();
assert_eq!(trait_ref.def_id, dispatch_from_dyn_trait); assert_eq!(trait_ref.def_id, dispatch_from_dyn_trait);
trait_ref.substs.type_at(1) trait_ref.args.type_at(1)
}; };
debug!("visit_implementation_of_dispatch_from_dyn: {:?} -> {:?}", source, target); debug!("visit_implementation_of_dispatch_from_dyn: {:?} -> {:?}", source, target);
@ -163,9 +163,7 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
if infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, r_a, *r_b).is_ok() if infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, r_a, *r_b).is_ok()
&& mutbl_a == *mutbl_b => {} && mutbl_a == *mutbl_b => {}
(&RawPtr(tm_a), &RawPtr(tm_b)) if tm_a.mutbl == tm_b.mutbl => (), (&RawPtr(tm_a), &RawPtr(tm_b)) if tm_a.mutbl == tm_b.mutbl => (),
(&Adt(def_a, substs_a), &Adt(def_b, substs_b)) (&Adt(def_a, args_a), &Adt(def_b, args_b)) if def_a.is_struct() && def_b.is_struct() => {
if def_a.is_struct() && def_b.is_struct() =>
{
if def_a != def_b { if def_a != def_b {
let source_path = tcx.def_path_str(def_a.did()); let source_path = tcx.def_path_str(def_a.did());
let target_path = tcx.def_path_str(def_b.did()); let target_path = tcx.def_path_str(def_b.did());
@ -194,8 +192,8 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
let coerced_fields = fields let coerced_fields = fields
.iter() .iter()
.filter(|field| { .filter(|field| {
let ty_a = field.ty(tcx, substs_a); let ty_a = field.ty(tcx, args_a);
let ty_b = field.ty(tcx, substs_b); let ty_b = field.ty(tcx, args_b);
if let Ok(layout) = tcx.layout_of(param_env.and(ty_a)) { if let Ok(layout) = tcx.layout_of(param_env.and(ty_a)) {
if layout.is_zst() && layout.align.abi.bytes() == 1 { if layout.is_zst() && layout.align.abi.bytes() == 1 {
@ -250,8 +248,8 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
format!( format!(
"`{}` (`{}` to `{}`)", "`{}` (`{}` to `{}`)",
field.name, field.name,
field.ty(tcx, substs_a), field.ty(tcx, args_a),
field.ty(tcx, substs_b), field.ty(tcx, args_b),
) )
}) })
.collect::<Vec<_>>() .collect::<Vec<_>>()
@ -268,7 +266,7 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
ty::TraitRef::new( ty::TraitRef::new(
tcx, tcx,
dispatch_from_dyn_trait, dispatch_from_dyn_trait,
[field.ty(tcx, substs_a), field.ty(tcx, substs_b)], [field.ty(tcx, args_a), field.ty(tcx, args_b)],
), ),
)); ));
} }
@ -300,10 +298,10 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
let unsize_trait = tcx.require_lang_item(LangItem::Unsize, Some(span)); let unsize_trait = tcx.require_lang_item(LangItem::Unsize, Some(span));
let source = tcx.type_of(impl_did).subst_identity(); let source = tcx.type_of(impl_did).instantiate_identity();
let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().subst_identity(); let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().instantiate_identity();
assert_eq!(trait_ref.def_id, coerce_unsized_trait); assert_eq!(trait_ref.def_id, coerce_unsized_trait);
let target = trait_ref.substs.type_at(1); let target = trait_ref.args.type_at(1);
debug!("visit_implementation_of_coerce_unsized: {:?} -> {:?} (bound)", source, target); debug!("visit_implementation_of_coerce_unsized: {:?} -> {:?} (bound)", source, target);
let param_env = tcx.param_env(impl_did); let param_env = tcx.param_env(impl_did);
@ -348,7 +346,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
check_mutbl(mt_a, mt_b, &|ty| Ty::new_imm_ptr(tcx, ty)) check_mutbl(mt_a, mt_b, &|ty| Ty::new_imm_ptr(tcx, ty))
} }
(&ty::Adt(def_a, substs_a), &ty::Adt(def_b, substs_b)) (&ty::Adt(def_a, args_a), &ty::Adt(def_b, args_b))
if def_a.is_struct() && def_b.is_struct() => if def_a.is_struct() && def_b.is_struct() =>
{ {
if def_a != def_b { if def_a != def_b {
@ -411,9 +409,9 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
let diff_fields = fields let diff_fields = fields
.iter_enumerated() .iter_enumerated()
.filter_map(|(i, f)| { .filter_map(|(i, f)| {
let (a, b) = (f.ty(tcx, substs_a), f.ty(tcx, substs_b)); let (a, b) = (f.ty(tcx, args_a), f.ty(tcx, args_b));
if tcx.type_of(f.did).subst_identity().is_phantom_data() { if tcx.type_of(f.did).instantiate_identity().is_phantom_data() {
// Ignore PhantomData fields // Ignore PhantomData fields
return None; return None;
} }

View File

@ -171,7 +171,7 @@ impl<'tcx> InherentCollect<'tcx> {
let id = id.owner_id.def_id; let id = id.owner_id.def_id;
let item_span = self.tcx.def_span(id); let item_span = self.tcx.def_span(id);
let self_ty = self.tcx.type_of(id).subst_identity(); let self_ty = self.tcx.type_of(id).instantiate_identity();
match *self_ty.kind() { match *self_ty.kind() {
ty::Adt(def, _) => self.check_def_id(id, self_ty, def.did()), ty::Adt(def, _) => self.check_def_id(id, self_ty, def.did()),
ty::Foreign(did) => self.check_def_id(id, self_ty, did), ty::Foreign(did) => self.check_def_id(id, self_ty, did),

View File

@ -122,7 +122,7 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) {
let impls = tcx.hir().trait_impls(def_id); let impls = tcx.hir().trait_impls(def_id);
for &impl_def_id in impls { for &impl_def_id in impls {
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().subst_identity(); let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity();
check_impl(tcx, impl_def_id, trait_ref); check_impl(tcx, impl_def_id, trait_ref);
check_object_overlap(tcx, impl_def_id, trait_ref); check_object_overlap(tcx, impl_def_id, trait_ref);

View File

@ -5,8 +5,8 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{struct_span_err, DelayDm}; use rustc_errors::{struct_span_err, DelayDm};
use rustc_errors::{Diagnostic, ErrorGuaranteed}; use rustc_errors::{Diagnostic, ErrorGuaranteed};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::util::CheckRegions; use rustc_middle::ty::util::CheckRegions;
use rustc_middle::ty::GenericArgs;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, AliasKind, ImplPolarity, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, self, AliasKind, ImplPolarity, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
TypeVisitor, TypeVisitor,
@ -22,7 +22,7 @@ pub(crate) fn orphan_check_impl(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
impl_def_id: LocalDefId, impl_def_id: LocalDefId,
) -> Result<(), ErrorGuaranteed> { ) -> Result<(), ErrorGuaranteed> {
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().subst_identity(); let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity();
trait_ref.error_reported()?; trait_ref.error_reported()?;
let ret = do_orphan_check_impl(tcx, trait_ref, impl_def_id); let ret = do_orphan_check_impl(tcx, trait_ref, impl_def_id);
@ -488,10 +488,10 @@ fn lint_auto_trait_impl<'tcx>(
trait_ref: ty::TraitRef<'tcx>, trait_ref: ty::TraitRef<'tcx>,
impl_def_id: LocalDefId, impl_def_id: LocalDefId,
) { ) {
assert_eq!(trait_ref.substs.len(), 1); assert_eq!(trait_ref.args.len(), 1);
let self_ty = trait_ref.self_ty(); let self_ty = trait_ref.self_ty();
let (self_type_did, substs) = match self_ty.kind() { let (self_type_did, args) = match self_ty.kind() {
ty::Adt(def, substs) => (def.did(), substs), ty::Adt(def, args) => (def.did(), args),
_ => { _ => {
// FIXME: should also lint for stuff like `&i32` but // FIXME: should also lint for stuff like `&i32` but
// considering that auto traits are unstable, that // considering that auto traits are unstable, that
@ -502,9 +502,9 @@ fn lint_auto_trait_impl<'tcx>(
}; };
// Impls which completely cover a given root type are fine as they // Impls which completely cover a given root type are fine as they
// disable auto impls entirely. So only lint if the substs // disable auto impls entirely. So only lint if the args
// are not a permutation of the identity substs. // are not a permutation of the identity args.
let Err(arg) = tcx.uses_unique_generic_params(substs, CheckRegions::No) else { let Err(arg) = tcx.uses_unique_generic_params(args, CheckRegions::No) else {
// ok // ok
return; return;
}; };
@ -585,14 +585,14 @@ fn fast_reject_auto_impl<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, self_ty:
} }
match t.kind() { match t.kind() {
ty::Adt(def, substs) if def.is_phantom_data() => substs.visit_with(self), ty::Adt(def, args) if def.is_phantom_data() => args.visit_with(self),
ty::Adt(def, substs) => { ty::Adt(def, args) => {
// @lcnr: This is the only place where cycles can happen. We avoid this // @lcnr: This is the only place where cycles can happen. We avoid this
// by only visiting each `DefId` once. // by only visiting each `DefId` once.
// //
// This will be is incorrect in subtle cases, but I don't care :) // This will be is incorrect in subtle cases, but I don't care :)
if self.seen.insert(def.did()) { if self.seen.insert(def.did()) {
for ty in def.all_fields().map(|field| field.ty(tcx, substs)) { for ty in def.all_fields().map(|field| field.ty(tcx, args)) {
ty.visit_with(self)?; ty.visit_with(self)?;
} }
} }
@ -605,9 +605,7 @@ fn fast_reject_auto_impl<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, self_ty:
} }
let self_ty_root = match self_ty.kind() { let self_ty_root = match self_ty.kind() {
ty::Adt(def, _) => { ty::Adt(def, _) => Ty::new_adt(tcx, *def, GenericArgs::identity_for_item(tcx, def.did())),
Ty::new_adt(tcx, *def, InternalSubsts::identity_for_item(tcx, def.did()))
}
_ => unimplemented!("unexpected self ty {:?}", self_ty), _ => unimplemented!("unexpected self ty {:?}", self_ty),
}; };

View File

@ -12,7 +12,7 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
let impl_ = item.expect_impl(); let impl_ = item.expect_impl();
if let Some(trait_ref) = tcx.impl_trait_ref(item.owner_id) { if let Some(trait_ref) = tcx.impl_trait_ref(item.owner_id) {
let trait_ref = trait_ref.subst_identity(); let trait_ref = trait_ref.instantiate_identity();
let trait_def = tcx.trait_def(trait_ref.def_id); let trait_def = tcx.trait_def(trait_ref.def_id);
let unsafe_attr = let unsafe_attr =
impl_.generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle"); impl_.generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle");

View File

@ -401,13 +401,13 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
poly_trait_ref: ty::PolyTraitRef<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tcx>,
) -> Ty<'tcx> { ) -> Ty<'tcx> {
if let Some(trait_ref) = poly_trait_ref.no_bound_vars() { if let Some(trait_ref) = poly_trait_ref.no_bound_vars() {
let item_substs = self.astconv().create_substs_for_associated_item( let item_args = self.astconv().create_args_for_associated_item(
span, span,
item_def_id, item_def_id,
item_segment, item_segment,
trait_ref.substs, trait_ref.args,
); );
Ty::new_projection(self.tcx(), item_def_id, item_substs) Ty::new_projection(self.tcx(), item_def_id, item_args)
} else { } else {
// There are no late-bound regions; we can just ignore the binder. // There are no late-bound regions; we can just ignore the binder.
let (mut mpart_sugg, mut inferred_sugg) = (None, None); let (mut mpart_sugg, mut inferred_sugg) = (None, None);
@ -1145,8 +1145,8 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig<
} }
Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor().is_some() => { Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor().is_some() => {
let ty = tcx.type_of(tcx.hir().get_parent_item(hir_id)).subst_identity(); let ty = tcx.type_of(tcx.hir().get_parent_item(hir_id)).instantiate_identity();
let inputs = data.fields().iter().map(|f| tcx.type_of(f.def_id).subst_identity()); let inputs = data.fields().iter().map(|f| tcx.type_of(f.def_id).instantiate_identity());
ty::Binder::dummy(tcx.mk_fn_sig( ty::Binder::dummy(tcx.mk_fn_sig(
inputs, inputs,
ty, ty,
@ -1161,15 +1161,13 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig<
// signatures and cannot be accessed through `fn_sig`. For // signatures and cannot be accessed through `fn_sig`. For
// example, a closure signature excludes the `self` // example, a closure signature excludes the `self`
// argument. In any case they are embedded within the // argument. In any case they are embedded within the
// closure type as part of the `ClosureSubsts`. // closure type as part of the `ClosureArgs`.
// //
// To get the signature of a closure, you should use the // To get the signature of a closure, you should use the
// `sig` method on the `ClosureSubsts`: // `sig` method on the `ClosureArgs`:
// //
// substs.as_closure().sig(def_id, tcx) // args.as_closure().sig(def_id, tcx)
bug!( bug!("to get the signature of a closure, use `args.as_closure().sig()` not `fn_sig()`",);
"to get the signature of a closure, use `substs.as_closure().sig()` not `fn_sig()`",
);
} }
x => { x => {
@ -1266,7 +1264,7 @@ fn suggest_impl_trait<'tcx>(
) -> Option<String> { ) -> Option<String> {
let format_as_assoc: fn(_, _, _, _, _) -> _ = let format_as_assoc: fn(_, _, _, _, _) -> _ =
|tcx: TyCtxt<'tcx>, |tcx: TyCtxt<'tcx>,
_: ty::SubstsRef<'tcx>, _: ty::GenericArgsRef<'tcx>,
trait_def_id: DefId, trait_def_id: DefId,
assoc_item_def_id: DefId, assoc_item_def_id: DefId,
item_ty: Ty<'tcx>| { item_ty: Ty<'tcx>| {
@ -1276,12 +1274,12 @@ fn suggest_impl_trait<'tcx>(
}; };
let format_as_parenthesized: fn(_, _, _, _, _) -> _ = let format_as_parenthesized: fn(_, _, _, _, _) -> _ =
|tcx: TyCtxt<'tcx>, |tcx: TyCtxt<'tcx>,
substs: ty::SubstsRef<'tcx>, args: ty::GenericArgsRef<'tcx>,
trait_def_id: DefId, trait_def_id: DefId,
_: DefId, _: DefId,
item_ty: Ty<'tcx>| { item_ty: Ty<'tcx>| {
let trait_name = tcx.item_name(trait_def_id); let trait_name = tcx.item_name(trait_def_id);
let args_tuple = substs.type_at(1); let args_tuple = args.type_at(1);
let ty::Tuple(types) = *args_tuple.kind() else { let ty::Tuple(types) = *args_tuple.kind() else {
return None; return None;
}; };
@ -1328,24 +1326,23 @@ fn suggest_impl_trait<'tcx>(
} }
let param_env = tcx.param_env(def_id); let param_env = tcx.param_env(def_id);
let infcx = tcx.infer_ctxt().build(); let infcx = tcx.infer_ctxt().build();
let substs = ty::InternalSubsts::for_item(tcx, trait_def_id, |param, _| { let args = ty::GenericArgs::for_item(tcx, trait_def_id, |param, _| {
if param.index == 0 { ret_ty.into() } else { infcx.var_for_def(span, param) } if param.index == 0 { ret_ty.into() } else { infcx.var_for_def(span, param) }
}); });
if !infcx.type_implements_trait(trait_def_id, substs, param_env).must_apply_modulo_regions() if !infcx.type_implements_trait(trait_def_id, args, param_env).must_apply_modulo_regions() {
{
continue; continue;
} }
let ocx = ObligationCtxt::new(&infcx); let ocx = ObligationCtxt::new(&infcx);
let item_ty = ocx.normalize( let item_ty = ocx.normalize(
&ObligationCause::misc(span, def_id), &ObligationCause::misc(span, def_id),
param_env, param_env,
Ty::new_projection(tcx, assoc_item_def_id, substs), Ty::new_projection(tcx, assoc_item_def_id, args),
); );
// FIXME(compiler-errors): We may benefit from resolving regions here. // FIXME(compiler-errors): We may benefit from resolving regions here.
if ocx.select_where_possible().is_empty() if ocx.select_where_possible().is_empty()
&& let item_ty = infcx.resolve_vars_if_possible(item_ty) && let item_ty = infcx.resolve_vars_if_possible(item_ty)
&& let Some(item_ty) = item_ty.make_suggestable(tcx, false) && let Some(item_ty) = item_ty.make_suggestable(tcx, false)
&& let Some(sugg) = formatter(tcx, infcx.resolve_vars_if_possible(substs), trait_def_id, assoc_item_def_id, item_ty) && let Some(sugg) = formatter(tcx, infcx.resolve_vars_if_possible(args), trait_def_id, assoc_item_def_id, item_ty)
{ {
return Some(sugg); return Some(sugg);
} }
@ -1363,7 +1360,7 @@ fn impl_trait_ref(
.of_trait .of_trait
.as_ref() .as_ref()
.map(|ast_trait_ref| { .map(|ast_trait_ref| {
let selfty = tcx.type_of(def_id).subst_identity(); let selfty = tcx.type_of(def_id).instantiate_identity();
icx.astconv().instantiate_mono_trait_ref( icx.astconv().instantiate_mono_trait_ref(
ast_trait_ref, ast_trait_ref,
selfty, selfty,

View File

@ -68,17 +68,17 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
// ^ parent_def_id // ^ parent_def_id
// //
// then we only want to return generics for params to the left of `N`. If we don't do that we // then we only want to return generics for params to the left of `N`. If we don't do that we
// end up with that const looking like: `ty::ConstKind::Unevaluated(def_id, substs: [N#0])`. // end up with that const looking like: `ty::ConstKind::Unevaluated(def_id, args: [N#0])`.
// //
// This causes ICEs (#86580) when building the substs for Foo in `fn foo() -> Foo { .. }` as // This causes ICEs (#86580) when building the args for Foo in `fn foo() -> Foo { .. }` as
// we substitute the defaults with the partially built substs when we build the substs. Subst'ing // we substitute the defaults with the partially built args when we build the args. Subst'ing
// the `N#0` on the unevaluated const indexes into the empty substs we're in the process of building. // the `N#0` on the unevaluated const indexes into the empty args we're in the process of building.
// //
// We fix this by having this function return the parent's generics ourselves and truncating the // We fix this by having this function return the parent's generics ourselves and truncating the
// generics to only include non-forward declared params (with the exception of the `Self` ty) // generics to only include non-forward declared params (with the exception of the `Self` ty)
// //
// For the above code example that means we want `substs: []` // For the above code example that means we want `args: []`
// For the following struct def we want `substs: [N#0]` when generics_of is called on // For the following struct def we want `args: [N#0]` when generics_of is called on
// the def id of the `{ N + 1 }` anon const // the def id of the `{ N + 1 }` anon const
// struct Foo<const N: usize, const M: usize = { N + 1 }>; // struct Foo<const N: usize, const M: usize = { N + 1 }>;
// //
@ -93,7 +93,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
return ty::Generics { return ty::Generics {
// we set the parent of these generics to be our parent's parent so that we // we set the parent of these generics to be our parent's parent so that we
// dont end up with substs: [N, M, N] for the const default on a struct like this: // dont end up with args: [N, M, N] for the const default on a struct like this:
// struct Foo<const N: usize, const M: usize = { ... }>; // struct Foo<const N: usize, const M: usize = { ... }>;
parent: generics.parent, parent: generics.parent,
parent_count: generics.parent_count, parent_count: generics.parent_count,

View File

@ -2,7 +2,7 @@ use super::ItemCtxt;
use crate::astconv::{AstConv, PredicateFilter}; use crate::astconv::{AstConv, PredicateFilter};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_infer::traits::util; use rustc_infer::traits::util;
use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::GenericArgs;
use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::Span; use rustc_span::Span;
@ -10,7 +10,7 @@ use rustc_span::Span;
/// For associated types we include both bounds written on the type /// For associated types we include both bounds written on the type
/// (`type X: Trait`) and predicates from the trait: `where Self::X: Trait`. /// (`type X: Trait`) and predicates from the trait: `where Self::X: Trait`.
/// ///
/// Note that this filtering is done with the items identity substs to /// Note that this filtering is done with the items identity args to
/// simplify checking that these bounds are met in impls. This means that /// simplify checking that these bounds are met in impls. This means that
/// a bound such as `for<'b> <Self as X<'b>>::U: Clone` can't be used, as in /// a bound such as `for<'b> <Self as X<'b>>::U: Clone` can't be used, as in
/// `hr-associated-type-bound-1.rs`. /// `hr-associated-type-bound-1.rs`.
@ -23,7 +23,7 @@ fn associated_type_bounds<'tcx>(
let item_ty = Ty::new_projection( let item_ty = Ty::new_projection(
tcx, tcx,
assoc_item_def_id.to_def_id(), assoc_item_def_id.to_def_id(),
InternalSubsts::identity_for_item(tcx, assoc_item_def_id), GenericArgs::identity_for_item(tcx, assoc_item_def_id),
); );
let icx = ItemCtxt::new(tcx, assoc_item_def_id); let icx = ItemCtxt::new(tcx, assoc_item_def_id);
@ -95,7 +95,7 @@ pub(super) fn explicit_item_bounds(
Ty::new_projection( Ty::new_projection(
tcx, tcx,
def_id.to_def_id(), def_id.to_def_id(),
ty::InternalSubsts::identity_for_item(tcx, def_id), ty::GenericArgs::identity_for_item(tcx, def_id),
), ),
item.span, item.span,
)); ));
@ -117,8 +117,8 @@ pub(super) fn explicit_item_bounds(
span, span,
.. ..
}) => { }) => {
let substs = InternalSubsts::identity_for_item(tcx, def_id); let args = GenericArgs::identity_for_item(tcx, def_id);
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), substs); let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
opaque_type_bounds(tcx, def_id, bounds, item_ty, *span) opaque_type_bounds(tcx, def_id, bounds, item_ty, *span)
} }
hir::Node::Item(hir::Item { kind: hir::ItemKind::TyAlias(..), .. }) => &[], hir::Node::Item(hir::Item { kind: hir::ItemKind::TyAlias(..), .. }) => &[],

View File

@ -8,7 +8,6 @@ use rustc_hir as hir;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::intravisit::{self, Visitor};
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty::{GenericPredicates, Generics, ImplTraitInTraitData, ToPredicate}; use rustc_middle::ty::{GenericPredicates, Generics, ImplTraitInTraitData, ToPredicate};
use rustc_span::symbol::{sym, Ident}; use rustc_span::symbol::{sym, Ident};
@ -80,10 +79,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
// both to ensure that the RPITITs are only instantiated when the // both to ensure that the RPITITs are only instantiated when the
// parent predicates would hold, and also so that the param-env // parent predicates would hold, and also so that the param-env
// inherits these predicates as assumptions. // inherits these predicates as assumptions.
let identity_substs = InternalSubsts::identity_for_item(tcx, def_id); let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
predicates.extend( predicates
tcx.explicit_predicates_of(fn_def_id).instantiate_own(tcx, identity_substs), .extend(tcx.explicit_predicates_of(fn_def_id).instantiate_own(tcx, identity_args));
);
// We also install bidirectional outlives predicates for the RPITIT // We also install bidirectional outlives predicates for the RPITIT
// to keep the duplicates lifetimes from opaque lowering in sync. // to keep the duplicates lifetimes from opaque lowering in sync.
@ -108,15 +106,15 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
let trait_assoc_predicates = let trait_assoc_predicates =
tcx.explicit_predicates_of(assoc_item.trait_item_def_id.unwrap()); tcx.explicit_predicates_of(assoc_item.trait_item_def_id.unwrap());
let impl_assoc_identity_substs = InternalSubsts::identity_for_item(tcx, def_id); let impl_assoc_identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
let impl_def_id = tcx.parent(fn_def_id); let impl_def_id = tcx.parent(fn_def_id);
let impl_trait_ref_substs = let impl_trait_ref_args =
tcx.impl_trait_ref(impl_def_id).unwrap().subst_identity().substs; tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity().args;
let impl_assoc_substs = let impl_assoc_args =
impl_assoc_identity_substs.rebase_onto(tcx, impl_def_id, impl_trait_ref_substs); impl_assoc_identity_args.rebase_onto(tcx, impl_def_id, impl_trait_ref_args);
let impl_predicates = trait_assoc_predicates.instantiate_own(tcx, impl_assoc_substs); let impl_predicates = trait_assoc_predicates.instantiate_own(tcx, impl_assoc_args);
return ty::GenericPredicates { return ty::GenericPredicates {
parent: Some(impl_def_id), parent: Some(impl_def_id),
@ -150,8 +148,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
Node::Item(item) => match item.kind { Node::Item(item) => match item.kind {
ItemKind::Impl(impl_) => { ItemKind::Impl(impl_) => {
if impl_.defaultness.is_default() { if impl_.defaultness.is_default() {
is_default_impl_trait = is_default_impl_trait = tcx
tcx.impl_trait_ref(def_id).map(|t| ty::Binder::dummy(t.subst_identity())); .impl_trait_ref(def_id)
.map(|t| ty::Binder::dummy(t.instantiate_identity()));
} }
impl_.generics impl_.generics
} }
@ -337,8 +336,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
// in trait checking. See `setup_constraining_predicates` // in trait checking. See `setup_constraining_predicates`
// for details. // for details.
if let Node::Item(&Item { kind: ItemKind::Impl { .. }, .. }) = node { if let Node::Item(&Item { kind: ItemKind::Impl { .. }, .. }) = node {
let self_ty = tcx.type_of(def_id).subst_identity(); let self_ty = tcx.type_of(def_id).instantiate_identity();
let trait_ref = tcx.impl_trait_ref(def_id).map(ty::EarlyBinder::subst_identity); let trait_ref = tcx.impl_trait_ref(def_id).map(ty::EarlyBinder::instantiate_identity);
cgp::setup_constraining_predicates( cgp::setup_constraining_predicates(
tcx, tcx,
&mut predicates, &mut predicates,
@ -397,7 +396,7 @@ fn compute_bidirectional_outlives_predicates<'tcx>(
let orig_region = icx.astconv().ast_region_to_region(&arg, None); let orig_region = icx.astconv().ast_region_to_region(&arg, None);
if !matches!(orig_region.kind(), ty::ReEarlyBound(..)) { if !matches!(orig_region.kind(), ty::ReEarlyBound(..)) {
// There is no late-bound lifetime to actually match up here, since the lifetime doesn't // There is no late-bound lifetime to actually match up here, since the lifetime doesn't
// show up in the opaque's parent's substs. // show up in the opaque's parent's args.
continue; continue;
} }
@ -499,20 +498,20 @@ pub(super) fn explicit_predicates_of<'tcx>(
// Remove bounds on associated types from the predicates, they will be // Remove bounds on associated types from the predicates, they will be
// returned by `explicit_item_bounds`. // returned by `explicit_item_bounds`.
let predicates_and_bounds = tcx.trait_explicit_predicates_and_bounds(def_id); let predicates_and_bounds = tcx.trait_explicit_predicates_and_bounds(def_id);
let trait_identity_substs = InternalSubsts::identity_for_item(tcx, def_id); let trait_identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
let is_assoc_item_ty = |ty: Ty<'tcx>| { let is_assoc_item_ty = |ty: Ty<'tcx>| {
// For a predicate from a where clause to become a bound on an // For a predicate from a where clause to become a bound on an
// associated type: // associated type:
// * It must use the identity substs of the item. // * It must use the identity args of the item.
// * We're in the scope of the trait, so we can't name any // * We're in the scope of the trait, so we can't name any
// parameters of the GAT. That means that all we need to // parameters of the GAT. That means that all we need to
// check are that the substs of the projection are the // check are that the args of the projection are the
// identity substs of the trait. // identity args of the trait.
// * It must be an associated type for this trait (*not* a // * It must be an associated type for this trait (*not* a
// supertrait). // supertrait).
if let ty::Alias(ty::Projection, projection) = ty.kind() { if let ty::Alias(ty::Projection, projection) = ty.kind() {
projection.substs == trait_identity_substs projection.args == trait_identity_args
// FIXME(return_type_notation): This check should be more robust // FIXME(return_type_notation): This check should be more robust
&& !tcx.is_impl_trait_in_trait(projection.def_id) && !tcx.is_impl_trait_in_trait(projection.def_id)
&& tcx.associated_item(projection.def_id).container_id(tcx) && tcx.associated_item(projection.def_id).container_id(tcx)

View File

@ -1721,7 +1721,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
}, },
)); ));
bound_vars bound_vars
.extend(self.tcx.fn_sig(assoc_fn.def_id).subst_identity().bound_vars()); .extend(self.tcx.fn_sig(assoc_fn.def_id).instantiate_identity().bound_vars());
bound_vars bound_vars
} else { } else {
self.tcx.sess.delay_span_bug( self.tcx.sess.delay_span_bug(
@ -2038,12 +2038,12 @@ fn is_late_bound_map(
hir::Path { res: Res::Def(DefKind::TyAlias, alias_def), segments, span }, hir::Path { res: Res::Def(DefKind::TyAlias, alias_def), segments, span },
)) => { )) => {
// See comments on `ConstrainedCollectorPostAstConv` for why this arm does not just consider // See comments on `ConstrainedCollectorPostAstConv` for why this arm does not just consider
// substs to be unconstrained. // args to be unconstrained.
let generics = self.tcx.generics_of(alias_def); let generics = self.tcx.generics_of(alias_def);
let mut walker = ConstrainedCollectorPostAstConv { let mut walker = ConstrainedCollectorPostAstConv {
arg_is_constrained: vec![false; generics.params.len()].into_boxed_slice(), arg_is_constrained: vec![false; generics.params.len()].into_boxed_slice(),
}; };
walker.visit_ty(self.tcx.type_of(alias_def).subst_identity()); walker.visit_ty(self.tcx.type_of(alias_def).instantiate_identity());
match segments.last() { match segments.last() {
Some(hir::PathSegment { args: Some(args), .. }) => { Some(hir::PathSegment { args: Some(args), .. }) => {

View File

@ -3,7 +3,6 @@ use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId; use rustc_hir::def_id::LocalDefId;
use rustc_hir::HirId; use rustc_hir::HirId;
use rustc_middle::ty::print::with_forced_trimmed_paths; use rustc_middle::ty::print::with_forced_trimmed_paths;
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, ImplTraitInTraitData, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{self, ImplTraitInTraitData, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::symbol::Ident; use rustc_span::symbol::Ident;
@ -338,8 +337,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
let output = match tcx.hir().get(hir_id) { let output = match tcx.hir().get(hir_id) {
Node::TraitItem(item) => match item.kind { Node::TraitItem(item) => match item.kind {
TraitItemKind::Fn(..) => { TraitItemKind::Fn(..) => {
let substs = InternalSubsts::identity_for_item(tcx, def_id); let args = ty::GenericArgs::identity_for_item(tcx, def_id);
Ty::new_fn_def(tcx, def_id.to_def_id(), substs) Ty::new_fn_def(tcx, def_id.to_def_id(), args)
} }
TraitItemKind::Const(ty, body_id) => body_id TraitItemKind::Const(ty, body_id) => body_id
.and_then(|body_id| { .and_then(|body_id| {
@ -363,8 +362,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
Node::ImplItem(item) => match item.kind { Node::ImplItem(item) => match item.kind {
ImplItemKind::Fn(..) => { ImplItemKind::Fn(..) => {
let substs = InternalSubsts::identity_for_item(tcx, def_id); let args = ty::GenericArgs::identity_for_item(tcx, def_id);
Ty::new_fn_def(tcx, def_id.to_def_id(), substs) Ty::new_fn_def(tcx, def_id.to_def_id(), args)
} }
ImplItemKind::Const(ty, body_id) => { ImplItemKind::Const(ty, body_id) => {
if is_suggestable_infer_ty(ty) { if is_suggestable_infer_ty(ty) {
@ -426,13 +425,13 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
_ => icx.to_ty(*self_ty), _ => icx.to_ty(*self_ty),
}, },
ItemKind::Fn(..) => { ItemKind::Fn(..) => {
let substs = InternalSubsts::identity_for_item(tcx, def_id); let args = ty::GenericArgs::identity_for_item(tcx, def_id);
Ty::new_fn_def(tcx, def_id.to_def_id(), substs) Ty::new_fn_def(tcx, def_id.to_def_id(), args)
} }
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => { ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => {
let def = tcx.adt_def(def_id); let def = tcx.adt_def(def_id);
let substs = InternalSubsts::identity_for_item(tcx, def_id); let args = ty::GenericArgs::identity_for_item(tcx, def_id);
Ty::new_adt(tcx, def, substs) Ty::new_adt(tcx, def, args)
} }
ItemKind::OpaqueTy(OpaqueTy { ItemKind::OpaqueTy(OpaqueTy {
origin: hir::OpaqueTyOrigin::TyAlias { .. }, origin: hir::OpaqueTyOrigin::TyAlias { .. },
@ -472,8 +471,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
Node::ForeignItem(foreign_item) => match foreign_item.kind { Node::ForeignItem(foreign_item) => match foreign_item.kind {
ForeignItemKind::Fn(..) => { ForeignItemKind::Fn(..) => {
let substs = InternalSubsts::identity_for_item(tcx, def_id); let args = ty::GenericArgs::identity_for_item(tcx, def_id);
Ty::new_fn_def(tcx, def_id.to_def_id(), substs) Ty::new_fn_def(tcx, def_id.to_def_id(), args)
} }
ForeignItemKind::Static(t, _) => icx.to_ty(t), ForeignItemKind::Static(t, _) => icx.to_ty(t),
ForeignItemKind::Type => Ty::new_foreign(tcx, def_id.to_def_id()), ForeignItemKind::Type => Ty::new_foreign(tcx, def_id.to_def_id()),
@ -481,11 +480,11 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
Node::Ctor(def) | Node::Variant(Variant { data: def, .. }) => match def { Node::Ctor(def) | Node::Variant(Variant { data: def, .. }) => match def {
VariantData::Unit(..) | VariantData::Struct(..) => { VariantData::Unit(..) | VariantData::Struct(..) => {
tcx.type_of(tcx.hir().get_parent_item(hir_id)).subst_identity() tcx.type_of(tcx.hir().get_parent_item(hir_id)).instantiate_identity()
} }
VariantData::Tuple(..) => { VariantData::Tuple(..) => {
let substs = InternalSubsts::identity_for_item(tcx, def_id); let args = ty::GenericArgs::identity_for_item(tcx, def_id);
Ty::new_fn_def(tcx, def_id.to_def_id(), substs) Ty::new_fn_def(tcx, def_id.to_def_id(), args)
} }
}, },
@ -498,8 +497,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
Node::AnonConst(_) => anon_const_type_of(tcx, def_id), Node::AnonConst(_) => anon_const_type_of(tcx, def_id),
Node::ConstBlock(_) => { Node::ConstBlock(_) => {
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id()); let args = ty::GenericArgs::identity_for_item(tcx, def_id.to_def_id());
substs.as_inline_const().ty() args.as_inline_const().ty()
} }
Node::GenericParam(param) => match &param.kind { Node::GenericParam(param) => match &param.kind {

View File

@ -70,7 +70,7 @@ pub fn provide(providers: &mut Providers) {
fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) { fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) {
// Every lifetime used in an associated type must be constrained. // Every lifetime used in an associated type must be constrained.
let impl_self_ty = tcx.type_of(impl_def_id).subst_identity(); let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity();
if impl_self_ty.references_error() { if impl_self_ty.references_error() {
// Don't complain about unconstrained type params when self ty isn't known due to errors. // Don't complain about unconstrained type params when self ty isn't known due to errors.
// (#36836) // (#36836)
@ -85,7 +85,7 @@ fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId)
} }
let impl_generics = tcx.generics_of(impl_def_id); let impl_generics = tcx.generics_of(impl_def_id);
let impl_predicates = tcx.predicates_of(impl_def_id); let impl_predicates = tcx.predicates_of(impl_def_id);
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).map(ty::EarlyBinder::subst_identity); let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).map(ty::EarlyBinder::instantiate_identity);
let mut input_parameters = cgp::parameters_for_impl(impl_self_ty, impl_trait_ref); let mut input_parameters = cgp::parameters_for_impl(impl_self_ty, impl_trait_ref);
cgp::identify_constrained_generic_params( cgp::identify_constrained_generic_params(
@ -104,7 +104,7 @@ fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId)
match item.kind { match item.kind {
ty::AssocKind::Type => { ty::AssocKind::Type => {
if item.defaultness(tcx).has_value() { if item.defaultness(tcx).has_value() {
cgp::parameters_for(&tcx.type_of(def_id).subst_identity(), true) cgp::parameters_for(&tcx.type_of(def_id).instantiate_identity(), true)
} else { } else {
vec![] vec![]
} }

View File

@ -14,15 +14,15 @@
//! To enforce this requirement on specializations we take the following //! To enforce this requirement on specializations we take the following
//! approach: //! approach:
//! //!
//! 1. Match up the substs for `impl2` so that the implemented trait and //! 1. Match up the args for `impl2` so that the implemented trait and
//! self-type match those for `impl1`. //! self-type match those for `impl1`.
//! 2. Check for any direct use of `'static` in the substs of `impl2`. //! 2. Check for any direct use of `'static` in the args of `impl2`.
//! 3. Check that all of the generic parameters of `impl1` occur at most once //! 3. Check that all of the generic parameters of `impl1` occur at most once
//! in the *unconstrained* substs for `impl2`. A parameter is constrained if //! in the *unconstrained* args for `impl2`. A parameter is constrained if
//! its value is completely determined by an associated type projection //! its value is completely determined by an associated type projection
//! predicate. //! predicate.
//! 4. Check that all predicates on `impl1` either exist on `impl2` (after //! 4. Check that all predicates on `impl1` either exist on `impl2` (after
//! matching substs), or are well-formed predicates for the trait's type //! matching args), or are well-formed predicates for the trait's type
//! arguments. //! arguments.
//! //!
//! ## Example //! ## Example
@ -74,13 +74,13 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::outlives::env::OutlivesEnvironment;
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::specialization_graph::Node; use rustc_infer::traits::specialization_graph::Node;
use rustc_middle::ty::subst::{GenericArg, InternalSubsts, SubstsRef};
use rustc_middle::ty::trait_def::TraitSpecializationKind; use rustc_middle::ty::trait_def::TraitSpecializationKind;
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
use rustc_middle::ty::{GenericArg, GenericArgs, GenericArgsRef};
use rustc_span::{ErrorGuaranteed, Span}; use rustc_span::{ErrorGuaranteed, Span};
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
use rustc_trait_selection::traits::{self, translate_substs_with_cause, wf, ObligationCtxt}; use rustc_trait_selection::traits::{self, translate_args_with_cause, wf, ObligationCtxt};
pub(super) fn check_min_specialization(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) { pub(super) fn check_min_specialization(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) {
if let Some(node) = parent_specialization_node(tcx, impl_def_id) { if let Some(node) = parent_specialization_node(tcx, impl_def_id) {
@ -113,20 +113,20 @@ fn check_always_applicable(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node
let span = tcx.def_span(impl1_def_id); let span = tcx.def_span(impl1_def_id);
check_has_items(tcx, impl1_def_id, impl2_node, span); check_has_items(tcx, impl1_def_id, impl2_node, span);
if let Ok((impl1_substs, impl2_substs)) = get_impl_substs(tcx, impl1_def_id, impl2_node) { if let Ok((impl1_args, impl2_args)) = get_impl_args(tcx, impl1_def_id, impl2_node) {
let impl2_def_id = impl2_node.def_id(); let impl2_def_id = impl2_node.def_id();
debug!(?impl2_def_id, ?impl2_substs); debug!(?impl2_def_id, ?impl2_args);
let parent_substs = if impl2_node.is_from_trait() { let parent_args = if impl2_node.is_from_trait() {
impl2_substs.to_vec() impl2_args.to_vec()
} else { } else {
unconstrained_parent_impl_substs(tcx, impl2_def_id, impl2_substs) unconstrained_parent_impl_args(tcx, impl2_def_id, impl2_args)
}; };
check_constness(tcx, impl1_def_id, impl2_node, span); check_constness(tcx, impl1_def_id, impl2_node, span);
check_static_lifetimes(tcx, &parent_substs, span); check_static_lifetimes(tcx, &parent_args, span);
check_duplicate_params(tcx, impl1_substs, &parent_substs, span); check_duplicate_params(tcx, impl1_args, &parent_args, span);
check_predicates(tcx, impl1_def_id, impl1_substs, impl2_node, impl2_substs, span); check_predicates(tcx, impl1_def_id, impl1_args, impl2_node, impl2_args, span);
} }
} }
@ -167,23 +167,23 @@ fn check_constness(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node,
/// ``` /// ```
/// ///
/// Would return `S1 = [C]` and `S2 = [Vec<C>, C]`. /// Would return `S1 = [C]` and `S2 = [Vec<C>, C]`.
fn get_impl_substs( fn get_impl_args(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
impl1_def_id: LocalDefId, impl1_def_id: LocalDefId,
impl2_node: Node, impl2_node: Node,
) -> Result<(SubstsRef<'_>, SubstsRef<'_>), ErrorGuaranteed> { ) -> Result<(GenericArgsRef<'_>, GenericArgsRef<'_>), ErrorGuaranteed> {
let infcx = &tcx.infer_ctxt().build(); let infcx = &tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(infcx); let ocx = ObligationCtxt::new(infcx);
let param_env = tcx.param_env(impl1_def_id); let param_env = tcx.param_env(impl1_def_id);
let impl1_span = tcx.def_span(impl1_def_id); let impl1_span = tcx.def_span(impl1_def_id);
let assumed_wf_types = ocx.assumed_wf_types_and_report_errors(param_env, impl1_def_id)?; let assumed_wf_types = ocx.assumed_wf_types_and_report_errors(param_env, impl1_def_id)?;
let impl1_substs = InternalSubsts::identity_for_item(tcx, impl1_def_id); let impl1_args = GenericArgs::identity_for_item(tcx, impl1_def_id);
let impl2_substs = translate_substs_with_cause( let impl2_args = translate_args_with_cause(
infcx, infcx,
param_env, param_env,
impl1_def_id.to_def_id(), impl1_def_id.to_def_id(),
impl1_substs, impl1_args,
impl2_node, impl2_node,
|_, span| { |_, span| {
traits::ObligationCause::new( traits::ObligationCause::new(
@ -203,12 +203,12 @@ fn get_impl_substs(
let implied_bounds = infcx.implied_bounds_tys(param_env, impl1_def_id, assumed_wf_types); let implied_bounds = infcx.implied_bounds_tys(param_env, impl1_def_id, assumed_wf_types);
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
let _ = ocx.resolve_regions_and_report_errors(impl1_def_id, &outlives_env); let _ = ocx.resolve_regions_and_report_errors(impl1_def_id, &outlives_env);
let Ok(impl2_substs) = infcx.fully_resolve(impl2_substs) else { let Ok(impl2_args) = infcx.fully_resolve(impl2_args) else {
let span = tcx.def_span(impl1_def_id); let span = tcx.def_span(impl1_def_id);
let guar = tcx.sess.emit_err(SubstsOnOverriddenImpl { span }); let guar = tcx.sess.emit_err(SubstsOnOverriddenImpl { span });
return Err(guar); return Err(guar);
}; };
Ok((impl1_substs, impl2_substs)) Ok((impl1_args, impl2_args))
} }
/// Returns a list of all of the unconstrained subst of the given impl. /// Returns a list of all of the unconstrained subst of the given impl.
@ -217,17 +217,17 @@ fn get_impl_substs(
/// ///
/// impl<'a, T, I> ... where &'a I: IntoIterator<Item=&'a T> /// impl<'a, T, I> ... where &'a I: IntoIterator<Item=&'a T>
/// ///
/// This would return the substs corresponding to `['a, I]`, because knowing /// This would return the args corresponding to `['a, I]`, because knowing
/// `'a` and `I` determines the value of `T`. /// `'a` and `I` determines the value of `T`.
fn unconstrained_parent_impl_substs<'tcx>( fn unconstrained_parent_impl_args<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
impl_def_id: DefId, impl_def_id: DefId,
impl_substs: SubstsRef<'tcx>, impl_args: GenericArgsRef<'tcx>,
) -> Vec<GenericArg<'tcx>> { ) -> Vec<GenericArg<'tcx>> {
let impl_generic_predicates = tcx.predicates_of(impl_def_id); let impl_generic_predicates = tcx.predicates_of(impl_def_id);
let mut unconstrained_parameters = FxHashSet::default(); let mut unconstrained_parameters = FxHashSet::default();
let mut constrained_params = FxHashSet::default(); let mut constrained_params = FxHashSet::default();
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).map(ty::EarlyBinder::subst_identity); let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).map(ty::EarlyBinder::instantiate_identity);
// Unfortunately the functions in `constrained_generic_parameters` don't do // Unfortunately the functions in `constrained_generic_parameters` don't do
// what we want here. We want only a list of constrained parameters while // what we want here. We want only a list of constrained parameters while
@ -255,7 +255,7 @@ fn unconstrained_parent_impl_substs<'tcx>(
} }
} }
impl_substs impl_args
.iter() .iter()
.enumerate() .enumerate()
.filter(|&(idx, _)| !constrained_params.contains(&(idx as u32))) .filter(|&(idx, _)| !constrained_params.contains(&(idx as u32)))
@ -264,7 +264,7 @@ fn unconstrained_parent_impl_substs<'tcx>(
} }
/// Check that parameters of the derived impl don't occur more than once in the /// Check that parameters of the derived impl don't occur more than once in the
/// equated substs of the base impl. /// equated args of the base impl.
/// ///
/// For example forbid the following: /// For example forbid the following:
/// ///
@ -280,19 +280,19 @@ fn unconstrained_parent_impl_substs<'tcx>(
/// impl<T> Tr<T> for Vec<T> { } /// impl<T> Tr<T> for Vec<T> { }
/// ``` /// ```
/// ///
/// The substs for the parent impl here are `[T, Vec<T>]`, which repeats `T`, /// The args for the parent impl here are `[T, Vec<T>]`, which repeats `T`,
/// but `S` is constrained in the parent impl, so `parent_substs` is only /// but `S` is constrained in the parent impl, so `parent_args` is only
/// `[Vec<T>]`. This means we allow this impl. /// `[Vec<T>]`. This means we allow this impl.
fn check_duplicate_params<'tcx>( fn check_duplicate_params<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
impl1_substs: SubstsRef<'tcx>, impl1_args: GenericArgsRef<'tcx>,
parent_substs: &Vec<GenericArg<'tcx>>, parent_args: &Vec<GenericArg<'tcx>>,
span: Span, span: Span,
) { ) {
let mut base_params = cgp::parameters_for(parent_substs, true); let mut base_params = cgp::parameters_for(parent_args, true);
base_params.sort_by_key(|param| param.0); base_params.sort_by_key(|param| param.0);
if let (_, [duplicate, ..]) = base_params.partition_dedup() { if let (_, [duplicate, ..]) = base_params.partition_dedup() {
let param = impl1_substs[duplicate.0 as usize]; let param = impl1_args[duplicate.0 as usize];
tcx.sess tcx.sess
.struct_span_err(span, format!("specializing impl repeats parameter `{}`", param)) .struct_span_err(span, format!("specializing impl repeats parameter `{}`", param))
.emit(); .emit();
@ -309,10 +309,10 @@ fn check_duplicate_params<'tcx>(
/// ``` /// ```
fn check_static_lifetimes<'tcx>( fn check_static_lifetimes<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
parent_substs: &Vec<GenericArg<'tcx>>, parent_args: &Vec<GenericArg<'tcx>>,
span: Span, span: Span,
) { ) {
if tcx.any_free_region_meets(parent_substs, |r| r.is_static()) { if tcx.any_free_region_meets(parent_args, |r| r.is_static()) {
tcx.sess.emit_err(errors::StaticSpecialize { span }); tcx.sess.emit_err(errors::StaticSpecialize { span });
} }
} }
@ -331,14 +331,14 @@ fn check_static_lifetimes<'tcx>(
fn check_predicates<'tcx>( fn check_predicates<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
impl1_def_id: LocalDefId, impl1_def_id: LocalDefId,
impl1_substs: SubstsRef<'tcx>, impl1_args: GenericArgsRef<'tcx>,
impl2_node: Node, impl2_node: Node,
impl2_substs: SubstsRef<'tcx>, impl2_args: GenericArgsRef<'tcx>,
span: Span, span: Span,
) { ) {
let impl1_predicates: Vec<_> = traits::elaborate( let impl1_predicates: Vec<_> = traits::elaborate(
tcx, tcx,
tcx.predicates_of(impl1_def_id).instantiate(tcx, impl1_substs).into_iter(), tcx.predicates_of(impl1_def_id).instantiate(tcx, impl1_args).into_iter(),
) )
.collect(); .collect();
@ -350,7 +350,7 @@ fn check_predicates<'tcx>(
traits::elaborate( traits::elaborate(
tcx, tcx,
tcx.predicates_of(impl2_node.def_id()) tcx.predicates_of(impl2_node.def_id())
.instantiate(tcx, impl2_substs) .instantiate(tcx, impl2_args)
.into_iter() .into_iter()
.map(|(c, _s)| c.as_predicate()), .map(|(c, _s)| c.as_predicate()),
) )
@ -385,7 +385,7 @@ fn check_predicates<'tcx>(
.map(|(c, _span)| c.as_predicate()); .map(|(c, _span)| c.as_predicate());
// Include the well-formed predicates of the type parameters of the impl. // Include the well-formed predicates of the type parameters of the impl.
for arg in tcx.impl_trait_ref(impl1_def_id).unwrap().subst_identity().substs { for arg in tcx.impl_trait_ref(impl1_def_id).unwrap().instantiate_identity().args {
let infcx = &tcx.infer_ctxt().build(); let infcx = &tcx.infer_ctxt().build();
let obligations = let obligations =
wf::obligations(infcx, tcx.param_env(impl1_def_id), impl1_def_id, 0, arg, span) wf::obligations(infcx, tcx.param_env(impl1_def_id), impl1_def_id, 0, arg, span)

View File

@ -178,12 +178,12 @@ fn require_same_types<'tcx>(
} }
fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) { fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
let main_fnsig = tcx.fn_sig(main_def_id).subst_identity(); let main_fnsig = tcx.fn_sig(main_def_id).instantiate_identity();
let main_span = tcx.def_span(main_def_id); let main_span = tcx.def_span(main_def_id);
fn main_fn_diagnostics_def_id(tcx: TyCtxt<'_>, def_id: DefId, sp: Span) -> LocalDefId { fn main_fn_diagnostics_def_id(tcx: TyCtxt<'_>, def_id: DefId, sp: Span) -> LocalDefId {
if let Some(local_def_id) = def_id.as_local() { if let Some(local_def_id) = def_id.as_local() {
let hir_type = tcx.type_of(local_def_id).subst_identity(); let hir_type = tcx.type_of(local_def_id).instantiate_identity();
if !matches!(hir_type.kind(), ty::FnDef(..)) { if !matches!(hir_type.kind(), ty::FnDef(..)) {
span_bug!(sp, "main has a non-function type: found `{}`", hir_type); span_bug!(sp, "main has a non-function type: found `{}`", hir_type);
} }
@ -350,7 +350,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
let start_def_id = start_def_id.expect_local(); 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_id = tcx.hir().local_def_id_to_hir_id(start_def_id);
let start_span = tcx.def_span(start_def_id); let start_span = tcx.def_span(start_def_id);
let start_t = tcx.type_of(start_def_id).subst_identity(); let start_t = tcx.type_of(start_def_id).instantiate_identity();
match start_t.kind() { match start_t.kind() {
ty::FnDef(..) => { ty::FnDef(..) => {
if let Some(Node::Item(it)) = tcx.hir().find(start_id) { if let Some(Node::Item(it)) = tcx.hir().find(start_id) {
@ -421,7 +421,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
), ),
ty::ParamEnv::empty(), // start should not have any where bounds. ty::ParamEnv::empty(), // start should not have any where bounds.
se_ty, se_ty,
Ty::new_fn_ptr(tcx, tcx.fn_sig(start_def_id).subst_identity()), Ty::new_fn_ptr(tcx, tcx.fn_sig(start_def_id).instantiate_identity()),
); );
} }
_ => { _ => {

View File

@ -46,7 +46,7 @@ pub(super) fn infer_predicates(
// For field of type &'a T (reference) or Adt // For field of type &'a T (reference) or Adt
// (struct/enum/union) there will be outlive // (struct/enum/union) there will be outlive
// requirements for adt_def. // requirements for adt_def.
let field_ty = tcx.type_of(field_def.did).subst_identity(); let field_ty = tcx.type_of(field_def.did).instantiate_identity();
let field_span = tcx.def_span(field_def.did); let field_span = tcx.def_span(field_def.did);
insert_required_predicates_to_be_wf( insert_required_predicates_to_be_wf(
tcx, tcx,
@ -117,7 +117,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
// can load the current set of inferred and explicit // can load the current set of inferred and explicit
// predicates from `global_inferred_outlives` and filter the // predicates from `global_inferred_outlives` and filter the
// ones that are TypeOutlives. // ones that are TypeOutlives.
ty::Adt(def, substs) => { ty::Adt(def, args) => {
// First check the inferred predicates // First check the inferred predicates
// //
// Example 1: // Example 1:
@ -146,7 +146,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
// get `T: 'a` (or `predicate`): // get `T: 'a` (or `predicate`):
let predicate = unsubstituted_predicates let predicate = unsubstituted_predicates
.rebind(*unsubstituted_predicate) .rebind(*unsubstituted_predicate)
.subst(tcx, substs); .instantiate(tcx, args);
insert_outlives_predicate( insert_outlives_predicate(
tcx, tcx,
predicate.0, predicate.0,
@ -159,11 +159,11 @@ fn insert_required_predicates_to_be_wf<'tcx>(
// Check if the type has any explicit predicates that need // Check if the type has any explicit predicates that need
// to be added to `required_predicates` // to be added to `required_predicates`
// let _: () = substs.region_at(0); // let _: () = args.region_at(0);
check_explicit_predicates( check_explicit_predicates(
tcx, tcx,
def.did(), def.did(),
substs, args,
required_predicates, required_predicates,
explicit_map, explicit_map,
None, None,
@ -186,12 +186,11 @@ fn insert_required_predicates_to_be_wf<'tcx>(
// predicates in `check_explicit_predicates` we // predicates in `check_explicit_predicates` we
// need to ignore checking the explicit_map for // need to ignore checking the explicit_map for
// Self type. // Self type.
let substs = let args = ex_trait_ref.with_self_ty(tcx, tcx.types.usize).skip_binder().args;
ex_trait_ref.with_self_ty(tcx, tcx.types.usize).skip_binder().substs;
check_explicit_predicates( check_explicit_predicates(
tcx, tcx,
ex_trait_ref.skip_binder().def_id, ex_trait_ref.skip_binder().def_id,
substs, args,
required_predicates, required_predicates,
explicit_map, explicit_map,
Some(tcx.types.self_param), Some(tcx.types.self_param),
@ -206,7 +205,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
check_explicit_predicates( check_explicit_predicates(
tcx, tcx,
tcx.parent(obj.def_id), tcx.parent(obj.def_id),
obj.substs, obj.args,
required_predicates, required_predicates,
explicit_map, explicit_map,
None, None,
@ -239,18 +238,18 @@ fn insert_required_predicates_to_be_wf<'tcx>(
fn check_explicit_predicates<'tcx>( fn check_explicit_predicates<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
def_id: DefId, def_id: DefId,
substs: &[GenericArg<'tcx>], args: &[GenericArg<'tcx>],
required_predicates: &mut RequiredPredicates<'tcx>, required_predicates: &mut RequiredPredicates<'tcx>,
explicit_map: &mut ExplicitPredicatesMap<'tcx>, explicit_map: &mut ExplicitPredicatesMap<'tcx>,
ignored_self_ty: Option<Ty<'tcx>>, ignored_self_ty: Option<Ty<'tcx>>,
) { ) {
debug!( debug!(
"check_explicit_predicates(def_id={:?}, \ "check_explicit_predicates(def_id={:?}, \
substs={:?}, \ args={:?}, \
explicit_map={:?}, \ explicit_map={:?}, \
required_predicates={:?}, \ required_predicates={:?}, \
ignored_self_ty={:?})", ignored_self_ty={:?})",
def_id, substs, explicit_map, required_predicates, ignored_self_ty, def_id, args, explicit_map, required_predicates, ignored_self_ty,
); );
let explicit_predicates = explicit_map.explicit_predicates_of(tcx, def_id); let explicit_predicates = explicit_map.explicit_predicates_of(tcx, def_id);
@ -278,10 +277,10 @@ fn check_explicit_predicates<'tcx>(
// that is represented by the `dyn Trait`, not to the `X` type parameter // that is represented by the `dyn Trait`, not to the `X` type parameter
// (or any other generic parameter) declared on `MyStruct`. // (or any other generic parameter) declared on `MyStruct`.
// //
// Note that we do this check for self **before** applying `substs`. In the // Note that we do this check for self **before** applying `args`. In the
// case that `substs` come from a `dyn Trait` type, our caller will have // case that `args` come from a `dyn Trait` type, our caller will have
// included `Self = usize` as the value for `Self`. If we were // included `Self = usize` as the value for `Self`. If we were
// to apply the substs, and not filter this predicate, we might then falsely // to apply the args, and not filter this predicate, we might then falsely
// conclude that e.g., `X: 'x` was a reasonable inferred requirement. // conclude that e.g., `X: 'x` was a reasonable inferred requirement.
// //
// Another similar case is where we have an inferred // Another similar case is where we have an inferred
@ -299,7 +298,7 @@ fn check_explicit_predicates<'tcx>(
continue; continue;
} }
let predicate = explicit_predicates.rebind(*outlives_predicate).subst(tcx, substs); let predicate = explicit_predicates.rebind(*outlives_predicate).instantiate(tcx, args);
debug!("predicate = {:?}", &predicate); debug!("predicate = {:?}", &predicate);
insert_outlives_predicate(tcx, predicate.0, predicate.1, span, required_predicates); insert_outlives_predicate(tcx, predicate.0, predicate.1, span, required_predicates);
} }

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