refactor(rustc_middle): Substs -> GenericArg
This commit is contained in:
parent
df5c2cf9bc
commit
e55583c4b8
466 changed files with 4574 additions and 4604 deletions
|
@ -341,8 +341,8 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||
// If we have an method return type bound, then we need to substitute
|
||||
// the method's early bound params with suitable late-bound params.
|
||||
let mut num_bound_vars = candidate.bound_vars().len();
|
||||
let substs =
|
||||
candidate.skip_binder().substs.extend_to(tcx, assoc_item.def_id, |param, _| {
|
||||
let args =
|
||||
candidate.skip_binder().args.extend_to(tcx, assoc_item.def_id, |param, _| {
|
||||
let subst = match param.kind {
|
||||
ty::GenericParamDefKind::Lifetime => ty::Region::new_late_bound(
|
||||
tcx,
|
||||
|
@ -422,7 +422,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||
// params (and trait ref's late bound params). This logic is very similar to
|
||||
// `Predicate::subst_supertrait`, and it's no coincidence why.
|
||||
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);
|
||||
ty::Binder::bind_with_vars(subst_output, bound_vars)
|
||||
|
@ -438,16 +438,16 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||
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,
|
||||
assoc_item.def_id,
|
||||
&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,
|
||||
reported,
|
||||
tcx.type_of(assoc_item_def_id)
|
||||
.subst(tcx, projection_ty.skip_binder().substs),
|
||||
.instantiate(tcx, projection_ty.skip_binder().args),
|
||||
)
|
||||
.into(),
|
||||
_ => unreachable!(),
|
||||
|
|
|
@ -247,7 +247,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
"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}`");
|
||||
|
||||
if let Some(span) = note_span {
|
||||
|
@ -295,7 +295,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
let type_candidates = candidates
|
||||
.iter()
|
||||
.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<_>>()
|
||||
.join("\n");
|
||||
let additional_types = if candidates.len() > limit {
|
||||
|
@ -356,13 +358,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
// `<Foo as Iterator>::Item = String`.
|
||||
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())
|
||||
.chain(projection_ty.substs.iter().skip(1)),
|
||||
.chain(projection_ty.args.iter().skip(1)),
|
||||
);
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ use rustc_hir::def::{DefKind, Res};
|
|||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::GenericArg;
|
||||
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_span::{symbol::kw, Span};
|
||||
|
@ -76,7 +76,7 @@ fn generic_arg_mismatch_err(
|
|||
Res::Def(DefKind::TyParam, src_def_id) => {
|
||||
if let Some(param_local_id) = param.def_id.as_local() {
|
||||
let param_name = tcx.hir().ty_param_name(param_local_id);
|
||||
let param_type = tcx.type_of(param.def_id).subst_identity();
|
||||
let param_type = tcx.type_of(param.def_id).instantiate_identity();
|
||||
if param_type.is_suggestable(tcx, false) {
|
||||
err.span_suggestion(
|
||||
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
|
||||
/// 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
|
||||
/// that item -- e.g., for a method it might include the
|
||||
/// parameters from the impl.
|
||||
///
|
||||
/// Therefore, the method begins by walking down these parents,
|
||||
/// 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,
|
||||
/// we can append those and move on. Otherwise, it invokes the
|
||||
/// three callback functions:
|
||||
|
@ -168,15 +168,15 @@ fn generic_arg_mismatch_err(
|
|||
/// instantiate a `GenericArg`.
|
||||
/// - `inferred_kind`: if no parameter was provided, and inference is enabled, then
|
||||
/// 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>,
|
||||
def_id: DefId,
|
||||
parent_substs: &[subst::GenericArg<'tcx>],
|
||||
parent_args: &[ty::GenericArg<'tcx>],
|
||||
has_self: bool,
|
||||
self_ty: Option<Ty<'tcx>>,
|
||||
arg_count: &GenericArgCountResult,
|
||||
ctx: &mut impl CreateSubstsForGenericArgsCtxt<'a, 'tcx>,
|
||||
) -> SubstsRef<'tcx> {
|
||||
) -> GenericArgsRef<'tcx> {
|
||||
// Collect the segments of the path; we need to substitute arguments
|
||||
// for parameters throughout the entire path (wherever there are
|
||||
// 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
|
||||
// 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.
|
||||
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.
|
||||
while let Some((def_id, defs)) = stack.pop() {
|
||||
let mut params = defs.params.iter().peekable();
|
||||
|
||||
// If we have already computed substitutions for parents, we can use those directly.
|
||||
while let Some(¶m) = params.peek() {
|
||||
if let Some(&kind) = parent_substs.get(param.index as usize) {
|
||||
substs.push(kind);
|
||||
if let Some(&kind) = parent_args.get(param.index as usize) {
|
||||
args.push(kind);
|
||||
params.next();
|
||||
} else {
|
||||
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 let Some(¶m) = params.peek() {
|
||||
if param.index == 0 {
|
||||
if let GenericParamDefKind::Type { .. } = param.kind {
|
||||
substs.push(
|
||||
args.push(
|
||||
self_ty
|
||||
.map(|ty| ty.into())
|
||||
.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 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 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.
|
||||
// Mismatches can occur as a result of elided lifetimes, or for malformed
|
||||
// input. We try to handle both sensibly.
|
||||
match (args.peek(), params.peek()) {
|
||||
match (args_iter.peek(), params.peek()) {
|
||||
(Some(&arg), Some(¶m)) => {
|
||||
match (arg, ¶m.kind, arg_count.explicit_late_bound) {
|
||||
(GenericArg::Lifetime(_), GenericParamDefKind::Lifetime, _)
|
||||
|
@ -253,8 +253,8 @@ pub fn create_substs_for_generic_args<'tcx, 'a>(
|
|||
GenericParamDefKind::Const { .. },
|
||||
_,
|
||||
) => {
|
||||
substs.push(ctx.provided_kind(param, arg));
|
||||
args.next();
|
||||
args.push(ctx.provided_kind(param, arg));
|
||||
args_iter.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
|
||||
// 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));
|
||||
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
|
||||
// due to the presence of the explicit bound so we're just going to
|
||||
// ignore it.
|
||||
args.next();
|
||||
args_iter.next();
|
||||
}
|
||||
(_, _, _) => {
|
||||
// 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
|
||||
// and any following arguments. The rest of the parameters will be
|
||||
// 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(¶m)) => {
|
||||
// If there are fewer arguments than parameters, it means
|
||||
// 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();
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
|
|
@ -9,7 +9,7 @@ mod lint;
|
|||
mod object_safety;
|
||||
|
||||
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::collect::HirPlaceholderCollector;
|
||||
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::traits::ObligationCause;
|
||||
use rustc_middle::middle::stability::AllowUnstable;
|
||||
use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef};
|
||||
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_span::edit_distance::find_best_match_for_name;
|
||||
use rustc_span::symbol::{kw, Ident, Symbol};
|
||||
|
@ -220,14 +221,14 @@ pub trait CreateSubstsForGenericArgsCtxt<'a, 'tcx> {
|
|||
&mut self,
|
||||
param: &ty::GenericParamDef,
|
||||
arg: &GenericArg<'_>,
|
||||
) -> subst::GenericArg<'tcx>;
|
||||
) -> ty::GenericArg<'tcx>;
|
||||
|
||||
fn inferred_kind(
|
||||
&mut self,
|
||||
substs: Option<&[subst::GenericArg<'tcx>]>,
|
||||
args: Option<&[ty::GenericArg<'tcx>]>,
|
||||
param: &ty::GenericParamDef,
|
||||
infer_args: bool,
|
||||
) -> subst::GenericArg<'tcx>;
|
||||
) -> ty::GenericArg<'tcx>;
|
||||
}
|
||||
|
||||
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`,
|
||||
/// 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,
|
||||
span: Span,
|
||||
def_id: DefId,
|
||||
item_segment: &hir::PathSegment<'_>,
|
||||
) -> SubstsRef<'tcx> {
|
||||
let (substs, _) = self.create_substs_for_ast_path(
|
||||
) -> GenericArgsRef<'tcx> {
|
||||
let (args, _) = self.create_args_for_ast_path(
|
||||
span,
|
||||
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)));
|
||||
}
|
||||
|
||||
substs
|
||||
args
|
||||
}
|
||||
|
||||
/// 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`,
|
||||
/// which will have been resolved to a `def_id`
|
||||
/// 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`.
|
||||
///
|
||||
/// 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>
|
||||
/// ```
|
||||
///
|
||||
/// 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
|
||||
/// type itself: `['a]`. The returned `SubstsRef` concatenates these two
|
||||
/// type itself: `['a]`. The returned `GenericArgsRef` concatenates these two
|
||||
/// lists: `[Vec<u8>, u8, 'a]`.
|
||||
#[instrument(level = "debug", skip(self, span), ret)]
|
||||
fn create_substs_for_ast_path<'a>(
|
||||
fn create_args_for_ast_path<'a>(
|
||||
&self,
|
||||
span: Span,
|
||||
def_id: DefId,
|
||||
parent_substs: &[subst::GenericArg<'tcx>],
|
||||
parent_args: &[ty::GenericArg<'tcx>],
|
||||
seg: &hir::PathSegment<'_>,
|
||||
generic_args: &'a hir::GenericArgs<'_>,
|
||||
infer_args: bool,
|
||||
self_ty: Option<Ty<'tcx>>,
|
||||
constness: ty::BoundConstness,
|
||||
) -> (SubstsRef<'tcx>, GenericArgCountResult) {
|
||||
) -> (GenericArgsRef<'tcx>, GenericArgCountResult) {
|
||||
// If the type is parameterized by this region, then replace this
|
||||
// region with the current anon region binding (in other words,
|
||||
// whatever & would get replaced with).
|
||||
|
@ -369,7 +370,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
if generics.parent.is_some() {
|
||||
// The parent is a trait so it should have at least one subst
|
||||
// for the `Self` type.
|
||||
assert!(!parent_substs.is_empty())
|
||||
assert!(!parent_args.is_empty())
|
||||
} else {
|
||||
// This item (presumably a trait) needs a self-type.
|
||||
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
|
||||
// non-`Self` generic parameters.
|
||||
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> {
|
||||
|
@ -421,7 +422,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
&mut self,
|
||||
param: &ty::GenericParamDef,
|
||||
arg: &GenericArg<'_>,
|
||||
) -> subst::GenericArg<'tcx> {
|
||||
) -> ty::GenericArg<'tcx> {
|
||||
let tcx = self.astconv.tcx();
|
||||
|
||||
let mut handle_ty_args = |has_default, ty: &hir::Ty<'_>| {
|
||||
|
@ -483,10 +484,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
|
||||
fn inferred_kind(
|
||||
&mut self,
|
||||
substs: Option<&[subst::GenericArg<'tcx>]>,
|
||||
args: Option<&[ty::GenericArg<'tcx>]>,
|
||||
param: &ty::GenericParamDef,
|
||||
infer_args: bool,
|
||||
) -> subst::GenericArg<'tcx> {
|
||||
) -> ty::GenericArg<'tcx> {
|
||||
let tcx = self.astconv.tcx();
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => self
|
||||
|
@ -506,15 +507,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
GenericParamDefKind::Type { has_default, .. } => {
|
||||
if !infer_args && has_default {
|
||||
// No type parameter provided, but a default exists.
|
||||
let substs = substs.unwrap();
|
||||
if substs.iter().any(|arg| match arg.unpack() {
|
||||
let args = args.unwrap();
|
||||
if args.iter().any(|arg| match arg.unpack() {
|
||||
GenericArgKind::Type(ty) => ty.references_error(),
|
||||
_ => false,
|
||||
}) {
|
||||
// Avoid ICE #86756 when type error recovery goes awry.
|
||||
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 {
|
||||
self.astconv.ty_infer(Some(param), self.span).into()
|
||||
} else {
|
||||
|
@ -532,7 +533,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
return ty::Const::new_error(tcx, guar, ty).into();
|
||||
}
|
||||
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 {
|
||||
if infer_args {
|
||||
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,
|
||||
def_id,
|
||||
span,
|
||||
|
@ -554,14 +557,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
inferred_params: vec![],
|
||||
infer_args,
|
||||
};
|
||||
let substs = create_substs_for_generic_args(
|
||||
let args = create_args_for_parent_generic_args(
|
||||
tcx,
|
||||
def_id,
|
||||
parent_substs,
|
||||
parent_args,
|
||||
self_ty.is_some(),
|
||||
self_ty,
|
||||
&arg_count,
|
||||
&mut substs_ctx,
|
||||
&mut args_ctx,
|
||||
);
|
||||
|
||||
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 } );
|
||||
}
|
||||
|
||||
(substs, arg_count)
|
||||
(args, arg_count)
|
||||
}
|
||||
|
||||
fn create_assoc_bindings_for_generic_args<'a>(
|
||||
|
@ -617,21 +620,21 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
assoc_bindings
|
||||
}
|
||||
|
||||
pub fn create_substs_for_associated_item(
|
||||
pub fn create_args_for_associated_item(
|
||||
&self,
|
||||
span: Span,
|
||||
item_def_id: DefId,
|
||||
item_segment: &hir::PathSegment<'_>,
|
||||
parent_substs: SubstsRef<'tcx>,
|
||||
) -> SubstsRef<'tcx> {
|
||||
parent_args: GenericArgsRef<'tcx>,
|
||||
) -> GenericArgsRef<'tcx> {
|
||||
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
|
||||
);
|
||||
let (args, _) = self.create_substs_for_ast_path(
|
||||
let (args, _) = self.create_args_for_ast_path(
|
||||
span,
|
||||
item_def_id,
|
||||
parent_substs,
|
||||
parent_args,
|
||||
item_segment,
|
||||
item_segment.args(),
|
||||
item_segment.infer_args,
|
||||
|
@ -687,7 +690,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
self_ty: Ty<'tcx>,
|
||||
only_self_bounds: OnlySelfBounds,
|
||||
) -> 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_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 poly_trait_ref =
|
||||
ty::Binder::bind_with_vars(ty::TraitRef::new(tcx, trait_def_id, substs), bound_vars);
|
||||
let poly_trait_ref = ty::Binder::bind_with_vars(
|
||||
ty::TraitRef::new(tcx, trait_def_id, generic_args),
|
||||
bound_vars,
|
||||
);
|
||||
|
||||
debug!(?poly_trait_ref, ?assoc_bindings);
|
||||
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,
|
||||
constness: ty::BoundConstness,
|
||||
) -> ty::TraitRef<'tcx> {
|
||||
let (substs, _) = self.create_substs_for_ast_trait_ref(
|
||||
let (generic_args, _) = self.create_args_for_ast_trait_ref(
|
||||
span,
|
||||
trait_def_id,
|
||||
self_ty,
|
||||
|
@ -857,11 +862,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
if let Some(b) = trait_segment.args().bindings.first() {
|
||||
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))]
|
||||
fn create_substs_for_ast_trait_ref<'a>(
|
||||
fn create_args_for_ast_trait_ref<'a>(
|
||||
&self,
|
||||
span: Span,
|
||||
trait_def_id: DefId,
|
||||
|
@ -869,10 +874,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
trait_segment: &'a hir::PathSegment<'a>,
|
||||
is_impl: bool,
|
||||
constness: ty::BoundConstness,
|
||||
) -> (SubstsRef<'tcx>, GenericArgCountResult) {
|
||||
) -> (GenericArgsRef<'tcx>, GenericArgCountResult) {
|
||||
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,
|
||||
trait_def_id,
|
||||
&[],
|
||||
|
@ -902,7 +907,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
did: DefId,
|
||||
item_segment: &hir::PathSegment<'_>,
|
||||
) -> 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);
|
||||
|
||||
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
|
||||
// referencing a single opaque type) get encoded as a type alias that normalization will
|
||||
// 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)
|
||||
} 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(
|
||||
|| traits::supertraits(tcx, ty::Binder::dummy(trait_ref.subst_identity())),
|
||||
|| {
|
||||
traits::supertraits(
|
||||
tcx,
|
||||
ty::Binder::dummy(trait_ref.instantiate_identity()),
|
||||
)
|
||||
},
|
||||
kw::SelfUpper,
|
||||
assoc_ident,
|
||||
span,
|
||||
|
@ -1620,8 +1630,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
let ocx = ObligationCtxt::new(&infcx);
|
||||
ocx.register_obligations(obligations.clone());
|
||||
|
||||
let impl_substs = infcx.fresh_substs_for_item(span, impl_);
|
||||
let impl_ty = tcx.type_of(impl_).subst(tcx, impl_substs);
|
||||
let impl_args = infcx.fresh_args_for_item(span, impl_);
|
||||
let impl_ty = tcx.type_of(impl_).instantiate(tcx, impl_args);
|
||||
let impl_ty = ocx.normalize(&cause, param_env, impl_ty);
|
||||
|
||||
// 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.
|
||||
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_obligations = traits::predicates_for_generics(
|
||||
|_, _| cause.clone(),
|
||||
|
@ -1665,18 +1675,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
if let Some((impl_, (assoc_item, def_scope))) = applicable_candidates.pop() {
|
||||
self.check_assoc_ty(assoc_item, name, def_scope, block, span);
|
||||
|
||||
// FIXME(fmease): Currently creating throwaway `parent_substs` to please
|
||||
// `create_substs_for_associated_item`. Modify the latter instead (or sth. similar) to
|
||||
// not require the parent substs logic.
|
||||
let parent_substs = InternalSubsts::identity_for_item(tcx, impl_);
|
||||
let substs =
|
||||
self.create_substs_for_associated_item(span, assoc_item, segment, parent_substs);
|
||||
let substs = tcx.mk_substs_from_iter(
|
||||
// FIXME(fmease): Currently creating throwaway `parent_args` to please
|
||||
// `create_args_for_associated_item`. Modify the latter instead (or sth. similar) to
|
||||
// not require the parent args logic.
|
||||
let parent_args = ty::GenericArgs::identity_for_item(tcx, impl_);
|
||||
let args = self.create_args_for_associated_item(span, assoc_item, segment, parent_args);
|
||||
let args = tcx.mk_args_from_iter(
|
||||
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)));
|
||||
}
|
||||
|
@ -1780,9 +1789,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
.any(|impl_def_id| {
|
||||
let trait_ref = tcx.impl_trait_ref(impl_def_id);
|
||||
trait_ref.is_some_and(|trait_ref| {
|
||||
let impl_ = trait_ref.subst(
|
||||
let impl_ = trait_ref.instantiate(
|
||||
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);
|
||||
// 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
|
||||
})
|
||||
.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.
|
||||
.filter(|self_ty| !self_ty.has_non_region_param())
|
||||
.map(|self_ty| tcx.erase_regions(self_ty).to_string())
|
||||
|
@ -1877,16 +1886,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
constness,
|
||||
);
|
||||
|
||||
let item_substs = self.create_substs_for_associated_item(
|
||||
span,
|
||||
item_def_id,
|
||||
item_segment,
|
||||
trait_ref.substs,
|
||||
);
|
||||
let item_args =
|
||||
self.create_args_for_associated_item(span, item_def_id, item_segment, trait_ref.args);
|
||||
|
||||
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>(
|
||||
|
@ -2148,8 +2153,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
self.prohibit_generics(item_segment.1.iter(), |err| {
|
||||
err.note("`impl Trait` types can't have type parameters");
|
||||
});
|
||||
let substs = self.ast_path_substs_for_ty(span, did, item_segment.0);
|
||||
Ty::new_opaque(tcx, did, substs)
|
||||
let args = self.ast_path_args_for_ty(span, did, item_segment.0);
|
||||
Ty::new_opaque(tcx, did, args)
|
||||
}
|
||||
Res::Def(
|
||||
DefKind::Enum
|
||||
|
@ -2233,7 +2238,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
// `Self` in impl (we know the concrete type).
|
||||
assert_eq!(opt_self_ty, None);
|
||||
// Try to evaluate any array length constants.
|
||||
let ty = tcx.at(span).type_of(def_id).subst_identity();
|
||||
let ty = tcx.at(span).type_of(def_id).instantiate_identity();
|
||||
let span_of_impl = tcx.span_of_impl(def_id);
|
||||
self.prohibit_generics(path.segments.iter(), |err| {
|
||||
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, _)) => {
|
||||
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,
|
||||
def_id,
|
||||
&[],
|
||||
|
@ -2481,7 +2486,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
None,
|
||||
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) => {
|
||||
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)
|
||||
}
|
||||
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, _| {
|
||||
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);
|
||||
|
||||
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`
|
||||
// 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.
|
||||
|
@ -2550,12 +2555,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
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 {
|
||||
Ty::new_projection(tcx, def_id, substs)
|
||||
Ty::new_projection(tcx, def_id, args)
|
||||
} 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,
|
||||
)?;
|
||||
|
||||
let fn_sig = tcx.fn_sig(assoc.def_id).subst(
|
||||
let fn_sig = tcx.fn_sig(assoc.def_id).instantiate(
|
||||
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);
|
||||
|
||||
|
|
|
@ -262,8 +262,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
let mut missing_type_params = vec![];
|
||||
let mut references_self = false;
|
||||
let generics = tcx.generics_of(trait_ref.def_id);
|
||||
let substs: Vec<_> = trait_ref
|
||||
.substs
|
||||
let args: Vec<_> = trait_ref
|
||||
.args
|
||||
.iter()
|
||||
.enumerate()
|
||||
.skip(1) // Remove `Self` for `ExistentialPredicate`.
|
||||
|
@ -279,7 +279,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
arg
|
||||
})
|
||||
.collect();
|
||||
let substs = tcx.mk_substs(&substs);
|
||||
let args = tcx.mk_args(&args);
|
||||
|
||||
let span = i.bottom().1;
|
||||
let empty_generic_args = hir_trait_bounds.iter().any(|hir_bound| {
|
||||
|
@ -310,7 +310,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
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
|
||||
// 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()) {
|
||||
return true;
|
||||
}
|
||||
|
@ -336,9 +336,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
span,
|
||||
"trait object projection bounds reference `Self`",
|
||||
);
|
||||
let substs: Vec<_> = b
|
||||
let args: Vec<_> = b
|
||||
.projection_ty
|
||||
.substs
|
||||
.args
|
||||
.iter()
|
||||
.map(|arg| {
|
||||
if arg.walk().any(|arg| arg == dummy_self.into()) {
|
||||
|
@ -347,7 +347,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
arg
|
||||
})
|
||||
.collect();
|
||||
b.projection_ty.substs = tcx.mk_substs(&substs);
|
||||
b.projection_ty.args = tcx.mk_args(&args);
|
||||
}
|
||||
|
||||
ty::ExistentialProjection::erase_self_ty(tcx, b)
|
||||
|
|
|
@ -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."))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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()])),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -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(..) => {}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ impl<'tcx> Checker<'tcx> {
|
|||
|
||||
fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
|
||||
// Destructors only work on local ADT types.
|
||||
match tcx.type_of(impl_did).subst_identity().kind() {
|
||||
match tcx.type_of(impl_did).instantiate_identity().kind() {
|
||||
ty::Adt(def, _) if def.did().is_local() => 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) {
|
||||
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);
|
||||
|
||||
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) {
|
||||
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());
|
||||
|
||||
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 source = tcx.type_of(impl_did).subst_identity();
|
||||
let source = tcx.type_of(impl_did).instantiate_identity();
|
||||
assert!(!source.has_escaping_bound_vars());
|
||||
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);
|
||||
|
||||
trait_ref.substs.type_at(1)
|
||||
trait_ref.args.type_at(1)
|
||||
};
|
||||
|
||||
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()
|
||||
&& mutbl_a == *mutbl_b => {}
|
||||
(&RawPtr(tm_a), &RawPtr(tm_b)) if tm_a.mutbl == tm_b.mutbl => (),
|
||||
(&Adt(def_a, substs_a), &Adt(def_b, substs_b))
|
||||
if def_a.is_struct() && def_b.is_struct() =>
|
||||
{
|
||||
(&Adt(def_a, args_a), &Adt(def_b, args_b)) if def_a.is_struct() && def_b.is_struct() => {
|
||||
if def_a != def_b {
|
||||
let source_path = tcx.def_path_str(def_a.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
|
||||
.iter()
|
||||
.filter(|field| {
|
||||
let ty_a = field.ty(tcx, substs_a);
|
||||
let ty_b = field.ty(tcx, substs_b);
|
||||
let ty_a = field.ty(tcx, args_a);
|
||||
let ty_b = field.ty(tcx, args_b);
|
||||
|
||||
if let Ok(layout) = tcx.layout_of(param_env.and(ty_a)) {
|
||||
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!(
|
||||
"`{}` (`{}` to `{}`)",
|
||||
field.name,
|
||||
field.ty(tcx, substs_a),
|
||||
field.ty(tcx, substs_b),
|
||||
field.ty(tcx, args_a),
|
||||
field.ty(tcx, args_b),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
|
@ -268,7 +266,7 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
|
|||
ty::TraitRef::new(
|
||||
tcx,
|
||||
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 source = tcx.type_of(impl_did).subst_identity();
|
||||
let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().subst_identity();
|
||||
let source = tcx.type_of(impl_did).instantiate_identity();
|
||||
let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().instantiate_identity();
|
||||
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);
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
(&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 != def_b {
|
||||
|
@ -411,9 +409,9 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
|
|||
let diff_fields = fields
|
||||
.iter_enumerated()
|
||||
.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
|
||||
return None;
|
||||
}
|
||||
|
|
|
@ -171,7 +171,7 @@ impl<'tcx> InherentCollect<'tcx> {
|
|||
|
||||
let id = id.owner_id.def_id;
|
||||
let item_span = self.tcx.def_span(id);
|
||||
let self_ty = self.tcx.type_of(id).subst_identity();
|
||||
let self_ty = self.tcx.type_of(id).instantiate_identity();
|
||||
match *self_ty.kind() {
|
||||
ty::Adt(def, _) => self.check_def_id(id, self_ty, def.did()),
|
||||
ty::Foreign(did) => self.check_def_id(id, self_ty, did),
|
||||
|
|
|
@ -122,7 +122,7 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) {
|
|||
|
||||
let impls = tcx.hir().trait_impls(def_id);
|
||||
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_object_overlap(tcx, impl_def_id, trait_ref);
|
||||
|
|
|
@ -5,8 +5,8 @@ use rustc_data_structures::fx::FxHashSet;
|
|||
use rustc_errors::{struct_span_err, DelayDm};
|
||||
use rustc_errors::{Diagnostic, ErrorGuaranteed};
|
||||
use rustc_hir as hir;
|
||||
use rustc_middle::ty::subst::InternalSubsts;
|
||||
use rustc_middle::ty::util::CheckRegions;
|
||||
use rustc_middle::ty::GenericArgs;
|
||||
use rustc_middle::ty::{
|
||||
self, AliasKind, ImplPolarity, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
|
||||
TypeVisitor,
|
||||
|
@ -22,7 +22,7 @@ pub(crate) fn orphan_check_impl(
|
|||
tcx: TyCtxt<'_>,
|
||||
impl_def_id: LocalDefId,
|
||||
) -> 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()?;
|
||||
|
||||
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>,
|
||||
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_type_did, substs) = match self_ty.kind() {
|
||||
ty::Adt(def, substs) => (def.did(), substs),
|
||||
let (self_type_did, args) = match self_ty.kind() {
|
||||
ty::Adt(def, args) => (def.did(), args),
|
||||
_ => {
|
||||
// FIXME: should also lint for stuff like `&i32` but
|
||||
// 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
|
||||
// disable auto impls entirely. So only lint if the substs
|
||||
// are not a permutation of the identity substs.
|
||||
let Err(arg) = tcx.uses_unique_generic_params(substs, CheckRegions::No) else {
|
||||
// disable auto impls entirely. So only lint if the args
|
||||
// are not a permutation of the identity args.
|
||||
let Err(arg) = tcx.uses_unique_generic_params(args, CheckRegions::No) else {
|
||||
// ok
|
||||
return;
|
||||
};
|
||||
|
@ -585,14 +585,14 @@ fn fast_reject_auto_impl<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, self_ty:
|
|||
}
|
||||
|
||||
match t.kind() {
|
||||
ty::Adt(def, substs) if def.is_phantom_data() => substs.visit_with(self),
|
||||
ty::Adt(def, substs) => {
|
||||
ty::Adt(def, args) if def.is_phantom_data() => args.visit_with(self),
|
||||
ty::Adt(def, args) => {
|
||||
// @lcnr: This is the only place where cycles can happen. We avoid this
|
||||
// by only visiting each `DefId` once.
|
||||
//
|
||||
// This will be is incorrect in subtle cases, but I don't care :)
|
||||
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)?;
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
||||
ty::Adt(def, _) => {
|
||||
Ty::new_adt(tcx, *def, InternalSubsts::identity_for_item(tcx, def.did()))
|
||||
}
|
||||
ty::Adt(def, _) => Ty::new_adt(tcx, *def, GenericArgs::identity_for_item(tcx, def.did())),
|
||||
_ => unimplemented!("unexpected self ty {:?}", self_ty),
|
||||
};
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||
let impl_ = item.expect_impl();
|
||||
|
||||
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 unsafe_attr =
|
||||
impl_.generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle");
|
||||
|
|
|
@ -401,13 +401,13 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
|
|||
poly_trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
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,
|
||||
item_def_id,
|
||||
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 {
|
||||
// There are no late-bound regions; we can just ignore the binder.
|
||||
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() => {
|
||||
let ty = tcx.type_of(tcx.hir().get_parent_item(hir_id)).subst_identity();
|
||||
let inputs = data.fields().iter().map(|f| tcx.type_of(f.def_id).subst_identity());
|
||||
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).instantiate_identity());
|
||||
ty::Binder::dummy(tcx.mk_fn_sig(
|
||||
inputs,
|
||||
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
|
||||
// example, a closure signature excludes the `self`
|
||||
// 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
|
||||
// `sig` method on the `ClosureSubsts`:
|
||||
// `sig` method on the `ClosureArgs`:
|
||||
//
|
||||
// substs.as_closure().sig(def_id, tcx)
|
||||
bug!(
|
||||
"to get the signature of a closure, use `substs.as_closure().sig()` not `fn_sig()`",
|
||||
);
|
||||
// args.as_closure().sig(def_id, tcx)
|
||||
bug!("to get the signature of a closure, use `args.as_closure().sig()` not `fn_sig()`",);
|
||||
}
|
||||
|
||||
x => {
|
||||
|
@ -1266,7 +1264,7 @@ fn suggest_impl_trait<'tcx>(
|
|||
) -> Option<String> {
|
||||
let format_as_assoc: fn(_, _, _, _, _) -> _ =
|
||||
|tcx: TyCtxt<'tcx>,
|
||||
_: ty::SubstsRef<'tcx>,
|
||||
_: ty::GenericArgsRef<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
assoc_item_def_id: DefId,
|
||||
item_ty: Ty<'tcx>| {
|
||||
|
@ -1276,12 +1274,12 @@ fn suggest_impl_trait<'tcx>(
|
|||
};
|
||||
let format_as_parenthesized: fn(_, _, _, _, _) -> _ =
|
||||
|tcx: TyCtxt<'tcx>,
|
||||
substs: ty::SubstsRef<'tcx>,
|
||||
args: ty::GenericArgsRef<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
_: DefId,
|
||||
item_ty: Ty<'tcx>| {
|
||||
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 {
|
||||
return None;
|
||||
};
|
||||
|
@ -1328,24 +1326,23 @@ fn suggest_impl_trait<'tcx>(
|
|||
}
|
||||
let param_env = tcx.param_env(def_id);
|
||||
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 !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;
|
||||
}
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
let item_ty = ocx.normalize(
|
||||
&ObligationCause::misc(span, def_id),
|
||||
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.
|
||||
if ocx.select_where_possible().is_empty()
|
||||
&& let item_ty = infcx.resolve_vars_if_possible(item_ty)
|
||||
&& 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);
|
||||
}
|
||||
|
@ -1363,7 +1360,7 @@ fn impl_trait_ref(
|
|||
.of_trait
|
||||
.as_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(
|
||||
ast_trait_ref,
|
||||
selfty,
|
||||
|
|
|
@ -68,17 +68,17 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
|||
// ^ parent_def_id
|
||||
//
|
||||
// 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
|
||||
// we substitute the defaults with the partially built substs when we build the substs. Subst'ing
|
||||
// the `N#0` on the unevaluated const indexes into the empty substs we're in the process of building.
|
||||
// This causes ICEs (#86580) when building the args for Foo in `fn foo() -> Foo { .. }` as
|
||||
// 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 args we're in the process of building.
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
// For the above code example that means we want `substs: []`
|
||||
// For the following struct def we want `substs: [N#0]` when generics_of is called on
|
||||
// For the above code example that means we want `args: []`
|
||||
// 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
|
||||
// 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 {
|
||||
// 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 = { ... }>;
|
||||
parent: generics.parent,
|
||||
parent_count: generics.parent_count,
|
||||
|
|
|
@ -2,7 +2,7 @@ use super::ItemCtxt;
|
|||
use crate::astconv::{AstConv, PredicateFilter};
|
||||
use rustc_hir as hir;
|
||||
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_span::def_id::{DefId, LocalDefId};
|
||||
use rustc_span::Span;
|
||||
|
@ -10,7 +10,7 @@ use rustc_span::Span;
|
|||
/// For associated types we include both bounds written on the type
|
||||
/// (`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
|
||||
/// a bound such as `for<'b> <Self as X<'b>>::U: Clone` can't be used, as in
|
||||
/// `hr-associated-type-bound-1.rs`.
|
||||
|
@ -23,7 +23,7 @@ fn associated_type_bounds<'tcx>(
|
|||
let item_ty = Ty::new_projection(
|
||||
tcx,
|
||||
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);
|
||||
|
@ -95,7 +95,7 @@ pub(super) fn explicit_item_bounds(
|
|||
Ty::new_projection(
|
||||
tcx,
|
||||
def_id.to_def_id(),
|
||||
ty::InternalSubsts::identity_for_item(tcx, def_id),
|
||||
ty::GenericArgs::identity_for_item(tcx, def_id),
|
||||
),
|
||||
item.span,
|
||||
));
|
||||
|
@ -117,8 +117,8 @@ pub(super) fn explicit_item_bounds(
|
|||
span,
|
||||
..
|
||||
}) => {
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), substs);
|
||||
let args = GenericArgs::identity_for_item(tcx, def_id);
|
||||
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
|
||||
opaque_type_bounds(tcx, def_id, bounds, item_ty, *span)
|
||||
}
|
||||
hir::Node::Item(hir::Item { kind: hir::ItemKind::TyAlias(..), .. }) => &[],
|
||||
|
|
|
@ -8,7 +8,6 @@ use rustc_hir as hir;
|
|||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_middle::ty::subst::InternalSubsts;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{GenericPredicates, Generics, ImplTraitInTraitData, ToPredicate};
|
||||
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
|
||||
// parent predicates would hold, and also so that the param-env
|
||||
// inherits these predicates as assumptions.
|
||||
let identity_substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
predicates.extend(
|
||||
tcx.explicit_predicates_of(fn_def_id).instantiate_own(tcx, identity_substs),
|
||||
);
|
||||
let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||
predicates
|
||||
.extend(tcx.explicit_predicates_of(fn_def_id).instantiate_own(tcx, identity_args));
|
||||
|
||||
// We also install bidirectional outlives predicates for the RPITIT
|
||||
// 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 =
|
||||
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_trait_ref_substs =
|
||||
tcx.impl_trait_ref(impl_def_id).unwrap().subst_identity().substs;
|
||||
let impl_trait_ref_args =
|
||||
tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity().args;
|
||||
|
||||
let impl_assoc_substs =
|
||||
impl_assoc_identity_substs.rebase_onto(tcx, impl_def_id, impl_trait_ref_substs);
|
||||
let impl_assoc_args =
|
||||
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 {
|
||||
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 {
|
||||
ItemKind::Impl(impl_) => {
|
||||
if impl_.defaultness.is_default() {
|
||||
is_default_impl_trait =
|
||||
tcx.impl_trait_ref(def_id).map(|t| ty::Binder::dummy(t.subst_identity()));
|
||||
is_default_impl_trait = tcx
|
||||
.impl_trait_ref(def_id)
|
||||
.map(|t| ty::Binder::dummy(t.instantiate_identity()));
|
||||
}
|
||||
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`
|
||||
// for details.
|
||||
if let Node::Item(&Item { kind: ItemKind::Impl { .. }, .. }) = node {
|
||||
let self_ty = tcx.type_of(def_id).subst_identity();
|
||||
let trait_ref = tcx.impl_trait_ref(def_id).map(ty::EarlyBinder::subst_identity);
|
||||
let self_ty = tcx.type_of(def_id).instantiate_identity();
|
||||
let trait_ref = tcx.impl_trait_ref(def_id).map(ty::EarlyBinder::instantiate_identity);
|
||||
cgp::setup_constraining_predicates(
|
||||
tcx,
|
||||
&mut predicates,
|
||||
|
@ -397,7 +396,7 @@ fn compute_bidirectional_outlives_predicates<'tcx>(
|
|||
let orig_region = icx.astconv().ast_region_to_region(&arg, None);
|
||||
if !matches!(orig_region.kind(), ty::ReEarlyBound(..)) {
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -499,20 +498,20 @@ pub(super) fn explicit_predicates_of<'tcx>(
|
|||
// Remove bounds on associated types from the predicates, they will be
|
||||
// returned by `explicit_item_bounds`.
|
||||
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>| {
|
||||
// For a predicate from a where clause to become a bound on an
|
||||
// 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
|
||||
// parameters of the GAT. That means that all we need to
|
||||
// check are that the substs of the projection are the
|
||||
// identity substs of the trait.
|
||||
// check are that the args of the projection are the
|
||||
// identity args of the trait.
|
||||
// * It must be an associated type for this trait (*not* a
|
||||
// supertrait).
|
||||
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
|
||||
&& !tcx.is_impl_trait_in_trait(projection.def_id)
|
||||
&& tcx.associated_item(projection.def_id).container_id(tcx)
|
||||
|
|
|
@ -1721,7 +1721,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
},
|
||||
));
|
||||
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
|
||||
} else {
|
||||
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 },
|
||||
)) => {
|
||||
// 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 mut walker = ConstrainedCollectorPostAstConv {
|
||||
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() {
|
||||
Some(hir::PathSegment { args: Some(args), .. }) => {
|
||||
|
|
|
@ -3,7 +3,6 @@ use rustc_hir as hir;
|
|||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::HirId;
|
||||
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::{self, ImplTraitInTraitData, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
|
||||
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) {
|
||||
Node::TraitItem(item) => match item.kind {
|
||||
TraitItemKind::Fn(..) => {
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
Ty::new_fn_def(tcx, def_id.to_def_id(), substs)
|
||||
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||
Ty::new_fn_def(tcx, def_id.to_def_id(), args)
|
||||
}
|
||||
TraitItemKind::Const(ty, body_id) => 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 {
|
||||
ImplItemKind::Fn(..) => {
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
Ty::new_fn_def(tcx, def_id.to_def_id(), substs)
|
||||
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||
Ty::new_fn_def(tcx, def_id.to_def_id(), args)
|
||||
}
|
||||
ImplItemKind::Const(ty, body_id) => {
|
||||
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),
|
||||
},
|
||||
ItemKind::Fn(..) => {
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
Ty::new_fn_def(tcx, def_id.to_def_id(), substs)
|
||||
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||
Ty::new_fn_def(tcx, def_id.to_def_id(), args)
|
||||
}
|
||||
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => {
|
||||
let def = tcx.adt_def(def_id);
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
Ty::new_adt(tcx, def, substs)
|
||||
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||
Ty::new_adt(tcx, def, args)
|
||||
}
|
||||
ItemKind::OpaqueTy(OpaqueTy {
|
||||
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 {
|
||||
ForeignItemKind::Fn(..) => {
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
Ty::new_fn_def(tcx, def_id.to_def_id(), substs)
|
||||
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||
Ty::new_fn_def(tcx, def_id.to_def_id(), args)
|
||||
}
|
||||
ForeignItemKind::Static(t, _) => icx.to_ty(t),
|
||||
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 {
|
||||
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(..) => {
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
Ty::new_fn_def(tcx, def_id.to_def_id(), substs)
|
||||
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||
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::ConstBlock(_) => {
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
|
||||
substs.as_inline_const().ty()
|
||||
let args = ty::GenericArgs::identity_for_item(tcx, def_id.to_def_id());
|
||||
args.as_inline_const().ty()
|
||||
}
|
||||
|
||||
Node::GenericParam(param) => match ¶m.kind {
|
||||
|
|
|
@ -70,7 +70,7 @@ pub fn provide(providers: &mut Providers) {
|
|||
|
||||
fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) {
|
||||
// Every lifetime used in an associated type must be constrained.
|
||||
let impl_self_ty = tcx.type_of(impl_def_id).subst_identity();
|
||||
let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity();
|
||||
if impl_self_ty.references_error() {
|
||||
// Don't complain about unconstrained type params when self ty isn't known due to errors.
|
||||
// (#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_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);
|
||||
cgp::identify_constrained_generic_params(
|
||||
|
@ -104,7 +104,7 @@ fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId)
|
|||
match item.kind {
|
||||
ty::AssocKind::Type => {
|
||||
if item.defaultness(tcx).has_value() {
|
||||
cgp::parameters_for(&tcx.type_of(def_id).subst_identity(), true)
|
||||
cgp::parameters_for(&tcx.type_of(def_id).instantiate_identity(), true)
|
||||
} else {
|
||||
vec![]
|
||||
}
|
||||
|
|
|
@ -14,15 +14,15 @@
|
|||
//! To enforce this requirement on specializations we take the following
|
||||
//! 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`.
|
||||
//! 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
|
||||
//! 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
|
||||
//! predicate.
|
||||
//! 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.
|
||||
//!
|
||||
//! ## Example
|
||||
|
@ -74,13 +74,13 @@ use rustc_hir::def_id::{DefId, LocalDefId};
|
|||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
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::{self, TyCtxt, TypeVisitableExt};
|
||||
use rustc_middle::ty::{GenericArg, GenericArgs, GenericArgsRef};
|
||||
use rustc_span::{ErrorGuaranteed, Span};
|
||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
||||
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) {
|
||||
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);
|
||||
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();
|
||||
debug!(?impl2_def_id, ?impl2_substs);
|
||||
debug!(?impl2_def_id, ?impl2_args);
|
||||
|
||||
let parent_substs = if impl2_node.is_from_trait() {
|
||||
impl2_substs.to_vec()
|
||||
let parent_args = if impl2_node.is_from_trait() {
|
||||
impl2_args.to_vec()
|
||||
} 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_static_lifetimes(tcx, &parent_substs, span);
|
||||
check_duplicate_params(tcx, impl1_substs, &parent_substs, span);
|
||||
check_predicates(tcx, impl1_def_id, impl1_substs, impl2_node, impl2_substs, span);
|
||||
check_static_lifetimes(tcx, &parent_args, span);
|
||||
check_duplicate_params(tcx, impl1_args, &parent_args, 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]`.
|
||||
fn get_impl_substs(
|
||||
fn get_impl_args(
|
||||
tcx: TyCtxt<'_>,
|
||||
impl1_def_id: LocalDefId,
|
||||
impl2_node: Node,
|
||||
) -> Result<(SubstsRef<'_>, SubstsRef<'_>), ErrorGuaranteed> {
|
||||
) -> Result<(GenericArgsRef<'_>, GenericArgsRef<'_>), ErrorGuaranteed> {
|
||||
let infcx = &tcx.infer_ctxt().build();
|
||||
let ocx = ObligationCtxt::new(infcx);
|
||||
let param_env = tcx.param_env(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 impl1_substs = InternalSubsts::identity_for_item(tcx, impl1_def_id);
|
||||
let impl2_substs = translate_substs_with_cause(
|
||||
let impl1_args = GenericArgs::identity_for_item(tcx, impl1_def_id);
|
||||
let impl2_args = translate_args_with_cause(
|
||||
infcx,
|
||||
param_env,
|
||||
impl1_def_id.to_def_id(),
|
||||
impl1_substs,
|
||||
impl1_args,
|
||||
impl2_node,
|
||||
|_, span| {
|
||||
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 outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
|
||||
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 guar = tcx.sess.emit_err(SubstsOnOverriddenImpl { span });
|
||||
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.
|
||||
|
@ -217,17 +217,17 @@ fn get_impl_substs(
|
|||
///
|
||||
/// 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`.
|
||||
fn unconstrained_parent_impl_substs<'tcx>(
|
||||
fn unconstrained_parent_impl_args<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl_def_id: DefId,
|
||||
impl_substs: SubstsRef<'tcx>,
|
||||
impl_args: GenericArgsRef<'tcx>,
|
||||
) -> Vec<GenericArg<'tcx>> {
|
||||
let impl_generic_predicates = tcx.predicates_of(impl_def_id);
|
||||
let mut unconstrained_parameters = 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
|
||||
// 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()
|
||||
.enumerate()
|
||||
.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
|
||||
/// equated substs of the base impl.
|
||||
/// equated args of the base impl.
|
||||
///
|
||||
/// For example forbid the following:
|
||||
///
|
||||
|
@ -280,19 +280,19 @@ fn unconstrained_parent_impl_substs<'tcx>(
|
|||
/// impl<T> Tr<T> for Vec<T> { }
|
||||
/// ```
|
||||
///
|
||||
/// The substs 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
|
||||
/// The args for the parent impl here are `[T, Vec<T>]`, which repeats `T`,
|
||||
/// but `S` is constrained in the parent impl, so `parent_args` is only
|
||||
/// `[Vec<T>]`. This means we allow this impl.
|
||||
fn check_duplicate_params<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl1_substs: SubstsRef<'tcx>,
|
||||
parent_substs: &Vec<GenericArg<'tcx>>,
|
||||
impl1_args: GenericArgsRef<'tcx>,
|
||||
parent_args: &Vec<GenericArg<'tcx>>,
|
||||
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);
|
||||
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
|
||||
.struct_span_err(span, format!("specializing impl repeats parameter `{}`", param))
|
||||
.emit();
|
||||
|
@ -309,10 +309,10 @@ fn check_duplicate_params<'tcx>(
|
|||
/// ```
|
||||
fn check_static_lifetimes<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
parent_substs: &Vec<GenericArg<'tcx>>,
|
||||
parent_args: &Vec<GenericArg<'tcx>>,
|
||||
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 });
|
||||
}
|
||||
}
|
||||
|
@ -331,14 +331,14 @@ fn check_static_lifetimes<'tcx>(
|
|||
fn check_predicates<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl1_def_id: LocalDefId,
|
||||
impl1_substs: SubstsRef<'tcx>,
|
||||
impl1_args: GenericArgsRef<'tcx>,
|
||||
impl2_node: Node,
|
||||
impl2_substs: SubstsRef<'tcx>,
|
||||
impl2_args: GenericArgsRef<'tcx>,
|
||||
span: Span,
|
||||
) {
|
||||
let impl1_predicates: Vec<_> = traits::elaborate(
|
||||
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();
|
||||
|
||||
|
@ -350,7 +350,7 @@ fn check_predicates<'tcx>(
|
|||
traits::elaborate(
|
||||
tcx,
|
||||
tcx.predicates_of(impl2_node.def_id())
|
||||
.instantiate(tcx, impl2_substs)
|
||||
.instantiate(tcx, impl2_args)
|
||||
.into_iter()
|
||||
.map(|(c, _s)| c.as_predicate()),
|
||||
)
|
||||
|
@ -385,7 +385,7 @@ fn check_predicates<'tcx>(
|
|||
.map(|(c, _span)| c.as_predicate());
|
||||
|
||||
// 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 obligations =
|
||||
wf::obligations(infcx, tcx.param_env(impl1_def_id), impl1_def_id, 0, arg, span)
|
||||
|
|
|
@ -178,12 +178,12 @@ fn require_same_types<'tcx>(
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
fn main_fn_diagnostics_def_id(tcx: TyCtxt<'_>, def_id: DefId, sp: Span) -> LocalDefId {
|
||||
if let Some(local_def_id) = def_id.as_local() {
|
||||
let hir_type = tcx.type_of(local_def_id).subst_identity();
|
||||
let hir_type = tcx.type_of(local_def_id).instantiate_identity();
|
||||
if !matches!(hir_type.kind(), ty::FnDef(..)) {
|
||||
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_id = tcx.hir().local_def_id_to_hir_id(start_def_id);
|
||||
let start_span = tcx.def_span(start_def_id);
|
||||
let start_t = tcx.type_of(start_def_id).subst_identity();
|
||||
let start_t = tcx.type_of(start_def_id).instantiate_identity();
|
||||
match start_t.kind() {
|
||||
ty::FnDef(..) => {
|
||||
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.
|
||||
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()),
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
|
|
|
@ -46,7 +46,7 @@ pub(super) fn infer_predicates(
|
|||
// For field of type &'a T (reference) or Adt
|
||||
// (struct/enum/union) there will be outlive
|
||||
// requirements for adt_def.
|
||||
let field_ty = tcx.type_of(field_def.did).subst_identity();
|
||||
let field_ty = tcx.type_of(field_def.did).instantiate_identity();
|
||||
let field_span = tcx.def_span(field_def.did);
|
||||
insert_required_predicates_to_be_wf(
|
||||
tcx,
|
||||
|
@ -117,7 +117,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
|
|||
// can load the current set of inferred and explicit
|
||||
// predicates from `global_inferred_outlives` and filter the
|
||||
// ones that are TypeOutlives.
|
||||
ty::Adt(def, substs) => {
|
||||
ty::Adt(def, args) => {
|
||||
// First check the inferred predicates
|
||||
//
|
||||
// Example 1:
|
||||
|
@ -146,7 +146,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
|
|||
// get `T: 'a` (or `predicate`):
|
||||
let predicate = unsubstituted_predicates
|
||||
.rebind(*unsubstituted_predicate)
|
||||
.subst(tcx, substs);
|
||||
.instantiate(tcx, args);
|
||||
insert_outlives_predicate(
|
||||
tcx,
|
||||
predicate.0,
|
||||
|
@ -159,11 +159,11 @@ fn insert_required_predicates_to_be_wf<'tcx>(
|
|||
|
||||
// Check if the type has any explicit predicates that need
|
||||
// to be added to `required_predicates`
|
||||
// let _: () = substs.region_at(0);
|
||||
// let _: () = args.region_at(0);
|
||||
check_explicit_predicates(
|
||||
tcx,
|
||||
def.did(),
|
||||
substs,
|
||||
args,
|
||||
required_predicates,
|
||||
explicit_map,
|
||||
None,
|
||||
|
@ -186,12 +186,11 @@ fn insert_required_predicates_to_be_wf<'tcx>(
|
|||
// predicates in `check_explicit_predicates` we
|
||||
// need to ignore checking the explicit_map for
|
||||
// Self type.
|
||||
let substs =
|
||||
ex_trait_ref.with_self_ty(tcx, tcx.types.usize).skip_binder().substs;
|
||||
let args = ex_trait_ref.with_self_ty(tcx, tcx.types.usize).skip_binder().args;
|
||||
check_explicit_predicates(
|
||||
tcx,
|
||||
ex_trait_ref.skip_binder().def_id,
|
||||
substs,
|
||||
args,
|
||||
required_predicates,
|
||||
explicit_map,
|
||||
Some(tcx.types.self_param),
|
||||
|
@ -206,7 +205,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
|
|||
check_explicit_predicates(
|
||||
tcx,
|
||||
tcx.parent(obj.def_id),
|
||||
obj.substs,
|
||||
obj.args,
|
||||
required_predicates,
|
||||
explicit_map,
|
||||
None,
|
||||
|
@ -239,18 +238,18 @@ fn insert_required_predicates_to_be_wf<'tcx>(
|
|||
fn check_explicit_predicates<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: DefId,
|
||||
substs: &[GenericArg<'tcx>],
|
||||
args: &[GenericArg<'tcx>],
|
||||
required_predicates: &mut RequiredPredicates<'tcx>,
|
||||
explicit_map: &mut ExplicitPredicatesMap<'tcx>,
|
||||
ignored_self_ty: Option<Ty<'tcx>>,
|
||||
) {
|
||||
debug!(
|
||||
"check_explicit_predicates(def_id={:?}, \
|
||||
substs={:?}, \
|
||||
args={:?}, \
|
||||
explicit_map={:?}, \
|
||||
required_predicates={:?}, \
|
||||
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);
|
||||
|
||||
|
@ -278,10 +277,10 @@ fn check_explicit_predicates<'tcx>(
|
|||
// that is represented by the `dyn Trait`, not to the `X` type parameter
|
||||
// (or any other generic parameter) declared on `MyStruct`.
|
||||
//
|
||||
// Note that we do this check for self **before** applying `substs`. In the
|
||||
// case that `substs` come from a `dyn Trait` type, our caller will have
|
||||
// Note that we do this check for self **before** applying `args`. In the
|
||||
// case that `args` come from a `dyn Trait` type, our caller will have
|
||||
// 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.
|
||||
//
|
||||
// Another similar case is where we have an inferred
|
||||
|
@ -299,7 +298,7 @@ fn check_explicit_predicates<'tcx>(
|
|||
continue;
|
||||
}
|
||||
|
||||
let predicate = explicit_predicates.rebind(*outlives_predicate).subst(tcx, substs);
|
||||
let predicate = explicit_predicates.rebind(*outlives_predicate).instantiate(tcx, args);
|
||||
debug!("predicate = {:?}", &predicate);
|
||||
insert_outlives_predicate(tcx, predicate.0, predicate.1, span, required_predicates);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use hir::Node;
|
|||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::subst::GenericArgKind;
|
||||
use rustc_middle::ty::GenericArgKind;
|
||||
use rustc_middle::ty::{self, CratePredicatesMap, ToPredicate, TyCtxt};
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::Span;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use rustc_infer::infer::outlives::components::{push_outlives_components, Component};
|
||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
|
||||
use rustc_middle::ty::{self, Region, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{GenericArg, GenericArgKind};
|
||||
use rustc_span::Span;
|
||||
use smallvec::smallvec;
|
||||
use std::collections::BTreeMap;
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
use hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
|
||||
|
||||
use super::terms::VarianceTerm::*;
|
||||
use super::terms::*;
|
||||
|
@ -101,7 +101,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
|
||||
let inferred_start = self.terms_cx.inferred_starts[&def_id];
|
||||
let current_item = &CurrentItem { inferred_start };
|
||||
match tcx.type_of(def_id).subst_identity().kind() {
|
||||
match tcx.type_of(def_id).instantiate_identity().kind() {
|
||||
ty::Adt(def, _) => {
|
||||
// Not entirely obvious: constraints on structs/enums do not
|
||||
// affect the variance of their type parameters. See discussion
|
||||
|
@ -112,7 +112,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
for field in def.all_fields() {
|
||||
self.add_constraints_from_ty(
|
||||
current_item,
|
||||
tcx.type_of(field.did).subst_identity(),
|
||||
tcx.type_of(field.did).instantiate_identity(),
|
||||
self.covariant,
|
||||
);
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
ty::FnDef(..) => {
|
||||
self.add_constraints_from_sig(
|
||||
current_item,
|
||||
tcx.fn_sig(def_id).subst_identity(),
|
||||
tcx.fn_sig(def_id).instantiate_identity(),
|
||||
self.covariant,
|
||||
);
|
||||
}
|
||||
|
@ -175,16 +175,16 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self, current))]
|
||||
fn add_constraints_from_invariant_substs(
|
||||
fn add_constraints_from_invariant_args(
|
||||
&mut self,
|
||||
current: &CurrentItem,
|
||||
substs: SubstsRef<'tcx>,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
variance: VarianceTermPtr<'a>,
|
||||
) {
|
||||
// Trait are always invariant so we can take advantage of that.
|
||||
let variance_i = self.invariant(variance);
|
||||
|
||||
for k in substs {
|
||||
for k in args {
|
||||
match k.unpack() {
|
||||
GenericArgKind::Lifetime(lt) => {
|
||||
self.add_constraints_from_region(current, lt, variance_i)
|
||||
|
@ -248,12 +248,12 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
ty::Adt(def, substs) => {
|
||||
self.add_constraints_from_substs(current, def.did(), substs, variance);
|
||||
ty::Adt(def, args) => {
|
||||
self.add_constraints_from_args(current, def.did(), args, variance);
|
||||
}
|
||||
|
||||
ty::Alias(_, ref data) => {
|
||||
self.add_constraints_from_invariant_substs(current, data.substs, variance);
|
||||
self.add_constraints_from_invariant_args(current, data.args, variance);
|
||||
}
|
||||
|
||||
ty::Dynamic(data, r, _) => {
|
||||
|
@ -261,9 +261,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
self.add_constraints_from_region(current, r, variance);
|
||||
|
||||
if let Some(poly_trait_ref) = data.principal() {
|
||||
self.add_constraints_from_invariant_substs(
|
||||
self.add_constraints_from_invariant_args(
|
||||
current,
|
||||
poly_trait_ref.skip_binder().substs,
|
||||
poly_trait_ref.skip_binder().args,
|
||||
variance,
|
||||
);
|
||||
}
|
||||
|
@ -305,20 +305,20 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
|
||||
/// Adds constraints appropriate for a nominal type (enum, struct,
|
||||
/// object, etc) appearing in a context with ambient variance `variance`
|
||||
fn add_constraints_from_substs(
|
||||
fn add_constraints_from_args(
|
||||
&mut self,
|
||||
current: &CurrentItem,
|
||||
def_id: DefId,
|
||||
substs: SubstsRef<'tcx>,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
variance: VarianceTermPtr<'a>,
|
||||
) {
|
||||
debug!(
|
||||
"add_constraints_from_substs(def_id={:?}, substs={:?}, variance={:?})",
|
||||
def_id, substs, variance
|
||||
"add_constraints_from_args(def_id={:?}, args={:?}, variance={:?})",
|
||||
def_id, args, variance
|
||||
);
|
||||
|
||||
// We don't record `inferred_starts` entries for empty generics.
|
||||
if substs.is_empty() {
|
||||
if args.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -328,7 +328,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
(None, Some(self.tcx().variances_of(def_id)))
|
||||
};
|
||||
|
||||
for (i, k) in substs.iter().enumerate() {
|
||||
for (i, k) in args.iter().enumerate() {
|
||||
let variance_decl = if let Some(InferredIndex(start)) = local {
|
||||
// Parameter on an item defined within current crate:
|
||||
// variance not yet inferred, so return a symbolic
|
||||
|
@ -341,7 +341,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
};
|
||||
let variance_i = self.xform(variance, variance_decl);
|
||||
debug!(
|
||||
"add_constraints_from_substs: variance_decl={:?} variance_i={:?}",
|
||||
"add_constraints_from_args: variance_decl={:?} variance_i={:?}",
|
||||
variance_decl, variance_i
|
||||
);
|
||||
match k.unpack() {
|
||||
|
@ -368,7 +368,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
|
||||
match &c.kind() {
|
||||
ty::ConstKind::Unevaluated(uv) => {
|
||||
self.add_constraints_from_invariant_substs(current, uv.substs, variance);
|
||||
self.add_constraints_from_invariant_args(current, uv.args, variance);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use rustc_arena::DroplessArena;
|
|||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::{self, CrateVariancesMap, SubstsRef, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, CrateVariancesMap, GenericArgsRef, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable};
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
|
@ -83,17 +83,17 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
|
|||
|
||||
impl<'tcx> OpaqueTypeLifetimeCollector<'tcx> {
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
fn visit_opaque(&mut self, def_id: DefId, substs: SubstsRef<'tcx>) -> ControlFlow<!> {
|
||||
fn visit_opaque(&mut self, def_id: DefId, args: GenericArgsRef<'tcx>) -> ControlFlow<!> {
|
||||
if def_id != self.root_def_id && self.tcx.is_descendant_of(def_id, self.root_def_id) {
|
||||
let child_variances = self.tcx.variances_of(def_id);
|
||||
for (a, v) in substs.iter().zip(child_variances) {
|
||||
for (a, v) in args.iter().zip(child_variances) {
|
||||
if *v != ty::Bivariant {
|
||||
a.visit_with(self)?;
|
||||
}
|
||||
}
|
||||
ControlFlow::Continue(())
|
||||
} else {
|
||||
substs.visit_with(self)
|
||||
args.visit_with(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -110,10 +110,10 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
|
|||
#[instrument(level = "trace", skip(self), ret)]
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
match t.kind() {
|
||||
ty::Alias(_, ty::AliasTy { def_id, substs, .. })
|
||||
ty::Alias(_, ty::AliasTy { def_id, args, .. })
|
||||
if matches!(self.tcx.def_kind(*def_id), DefKind::OpaqueTy) =>
|
||||
{
|
||||
self.visit_opaque(*def_id, substs)
|
||||
self.visit_opaque(*def_id, args)
|
||||
}
|
||||
_ => t.super_visit_with(self),
|
||||
}
|
||||
|
@ -144,30 +144,30 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
|
|||
|
||||
let mut collector =
|
||||
OpaqueTypeLifetimeCollector { tcx, root_def_id: item_def_id.to_def_id(), variances };
|
||||
let id_substs = ty::InternalSubsts::identity_for_item(tcx, item_def_id);
|
||||
for (pred, _) in tcx.explicit_item_bounds(item_def_id).subst_iter_copied(tcx, id_substs) {
|
||||
let id_args = ty::GenericArgs::identity_for_item(tcx, item_def_id);
|
||||
for (pred, _) in tcx.explicit_item_bounds(item_def_id).arg_iter_copied(tcx, id_args) {
|
||||
debug!(?pred);
|
||||
|
||||
// We only ignore opaque type substs if the opaque type is the outermost type.
|
||||
// We only ignore opaque type args if the opaque type is the outermost type.
|
||||
// The opaque type may be nested within itself via recursion in e.g.
|
||||
// type Foo<'a> = impl PartialEq<Foo<'a>>;
|
||||
// which thus mentions `'a` and should thus accept hidden types that borrow 'a
|
||||
// instead of requiring an additional `+ 'a`.
|
||||
match pred.kind().skip_binder() {
|
||||
ty::ClauseKind::Trait(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef { def_id: _, substs, .. },
|
||||
trait_ref: ty::TraitRef { def_id: _, args, .. },
|
||||
constness: _,
|
||||
polarity: _,
|
||||
}) => {
|
||||
for subst in &substs[1..] {
|
||||
for subst in &args[1..] {
|
||||
subst.visit_with(&mut collector);
|
||||
}
|
||||
}
|
||||
ty::ClauseKind::Projection(ty::ProjectionPredicate {
|
||||
projection_ty: ty::AliasTy { substs, .. },
|
||||
projection_ty: ty::AliasTy { args, .. },
|
||||
term,
|
||||
}) => {
|
||||
for subst in &substs[1..] {
|
||||
for subst in &args[1..] {
|
||||
subst.visit_with(&mut collector);
|
||||
}
|
||||
term.visit_with(&mut collector);
|
||||
|
|
|
@ -103,7 +103,7 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
|
|||
self.enforce_const_invariance(generics, variances);
|
||||
|
||||
// Functions are permitted to have unused generic parameters: make those invariant.
|
||||
if let ty::FnDef(..) = tcx.type_of(def_id).subst_identity().kind() {
|
||||
if let ty::FnDef(..) = tcx.type_of(def_id).instantiate_identity().kind() {
|
||||
for variance in variances.iter_mut() {
|
||||
if *variance == ty::Bivariant {
|
||||
*variance = ty::Invariant;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue