1
Fork 0

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

@ -20,8 +20,8 @@ use rustc_middle::hir::nested_filter;
use rustc_middle::middle::stability::EvalResult;
use rustc_middle::traits::DefiningAnchor;
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::GenericArgKind;
use rustc_middle::ty::{
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.
fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool {
let item_type = tcx.type_of(item_def_id).subst_identity();
if let ty::Adt(def, substs) = item_type.kind() {
let item_type = tcx.type_of(item_def_id).instantiate_identity();
if let ty::Adt(def, args) = item_type.kind() {
assert!(def.is_union());
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);
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) {
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
// have UB during initialization if they are uninhabited, but there also seems to be no good
// reason to allow any statics to be uninhabited.
let ty = tcx.type_of(def_id).subst_identity();
let ty = tcx.type_of(def_id).instantiate_identity();
let span = tcx.def_span(def_id);
let layout = match tcx.layout_of(ParamEnv::reveal_all().and(ty)) {
Ok(l) => l,
@ -212,16 +212,16 @@ fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) {
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);
if !tcx.features().impl_trait_projections {
check_opaque_for_inheriting_lifetimes(tcx, item.owner_id.def_id, span);
}
if tcx.type_of(item.owner_id.def_id).subst_identity().references_error() {
if tcx.type_of(item.owner_id.def_id).instantiate_identity().references_error() {
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;
}
@ -305,8 +305,8 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
..
}) = item.kind
{
let substs = InternalSubsts::identity_for_item(tcx, def_id);
let opaque_identity_ty = Ty::new_opaque(tcx, def_id.to_def_id(), substs);
let args = GenericArgs::identity_for_item(tcx, def_id);
let opaque_identity_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
let mut visitor = ProhibitOpaqueVisitor {
opaque_identity_ty,
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
.explicit_item_bounds(def_id)
.subst_identity_iter_copied()
.instantiate_identity_iter_copied()
.try_for_each(|(predicate, _)| predicate.visit_with(&mut visitor));
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>(
tcx: TyCtxt<'tcx>,
def_id: LocalDefId,
substs: SubstsRef<'tcx>,
args: GenericArgsRef<'tcx>,
span: Span,
origin: &hir::OpaqueTyOrigin,
) -> 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 {
hir::OpaqueTyOrigin::AsyncFn(..) => async_opaque_type_cycle_error(tcx, span),
_ => opaque_type_cycle_error(tcx, def_id, span),
@ -404,16 +404,16 @@ fn check_opaque_meets_bounds<'tcx>(
.build();
let ocx = ObligationCtxt::new(&infcx);
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), substs);
let args = GenericArgs::identity_for_item(tcx, def_id.to_def_id());
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.
// 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
// 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() {
ty::ReErased => infcx.next_region_var(RegionVariableOrigin::MiscVariable(span)),
_ => re,
@ -472,7 +472,7 @@ fn check_opaque_meets_bounds<'tcx>(
fn is_enum_of_nonnullable_ptr<'tcx>(
tcx: TyCtxt<'tcx>,
adt_def: AdtDef<'tcx>,
substs: SubstsRef<'tcx>,
args: GenericArgsRef<'tcx>,
) -> bool {
if adt_def.repr().inhibit_enum_layout_opt() {
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 {
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) {
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::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,
} {
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(
tcx,
id.owner_id.def_id,
impl_trait_ref.subst_identity(),
impl_trait_ref.instantiate_identity(),
);
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);
}
ty::AssocKind::Type if assoc_item.defaultness(tcx).has_value() => {
let trait_substs =
InternalSubsts::identity_for_item(tcx, id.owner_id);
let trait_args =
GenericArgs::identity_for_item(tcx, id.owner_id);
let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds(
tcx,
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 => {
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);
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) {
let t = tcx.type_of(def_id).subst_identity();
if let ty::Adt(def, substs) = t.kind()
let t = tcx.type_of(def_id).instantiate_identity();
if let ty::Adt(def, args) = t.kind()
&& def.is_struct()
{
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();
return;
}
let e = fields[FieldIdx::from_u32(0)].ty(tcx, substs);
if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
let e = fields[FieldIdx::from_u32(0)].ty(tcx, args);
if !fields.iter().all(|f| f.ty(tcx, args) == e) {
struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
.span_label(sp, "SIMD elements must have the same type")
.emit();
@ -1003,7 +1003,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) {
if first {
format!(
"`{}` contains a field of type `{}`",
tcx.type_of(def.did()).subst_identity(),
tcx.type_of(def.did()).instantiate_identity(),
ident
)
} else {
@ -1025,7 +1025,7 @@ pub(super) fn check_packed_inner(
def_id: DefId,
stack: &mut Vec<DefId>,
) -> Option<Vec<(DefId, Span)>> {
if let ty::Adt(def, substs) = tcx.type_of(def_id).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.repr().align.is_some() {
return Some(vec![(def.did(), DUMMY_SP)]);
@ -1033,7 +1033,7 @@ pub(super) fn check_packed_inner(
stack.push(def_id);
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())
&& 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"
// respecting #[non_exhaustive] attributes.
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 layout = tcx.layout_of(param_env.and(ty));
// 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>(
tcx: TyCtxt<'tcx>,
t: Ty<'tcx>,
) -> ControlFlow<(&'static str, DefId, SubstsRef<'tcx>, bool)> {
) -> ControlFlow<(&'static str, DefId, GenericArgsRef<'tcx>, bool)> {
match t.kind() {
ty::Tuple(list) => list.iter().try_for_each(|t| check_non_exhaustive(tcx, t)),
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")
.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(
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS,
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 {
"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
.note(format!("this {descr} contains `{field_ty}`, which {note}, \
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::util::ExplicitSelf;
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_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
/// 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
/// impl trait reference:
///
/// ```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,
/// this is the identity transform, but we could as well use any
/// 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).
///
/// ```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
/// types:
///
@ -125,13 +125,13 @@ fn check_method_is_structurally_compatible<'tcx>(
///
/// We now want to extract and substitute the type of the *trait*
/// method and compare it. To do so, we must create a compound
/// substitution by combining `trait_to_impl_substs` and
/// `impl_to_placeholder_substs`, and also adding a mapping for the method
/// substitution by combining `trait_to_impl_args` and
/// `impl_to_placeholder_args`, and also adding a mapping for the method
/// type parameters. We extend the mapping to also include
/// the method parameters.
///
/// ```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:
@ -148,8 +148,8 @@ fn check_method_is_structurally_compatible<'tcx>(
/// satisfied by the implementation's method.
///
/// We do this by creating a parameter environment which contains a
/// substitution corresponding to `impl_to_placeholder_substs`. We then build
/// `trait_to_placeholder_substs` and use it to convert the predicates contained
/// substitution corresponding to `impl_to_placeholder_args`. We then build
/// `trait_to_placeholder_args` and use it to convert the predicates contained
/// in the `trait_m` generics to the placeholder form.
///
/// 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>,
check_implied_wf: CheckImpliedWfMode,
) -> 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
// `ObligationCause` (and the `FnCtxt`).
@ -182,12 +182,12 @@ fn compare_method_predicate_entailment<'tcx>(
);
// 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.
let trait_to_placeholder_substs =
impl_to_placeholder_substs.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_substs);
debug!("compare_impl_method: trait_to_placeholder_substs={:?}", trait_to_placeholder_substs);
let trait_to_placeholder_args =
impl_to_placeholder_args.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_args);
debug!("compare_impl_method: trait_to_placeholder_args={:?}", trait_to_placeholder_args);
let impl_m_predicates = tcx.predicates_of(impl_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.
hybrid_preds.predicates.extend(
trait_m_predicates
.instantiate_own(tcx, trait_to_placeholder_substs)
.instantiate_own(tcx, trait_to_placeholder_args)
.map(|(predicate, _)| predicate),
);
@ -231,7 +231,7 @@ fn compare_method_predicate_entailment<'tcx>(
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 {
let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id);
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(
impl_m_span,
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));
@ -277,7 +277,7 @@ fn compare_method_predicate_entailment<'tcx>(
let impl_sig = ocx.normalize(&norm_cause, param_env, unnormalized_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);
// 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 trait_m = tcx.opt_associated_item(impl_m.trait_item_def_id.unwrap()).unwrap();
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);
// First, check a few of the same things as `compare_impl_method`,
// just so we don't ICE during substitution later.
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 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.
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.
let trait_to_placeholder_substs =
impl_to_placeholder_substs.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_substs);
let trait_to_placeholder_args =
impl_to_placeholder_args.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_args);
let infcx = &tcx.infer_ctxt().build();
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(
&norm_cause,
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()?;
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(
return_span,
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);
@ -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)?;
let mut collected_tys = FxHashMap::default();
for (def_id, (ty, substs)) in collected_types {
match infcx.fully_resolve((ty, substs)) {
Ok((ty, substs)) => {
for (def_id, (ty, args)) in collected_types {
match infcx.fully_resolve((ty, args)) {
Ok((ty, args)) => {
// `ty` contains free regions that we created earlier while liberating the
// trait fn signature. However, projection normalization expects `ty` to
// contains `def_id`'s early-bound regions.
let id_substs = InternalSubsts::identity_for_item(tcx, def_id);
debug!(?id_substs, ?substs);
let map: FxHashMap<_, _> = std::iter::zip(substs, id_substs)
let id_args = GenericArgs::identity_for_item(tcx, def_id);
debug!(?id_args, ?args);
let map: FxHashMap<_, _> = std::iter::zip(args, id_args)
.skip(tcx.generics_of(trait_m.def_id).count())
.filter_map(|(a, b)| Some((a.as_region()?, b.as_region()?)))
.collect();
debug!(?map);
// NOTE(compiler-errors): RPITITs, like all other RPITs, have early-bound
// region substs that are synthesized during AST lowering. These are substs
// that are appended to the parent substs (trait and trait method). However,
// region args that are synthesized during AST lowering. These are args
// 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
// 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`).
//
// 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,
// 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
// (trait method) early-bound region substs onto the impl, and there's no
// guarantee that the indices from the trait substs and impl substs line up.
// So to fix this, we subtract the number of trait substs and add the number of
// impl substs to *renumber* these early-bound regions to their corresponding
// (trait method) early-bound region args onto the impl, and there's no
// guarantee that the indices from the trait args and impl args line up.
// So to fix this, we subtract the number of trait args and add the number of
// impl args to *renumber* these early-bound regions to their corresponding
// 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
// same generics.
let num_trait_substs = trait_to_impl_substs.len();
let num_impl_substs = tcx.generics_of(impl_m.container_id(tcx)).params.len();
let num_trait_args = trait_to_impl_args.len();
let num_impl_args = tcx.generics_of(impl_m.container_id(tcx)).params.len();
let ty = match ty.try_fold_with(&mut RemapHiddenTyRegions {
tcx,
map,
num_trait_substs,
num_impl_substs,
num_trait_args,
num_impl_args,
def_id,
impl_def_id: impl_m.container_id(tcx),
ty,
@ -824,7 +827,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
struct ImplTraitInTraitCollector<'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,
param_env: ty::ParamEnv<'tcx>,
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) {
return *ty;
}
//FIXME(RPITIT): Deny nested RPITIT in substs too
if proj.substs.has_escaping_bound_vars() {
//FIXME(RPITIT): Deny nested RPITIT in args too
if proj.args.has_escaping_bound_vars() {
bug!("FIXME(RPITIT): error here");
}
// Replace with infer var
@ -862,9 +865,9 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> {
span: self.span,
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
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 = self.ocx.normalize(
&ObligationCause::misc(self.span, self.body_id),
@ -893,8 +896,8 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> {
struct RemapHiddenTyRegions<'tcx> {
tcx: TyCtxt<'tcx>,
map: FxHashMap<ty::Region<'tcx>, ty::Region<'tcx>>,
num_trait_substs: usize,
num_impl_substs: usize,
num_trait_args: usize,
num_impl_args: usize,
def_id: DefId,
impl_def_id: DefId,
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> {
if let ty::Alias(ty::Opaque, ty::AliasTy { substs, def_id, .. }) = *t.kind() {
let mut mapped_substs = Vec::with_capacity(substs.len());
for (arg, v) in std::iter::zip(substs, self.tcx.variances_of(def_id)) {
mapped_substs.push(match (arg.unpack(), v) {
// Skip uncaptured opaque substs
if let ty::Alias(ty::Opaque, ty::AliasTy { args, def_id, .. }) = *t.kind() {
let mut mapped_args = Vec::with_capacity(args.len());
for (arg, v) in std::iter::zip(args, self.tcx.variances_of(def_id)) {
mapped_args.push(match (arg.unpack(), v) {
// Skip uncaptured opaque args
(ty::GenericArgKind::Lifetime(_), ty::Bivariant) => arg,
_ => 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 {
t.try_super_fold_with(self)
}
@ -975,7 +978,7 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
ty::EarlyBoundRegion {
def_id: e.def_id,
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::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 infcx = tcx.infer_ctxt().build();
@ -1738,7 +1741,7 @@ fn compare_generic_param_kinds<'tcx>(
format!(
"{} const parameter of type `{}`",
prefix,
tcx.type_of(param.def_id).subst_identity()
tcx.type_of(param.def_id).instantiate_identity()
)
}
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 trait_const_item = tcx.associated_item(trait_const_item_def);
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);
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
// predicates. In fact some of this should probably be put into
// 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
// method.
// 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 trait_ty = tcx.type_of(trait_const_item_def).subst(tcx, trait_to_impl_substs);
let impl_ty = tcx.type_of(impl_const_item_def.to_def_id()).instantiate_identity();
let trait_ty = tcx.type_of(trait_const_item_def).instantiate(tcx, trait_to_impl_args);
let mut cause = ObligationCause::new(
impl_c_span,
impl_const_item_def,
@ -1885,16 +1888,16 @@ fn compare_type_predicate_entailment<'tcx>(
trait_ty: ty::AssocItem,
impl_trait_ref: ty::TraitRef<'tcx>,
) -> Result<(), ErrorGuaranteed> {
let impl_substs = InternalSubsts::identity_for_item(tcx, impl_ty.def_id);
let trait_to_impl_substs =
impl_substs.rebase_onto(tcx, impl_ty.container_id(tcx), impl_trait_ref.substs);
let impl_args = GenericArgs::identity_for_item(tcx, impl_ty.def_id);
let trait_to_impl_args =
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 trait_ty_predicates = tcx.predicates_of(trait_ty.def_id);
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 {
// Nothing to check.
return Ok(());
@ -1904,7 +1907,7 @@ fn compare_type_predicate_entailment<'tcx>(
// `ObligationCause` (and the `FnCtxt`). This is what
// `regionck_item` expects.
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
// 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);
hybrid_preds.predicates.extend(
trait_ty_predicates
.instantiate_own(tcx, trait_to_impl_substs)
.instantiate_own(tcx, trait_to_impl_args)
.map(|(predicate, _)| predicate),
);
@ -1990,9 +1993,9 @@ pub(super) fn check_type_bounds<'tcx>(
// }
//
// - `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>`
// - `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).
//
// 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).
let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> =
smallvec::SmallVec::with_capacity(tcx.generics_of(impl_ty.def_id).params.len());
// Extend the impl's identity substs with late-bound GAT vars
let normalize_impl_ty_substs = ty::InternalSubsts::identity_for_item(tcx, container_id)
.extend_to(tcx, impl_ty.def_id, |param, _| match param.kind {
// Extend the impl's identity args with late-bound GAT vars
let normalize_impl_ty_args = ty::GenericArgs::identity_for_item(tcx, container_id).extend_to(
tcx,
impl_ty.def_id,
|param, _| match param.kind {
GenericParamDefKind::Type { .. } => {
let kind = ty::BoundTyKind::Param(param.def_id, param.name);
let bound_var = ty::BoundVariableKind::Ty(kind);
@ -2060,7 +2065,8 @@ pub(super) fn check_type_bounds<'tcx>(
)
.into()
}
});
},
);
// When checking something like
//
// 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
// checking the default value specifically here. Add this equality to the
// ParamEnv for normalization specifically.
let normalize_impl_ty = tcx.type_of(impl_ty.def_id).subst(tcx, normalize_impl_ty_substs);
let rebased_substs =
normalize_impl_ty_substs.rebase_onto(tcx, container_id, impl_trait_ref.substs);
let normalize_impl_ty = tcx.type_of(impl_ty.def_id).instantiate(tcx, normalize_impl_ty_args);
let rebased_args = normalize_impl_ty_args.rebase_onto(tcx, container_id, impl_trait_ref.args);
let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars);
let normalize_param_env = {
let mut predicates = param_env.caller_bounds().iter().collect::<Vec<_>>();
match normalize_impl_ty.kind() {
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
// exactly the same as the projection. This can occur in
@ -2089,7 +2094,7 @@ pub(super) fn check_type_bounds<'tcx>(
_ => predicates.push(
ty::Binder::bind_with_vars(
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(),
},
bound_vars,
@ -2102,8 +2107,8 @@ pub(super) fn check_type_bounds<'tcx>(
debug!(?normalize_param_env);
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 rebased_substs = impl_ty_substs.rebase_onto(tcx, container_id, impl_trait_ref.substs);
let impl_ty_args = GenericArgs::identity_for_item(tcx, impl_ty.def_id);
let rebased_args = impl_ty_args.rebase_onto(tcx, container_id, impl_trait_ref.args);
let infcx = tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx);
@ -2144,7 +2149,7 @@ pub(super) fn check_type_bounds<'tcx>(
let obligations: Vec<_> = tcx
.explicit_item_bounds(trait_ty.def_id)
.subst_iter_copied(tcx, rebased_substs)
.arg_iter_copied(tcx, rebased_args)
.map(|(concrete_ty_bound, span)| {
debug!("check_type_bounds: concrete_ty_bound = {:?}", 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_infer::infer::outlives::env::OutlivesEnvironment;
use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt};
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::util::CheckRegions;
use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{self, TyCtxt};
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() {
ty::Adt(adt_def, adt_to_impl_substs) => {
ty::Adt(adt_def, adt_to_impl_args) => {
ensure_drop_params_and_item_params_correspond(
tcx,
drop_impl_did.expect_local(),
adt_def.did(),
adt_to_impl_substs,
adt_to_impl_args,
)?;
ensure_drop_predicates_are_implied_by_item_defn(
tcx,
drop_impl_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>,
drop_impl_did: LocalDefId,
self_type_did: DefId,
adt_to_impl_substs: SubstsRef<'tcx>,
adt_to_impl_args: GenericArgsRef<'tcx>,
) -> 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 {
return Ok(());
};
@ -115,12 +115,12 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
tcx: TyCtxt<'tcx>,
drop_impl_def_id: LocalDefId,
adt_def_id: LocalDefId,
adt_to_impl_substs: SubstsRef<'tcx>,
adt_to_impl_args: GenericArgsRef<'tcx>,
) -> Result<(), ErrorGuaranteed> {
let infcx = tcx.infer_ctxt().build();
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
// 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
@ -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
// 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))
.subst(tcx, adt_to_impl_substs)
.instantiate(tcx, adt_to_impl_args)
.with_constness(tcx.constness(drop_impl_def_id));
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,
&cause,
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,
);
}
@ -155,7 +155,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
ty::INNERMOST,
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)
})
};
@ -238,7 +238,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
ty: Ty::new_adt(
tcx,
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,
},
@ -412,7 +412,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
ty::Region::new_late_bound(tcx, ty::INNERMOST, br),
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) => {
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 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() {
ty::Array(ty, len) => {
@ -423,7 +423,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
// Check that sym actually points to a function. Later passes
// depend on this.
hir::InlineAsmOperand::SymFn { anon_const } => {
let ty = self.tcx.type_of(anon_const.def_id).subst_identity();
let ty = self.tcx.type_of(anon_const.def_id).instantiate_identity();
match ty.kind() {
ty::Never | ty::Error(_) => {}
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
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
complete, the functions in the writeback module are used to take the
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_middle::query::Providers;
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_span::source_map::DUMMY_SP;
use rustc_span::symbol::{kw, Ident};
@ -211,7 +211,7 @@ fn missing_items_err(
let snippet = suggestion_signature(
tcx,
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);
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() {
output = if let ty::Alias(_, alias_ty) = *output.kind() {
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())
.unwrap_or_else(|| {
span_bug!(
@ -461,10 +461,10 @@ fn suggestion_signature<'tcx>(
assoc: ty::AssocItem,
impl_trait_ref: ty::TraitRef<'tcx>,
) -> 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,
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 {
@ -472,21 +472,21 @@ fn suggestion_signature<'tcx>(
tcx,
tcx.liberate_late_bound_regions(
assoc.def_id,
tcx.fn_sig(assoc.def_id).subst(tcx, substs),
tcx.fn_sig(assoc.def_id).instantiate(tcx, args),
),
assoc.ident(tcx),
tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs),
tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args),
assoc,
),
ty::AssocKind::Type => {
let (generics, where_clauses) = bounds_from_generic_predicates(
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)
}
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!()");
format!("const {}: {} = {};", assoc.name, ty, val)
}

View file

@ -18,7 +18,7 @@ use rustc_middle::ty::{
self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
TypeVisitable, TypeVisitableExt, TypeVisitor,
};
use rustc_middle::ty::{GenericArgKind, InternalSubsts};
use rustc_middle::ty::{GenericArgKind, GenericArgs};
use rustc_session::parse::feature_err;
use rustc_span::symbol::{sym, Ident, Symbol};
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
/// 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:
/// ```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 {
let gat_def_id = gat_item.id.owner_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 {
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.
let sig: ty::FnSig<'_> = tcx.liberate_late_bound_regions(
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(
tcx,
@ -374,7 +374,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
param_env,
item_def_id,
tcx.explicit_item_bounds(item_def_id)
.subst_identity_iter_copied()
.instantiate_identity_iter_copied()
.collect::<Vec<_>>(),
&FxIndexSet::default(),
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> {
match t.kind() {
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() {
GenericArgKind::Lifetime(lt) if !lt.is_late_bound() => {
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.
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 {
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 {
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 {
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);
wfcx.register_wf_obligation(span, loc, ty.into());
}
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");
check_fn_or_method(
wfcx,
@ -936,7 +936,7 @@ fn check_associated_item(
check_associated_type_bounds(wfcx, item, span)
}
if item.defaultness(tcx).has_value() {
let ty = tcx.type_of(item.def_id).subst_identity();
let ty = tcx.type_of(item.def_id).instantiate_identity();
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
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 hir::FieldDef { ty: hir_ty, .. } =
tcx.hir().get_by_def_id(field_id).expect_field();
let ty = wfcx.normalize(hir_ty.span, None, tcx.type_of(field.did).subst_identity());
let ty = wfcx.normalize(
hir_ty.span,
None,
tcx.type_of(field.did).instantiate_identity(),
);
wfcx.register_wf_obligation(
hir_ty.span,
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.
let needs_drop_copy = || {
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);
if ty.has_infer() {
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 hir::FieldDef { ty: hir_ty, .. } =
tcx.hir().get_by_def_id(field_id).expect_field();
let ty = wfcx.normalize(hir_ty.span, None, tcx.type_of(field.did).subst_identity());
let ty = wfcx.normalize(
hir_ty.span,
None,
tcx.type_of(field.did).instantiate_identity(),
);
wfcx.register_bound(
traits::ObligationCause::new(
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);
debug!("check_associated_type_bounds: bounds={:?}", bounds);
let wf_obligations = bounds.subst_identity_iter_copied().flat_map(|(bound, bound_span)| {
let normalized_bound = wfcx.normalize(span, None, bound);
traits::wf::predicate_obligations(
wfcx.infcx,
wfcx.param_env,
wfcx.body_def_id,
normalized_bound.as_predicate(),
bound_span,
)
});
let wf_obligations =
bounds.instantiate_identity_iter_copied().flat_map(|(bound, bound_span)| {
let normalized_bound = wfcx.normalize(span, None, bound);
traits::wf::predicate_obligations(
wfcx.infcx,
wfcx.param_env,
wfcx.body_def_id,
normalized_bound.as_predicate(),
bound_span,
)
});
wfcx.register_obligations(wf_obligations);
}
@ -1105,7 +1114,7 @@ fn check_item_fn(
decl: &hir::FnDecl<'_>,
) {
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);
})
}
@ -1125,7 +1134,7 @@ fn check_item_type(
debug!("check_item_type: {:?}", item_id);
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 forbid_unsized = match unsized_handling {
@ -1178,7 +1187,7 @@ fn check_impl<'tcx>(
// `#[rustc_reservation_impl]` impls are not real impls and
// therefore don't need to be WF (the trait's `Self: Trait` predicate
// 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(
ast_trait_ref.path.span,
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
@ -1211,7 +1220,7 @@ fn check_impl<'tcx>(
wfcx.register_obligations(obligations);
}
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(
item.span,
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 {
GenericParamDefKind::Type { .. } => {
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
// 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.
@ -1272,10 +1281,10 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
GenericParamDefKind::Const { .. } => {
if is_our_default(param) {
// 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 }>`
// 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() {
wfcx.register_wf_obligation(
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`.
//
// 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 {
GenericParamDefKind::Lifetime => {
// All regions are identity.
@ -1308,7 +1317,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
GenericParamDefKind::Type { .. } => {
// If the param has a default, ...
if is_our_default(param) {
let default_ty = tcx.type_of(param.def_id).subst_identity();
let default_ty = tcx.type_of(param.def_id).instantiate_identity();
// ... and it's not a dependent default, ...
if !default_ty.has_param() {
// ... then substitute it with the default.
@ -1321,7 +1330,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
GenericParamDefKind::Const { .. } => {
// If the param has a default, ...
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, ...
if !default_ct.has_param() {
// ... 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 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)
// or preds with multiple params.
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,
// 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
// 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
// deep into this, though.
struct ImplTraitInTraitFinder<'a, 'tcx> {
@ -1558,7 +1567,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
});
for (bound, bound_span) in tcx
.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);
self.wfcx.register_obligations(traits::wf::predicate_obligations(
@ -1569,7 +1578,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
bound_span,
));
// 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`,
// but that function doesn't actually need to normalize the bound it's visiting
// (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 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 = wfcx.normalize(span, None, sig);
@ -1773,9 +1782,9 @@ fn check_variances_for_type_defn<'tcx>(
item: &hir::Item<'tcx>,
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() {
if field.ty(tcx, identity_substs).references_error() {
if field.ty(tcx, identity_args).references_error() {
return;
}
}