mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
refactor(rustc_middle): Substs -> GenericArg
This commit is contained in:
parent
df5c2cf9bc
commit
e55583c4b8
@ -7,8 +7,8 @@ use rustc_middle::mir::{
|
||||
Body, Local, Location, Place, PlaceRef, ProjectionElem, Rvalue, SourceInfo, Statement,
|
||||
StatementKind, Terminator, TerminatorKind, UserTypeProjection,
|
||||
};
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::visit::TypeVisitable;
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
|
||||
|
||||
use crate::{
|
||||
@ -49,11 +49,11 @@ struct ConstraintGeneration<'cg, 'tcx> {
|
||||
}
|
||||
|
||||
impl<'cg, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'tcx> {
|
||||
/// We sometimes have `substs` within an rvalue, or within a
|
||||
/// We sometimes have `args` within an rvalue, or within a
|
||||
/// call. Make them live at the location where they appear.
|
||||
fn visit_substs(&mut self, substs: &SubstsRef<'tcx>, location: Location) {
|
||||
self.add_regular_live_constraint(*substs, location);
|
||||
self.super_substs(substs);
|
||||
fn visit_args(&mut self, args: &GenericArgsRef<'tcx>, location: Location) {
|
||||
self.add_regular_live_constraint(*args, location);
|
||||
self.super_args(args);
|
||||
}
|
||||
|
||||
/// We sometimes have `region` within an rvalue, or within a
|
||||
|
@ -702,11 +702,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
.iter()
|
||||
.copied()
|
||||
.find_map(find_fn_kind_from_did),
|
||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => tcx
|
||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => tcx
|
||||
.explicit_item_bounds(def_id)
|
||||
.subst_iter_copied(tcx, substs)
|
||||
.arg_iter_copied(tcx, args)
|
||||
.find_map(|(clause, span)| find_fn_kind_from_did((clause, span))),
|
||||
ty::Closure(_, substs) => match substs.as_closure().kind() {
|
||||
ty::Closure(_, args) => match args.as_closure().kind() {
|
||||
ty::ClosureKind::Fn => Some(hir::Mutability::Not),
|
||||
ty::ClosureKind::FnMut => Some(hir::Mutability::Mut),
|
||||
_ => None,
|
||||
@ -1448,11 +1448,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
}
|
||||
|
||||
// Get closure's arguments
|
||||
let ty::Closure(_, substs) = typeck_results.expr_ty(closure_expr).kind() else {
|
||||
let ty::Closure(_, args) = typeck_results.expr_ty(closure_expr).kind() else {
|
||||
/* hir::Closure can be a generator too */
|
||||
return;
|
||||
};
|
||||
let sig = substs.as_closure().sig();
|
||||
let sig = args.as_closure().sig();
|
||||
let tupled_params =
|
||||
tcx.erase_late_bound_regions(sig.inputs().iter().next().unwrap().map_bound(|&b| b));
|
||||
let ty::Tuple(params) = tupled_params.kind() else { return };
|
||||
@ -2676,7 +2676,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
kind: TerminatorKind::Call { call_source: CallSource::OverloadedOperator, .. },
|
||||
..
|
||||
}),
|
||||
Some((method_did, method_substs)),
|
||||
Some((method_did, method_args)),
|
||||
) = (
|
||||
&self.body[loan.reserve_location.block].terminator,
|
||||
rustc_middle::util::find_self_call(
|
||||
@ -2689,7 +2689,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
if tcx.is_diagnostic_item(sym::deref_method, method_did) {
|
||||
let deref_target =
|
||||
tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| {
|
||||
Instance::resolve(tcx, self.param_env, deref_target, method_substs)
|
||||
Instance::resolve(tcx, self.param_env, deref_target, method_args)
|
||||
.transpose()
|
||||
});
|
||||
if let Some(Ok(instance)) = deref_target {
|
||||
@ -2856,11 +2856,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
if is_closure {
|
||||
None
|
||||
} else {
|
||||
let ty = self.infcx.tcx.type_of(self.mir_def_id()).subst_identity();
|
||||
let ty = self.infcx.tcx.type_of(self.mir_def_id()).instantiate_identity();
|
||||
match ty.kind() {
|
||||
ty::FnDef(_, _) | ty::FnPtr(_) => self.annotate_fn_sig(
|
||||
self.mir_def_id(),
|
||||
self.infcx.tcx.fn_sig(self.mir_def_id()).subst_identity(),
|
||||
self.infcx.tcx.fn_sig(self.mir_def_id()).instantiate_identity(),
|
||||
),
|
||||
_ => None,
|
||||
}
|
||||
@ -2902,7 +2902,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
);
|
||||
// Check if our `target` was captured by a closure.
|
||||
if let Rvalue::Aggregate(
|
||||
box AggregateKind::Closure(def_id, substs),
|
||||
box AggregateKind::Closure(def_id, args),
|
||||
operands,
|
||||
) = rvalue
|
||||
{
|
||||
@ -2933,7 +2933,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
// into a place then we should annotate the closure in
|
||||
// case it ends up being assigned into the return place.
|
||||
annotated_closure =
|
||||
self.annotate_fn_sig(def_id, substs.as_closure().sig());
|
||||
self.annotate_fn_sig(def_id, args.as_closure().sig());
|
||||
debug!(
|
||||
"annotate_argument_and_return_for_borrow: \
|
||||
annotated_closure={:?} assigned_from_local={:?} \
|
||||
|
@ -168,17 +168,17 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
||||
let local_decl = &body.local_decls[dropped_local];
|
||||
let mut ty = local_decl.ty;
|
||||
if local_decl.source_info.span.desugaring_kind() == Some(DesugaringKind::ForLoop) {
|
||||
if let ty::Adt(adt, substs) = local_decl.ty.kind() {
|
||||
if let ty::Adt(adt, args) = local_decl.ty.kind() {
|
||||
if tcx.is_diagnostic_item(sym::Option, adt.did()) {
|
||||
// in for loop desugaring, only look at the `Some(..)` inner type
|
||||
ty = substs.type_at(0);
|
||||
ty = args.type_at(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
let (dtor_desc, type_desc) = match ty.kind() {
|
||||
// If type is an ADT that implements Drop, then
|
||||
// simplify output by reporting just the ADT name.
|
||||
ty::Adt(adt, _substs) if adt.has_dtor(tcx) && !adt.is_box() => {
|
||||
ty::Adt(adt, _args) if adt.has_dtor(tcx) && !adt.is_box() => {
|
||||
("`Drop` code", format!("type `{}`", tcx.def_path_str(adt.did())))
|
||||
}
|
||||
|
||||
|
@ -732,18 +732,18 @@ impl<'tcx> BorrowedContentSource<'tcx> {
|
||||
|
||||
fn from_call(func: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Option<Self> {
|
||||
match *func.kind() {
|
||||
ty::FnDef(def_id, substs) => {
|
||||
ty::FnDef(def_id, args) => {
|
||||
let trait_id = tcx.trait_of_item(def_id)?;
|
||||
|
||||
let lang_items = tcx.lang_items();
|
||||
if Some(trait_id) == lang_items.deref_trait()
|
||||
|| Some(trait_id) == lang_items.deref_mut_trait()
|
||||
{
|
||||
Some(BorrowedContentSource::OverloadedDeref(substs.type_at(0)))
|
||||
Some(BorrowedContentSource::OverloadedDeref(args.type_at(0)))
|
||||
} else if Some(trait_id) == lang_items.index_trait()
|
||||
|| Some(trait_id) == lang_items.index_mut_trait()
|
||||
{
|
||||
Some(BorrowedContentSource::OverloadedIndex(substs.type_at(0)))
|
||||
Some(BorrowedContentSource::OverloadedIndex(args.type_at(0)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -847,7 +847,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
kind: TerminatorKind::Call { fn_span, call_source, .. }, ..
|
||||
}) = &self.body[location.block].terminator
|
||||
{
|
||||
let Some((method_did, method_substs)) = rustc_middle::util::find_self_call(
|
||||
let Some((method_did, method_args)) = rustc_middle::util::find_self_call(
|
||||
self.infcx.tcx,
|
||||
&self.body,
|
||||
target_temp,
|
||||
@ -860,7 +860,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
self.infcx.tcx,
|
||||
self.param_env,
|
||||
method_did,
|
||||
method_substs,
|
||||
method_args,
|
||||
*fn_span,
|
||||
call_source.from_hir_call(),
|
||||
Some(self.infcx.tcx.fn_arg_names(method_did)[0]),
|
||||
@ -1039,7 +1039,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
});
|
||||
}
|
||||
}
|
||||
CallKind::Normal { self_arg, desugaring, method_did, method_substs } => {
|
||||
CallKind::Normal { self_arg, desugaring, method_did, method_args } => {
|
||||
let self_arg = self_arg.unwrap();
|
||||
let tcx = self.infcx.tcx;
|
||||
if let Some((CallDesugaringKind::ForLoopIntoIter, _)) = desugaring {
|
||||
@ -1106,13 +1106,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
// Erase and shadow everything that could be passed to the new infcx.
|
||||
let ty = moved_place.ty(self.body, tcx).ty;
|
||||
|
||||
if let ty::Adt(def, substs) = ty.kind()
|
||||
if let ty::Adt(def, args) = ty.kind()
|
||||
&& Some(def.did()) == tcx.lang_items().pin_type()
|
||||
&& let ty::Ref(_, _, hir::Mutability::Mut) = substs.type_at(0).kind()
|
||||
&& let ty::Ref(_, _, hir::Mutability::Mut) = args.type_at(0).kind()
|
||||
&& let self_ty = self.infcx.instantiate_binder_with_fresh_vars(
|
||||
fn_call_span,
|
||||
LateBoundRegionConversionTime::FnCall,
|
||||
tcx.fn_sig(method_did).subst(tcx, method_substs).input(0),
|
||||
tcx.fn_sig(method_did).instantiate(tcx, method_args).input(0),
|
||||
)
|
||||
&& self.infcx.can_eq(self.param_env, ty, self_ty)
|
||||
{
|
||||
@ -1161,7 +1161,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
let parent_self_ty =
|
||||
matches!(tcx.def_kind(parent_did), rustc_hir::def::DefKind::Impl { .. })
|
||||
.then_some(parent_did)
|
||||
.and_then(|did| match tcx.type_of(did).subst_identity().kind() {
|
||||
.and_then(|did| match tcx.type_of(did).instantiate_identity().kind() {
|
||||
ty::Adt(def, ..) => Some(def.did()),
|
||||
_ => None,
|
||||
});
|
||||
|
@ -324,10 +324,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
ty::Array(..) | ty::Slice(..) => {
|
||||
self.cannot_move_out_of_interior_noncopy(span, ty, None)
|
||||
}
|
||||
ty::Closure(def_id, closure_substs)
|
||||
ty::Closure(def_id, closure_args)
|
||||
if def_id.as_local() == Some(self.mir_def_id()) && upvar_field.is_some() =>
|
||||
{
|
||||
let closure_kind_ty = closure_substs.as_closure().kind_ty();
|
||||
let closure_kind_ty = closure_args.as_closure().kind_ty();
|
||||
let closure_kind = match closure_kind_ty.to_opt_closure_kind() {
|
||||
Some(kind @ (ty::ClosureKind::Fn | ty::ClosureKind::FnMut)) => kind,
|
||||
Some(ty::ClosureKind::FnOnce) => {
|
||||
|
@ -22,7 +22,7 @@ use rustc_infer::infer::{
|
||||
};
|
||||
use rustc_middle::hir::place::PlaceBase;
|
||||
use rustc_middle::mir::{ConstraintCategory, ReturnConstraint};
|
||||
use rustc_middle::ty::subst::InternalSubsts;
|
||||
use rustc_middle::ty::GenericArgs;
|
||||
use rustc_middle::ty::TypeVisitor;
|
||||
use rustc_middle::ty::{self, RegionVid, Ty};
|
||||
use rustc_middle::ty::{Region, TyCtxt};
|
||||
@ -183,9 +183,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
fn is_closure_fn_mut(&self, fr: RegionVid) -> bool {
|
||||
if let Some(ty::ReFree(free_region)) = self.to_error_region(fr).as_deref()
|
||||
&& let ty::BoundRegionKind::BrEnv = free_region.bound_region
|
||||
&& let DefiningTy::Closure(_, substs) = self.regioncx.universal_regions().defining_ty
|
||||
&& let DefiningTy::Closure(_, args) = self.regioncx.universal_regions().defining_ty
|
||||
{
|
||||
return substs.as_closure().kind() == ty::ClosureKind::FnMut;
|
||||
return args.as_closure().kind() == ty::ClosureKind::FnMut;
|
||||
}
|
||||
|
||||
false
|
||||
@ -502,12 +502,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
.to_string(),
|
||||
)
|
||||
}
|
||||
ty::Adt(adt, substs) => {
|
||||
let generic_arg = substs[param_index as usize];
|
||||
let identity_substs =
|
||||
InternalSubsts::identity_for_item(self.infcx.tcx, adt.did());
|
||||
let base_ty = Ty::new_adt(self.infcx.tcx, *adt, identity_substs);
|
||||
let base_generic_arg = identity_substs[param_index as usize];
|
||||
ty::Adt(adt, args) => {
|
||||
let generic_arg = args[param_index as usize];
|
||||
let identity_args =
|
||||
GenericArgs::identity_for_item(self.infcx.tcx, adt.did());
|
||||
let base_ty = Ty::new_adt(self.infcx.tcx, *adt, identity_args);
|
||||
let base_generic_arg = identity_args[param_index as usize];
|
||||
let adt_desc = adt.descr();
|
||||
|
||||
let desc = format!(
|
||||
@ -520,12 +520,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
}
|
||||
ty::FnDef(def_id, _) => {
|
||||
let name = self.infcx.tcx.item_name(*def_id);
|
||||
let identity_substs =
|
||||
InternalSubsts::identity_for_item(self.infcx.tcx, *def_id);
|
||||
let identity_args = GenericArgs::identity_for_item(self.infcx.tcx, *def_id);
|
||||
let desc = format!("a function pointer to `{name}`");
|
||||
let note = format!(
|
||||
"the function `{name}` is invariant over the parameter `{}`",
|
||||
identity_substs[param_index as usize]
|
||||
identity_args[param_index as usize]
|
||||
);
|
||||
(desc, note)
|
||||
}
|
||||
@ -573,7 +572,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
|
||||
let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty;
|
||||
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *output_ty.kind() {
|
||||
output_ty = self.infcx.tcx.type_of(def_id).subst_identity()
|
||||
output_ty = self.infcx.tcx.type_of(def_id).instantiate_identity()
|
||||
};
|
||||
|
||||
debug!("report_fnmut_error: output_ty={:?}", output_ty);
|
||||
@ -899,14 +898,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
let tcx = self.infcx.tcx;
|
||||
|
||||
let instance = if let ConstraintCategory::CallArgument(Some(func_ty)) = category {
|
||||
let (fn_did, substs) = match func_ty.kind() {
|
||||
ty::FnDef(fn_did, substs) => (fn_did, substs),
|
||||
let (fn_did, args) = match func_ty.kind() {
|
||||
ty::FnDef(fn_did, args) => (fn_did, args),
|
||||
_ => return,
|
||||
};
|
||||
debug!(?fn_did, ?substs);
|
||||
debug!(?fn_did, ?args);
|
||||
|
||||
// Only suggest this on function calls, not closures
|
||||
let ty = tcx.type_of(fn_did).subst_identity();
|
||||
let ty = tcx.type_of(fn_did).instantiate_identity();
|
||||
debug!("ty: {:?}, ty.kind: {:?}", ty, ty.kind());
|
||||
if let ty::Closure(_, _) = ty.kind() {
|
||||
return;
|
||||
@ -916,7 +915,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
tcx,
|
||||
self.param_env,
|
||||
*fn_did,
|
||||
self.infcx.resolve_vars_if_possible(substs),
|
||||
self.infcx.resolve_vars_if_possible(args),
|
||||
) {
|
||||
instance
|
||||
} else {
|
||||
|
@ -5,8 +5,8 @@ use rustc_errors::Diagnostic;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_middle::ty::print::RegionHighlightMode;
|
||||
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
|
||||
use rustc_middle::ty::{self, RegionVid, Ty};
|
||||
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
@ -321,7 +321,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||
ty::BoundRegionKind::BrEnv => {
|
||||
let def_ty = self.regioncx.universal_regions().defining_ty;
|
||||
|
||||
let DefiningTy::Closure(_, substs) = def_ty else {
|
||||
let DefiningTy::Closure(_, args) = def_ty else {
|
||||
// Can't have BrEnv in functions, constants or generators.
|
||||
bug!("BrEnv outside of closure.");
|
||||
};
|
||||
@ -332,7 +332,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||
};
|
||||
let region_name = self.synthesize_region_name();
|
||||
|
||||
let closure_kind_ty = substs.as_closure().kind_ty();
|
||||
let closure_kind_ty = args.as_closure().kind_ty();
|
||||
let note = match closure_kind_ty.to_opt_closure_kind() {
|
||||
Some(ty::ClosureKind::Fn) => {
|
||||
"closure implements `Fn`, so references to captured variables \
|
||||
@ -510,10 +510,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||
}
|
||||
|
||||
// Match up something like `Foo<'1>`
|
||||
(
|
||||
ty::Adt(_adt_def, substs),
|
||||
hir::TyKind::Path(hir::QPath::Resolved(None, path)),
|
||||
) => {
|
||||
(ty::Adt(_adt_def, args), hir::TyKind::Path(hir::QPath::Resolved(None, path))) => {
|
||||
match path.res {
|
||||
// Type parameters of the type alias have no reason to
|
||||
// be the same as those of the ADT.
|
||||
@ -523,7 +520,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||
_ => {
|
||||
if let Some(last_segment) = path.segments.last() {
|
||||
if let Some(highlight) = self.match_adt_and_segment(
|
||||
substs,
|
||||
args,
|
||||
needle_fr,
|
||||
last_segment,
|
||||
search_stack,
|
||||
@ -560,22 +557,22 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||
None
|
||||
}
|
||||
|
||||
/// We've found an enum/struct/union type with the substitutions
|
||||
/// `substs` and -- in the HIR -- a path type with the final
|
||||
/// We've found an enum/struct/union type with the generic args
|
||||
/// `args` and -- in the HIR -- a path type with the final
|
||||
/// segment `last_segment`. Try to find a `'_` to highlight in
|
||||
/// the generic args (or, if not, to produce new zipped pairs of
|
||||
/// types+hir to search through).
|
||||
fn match_adt_and_segment<'hir>(
|
||||
&self,
|
||||
substs: SubstsRef<'tcx>,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
needle_fr: RegionVid,
|
||||
last_segment: &'hir hir::PathSegment<'hir>,
|
||||
search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty<'hir>)>,
|
||||
) -> Option<RegionNameHighlight> {
|
||||
// Did the user give explicit arguments? (e.g., `Foo<..>`)
|
||||
let args = last_segment.args.as_ref()?;
|
||||
let explicit_args = last_segment.args.as_ref()?;
|
||||
let lifetime =
|
||||
self.try_match_adt_and_generic_args(substs, needle_fr, args, search_stack)?;
|
||||
self.try_match_adt_and_generic_args(args, needle_fr, explicit_args, search_stack)?;
|
||||
if lifetime.is_anonymous() {
|
||||
None
|
||||
} else {
|
||||
@ -583,19 +580,19 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// We've found an enum/struct/union type with the substitutions
|
||||
/// `substs` and -- in the HIR -- a path with the generic
|
||||
/// arguments `args`. If `needle_fr` appears in the args, return
|
||||
/// We've found an enum/struct/union type with the generic args
|
||||
/// `args` and -- in the HIR -- a path with the generic
|
||||
/// arguments `hir_args`. If `needle_fr` appears in the args, return
|
||||
/// the `hir::Lifetime` that corresponds to it. If not, push onto
|
||||
/// `search_stack` the types+hir to search through.
|
||||
fn try_match_adt_and_generic_args<'hir>(
|
||||
&self,
|
||||
substs: SubstsRef<'tcx>,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
needle_fr: RegionVid,
|
||||
args: &'hir hir::GenericArgs<'hir>,
|
||||
hir_args: &'hir hir::GenericArgs<'hir>,
|
||||
search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty<'hir>)>,
|
||||
) -> Option<&'hir hir::Lifetime> {
|
||||
for (kind, hir_arg) in iter::zip(substs, args.args) {
|
||||
for (kind, hir_arg) in iter::zip(args, hir_args.args) {
|
||||
match (kind.unpack(), hir_arg) {
|
||||
(GenericArgKind::Lifetime(r), hir::GenericArg::Lifetime(lt)) => {
|
||||
if r.as_var() == needle_fr {
|
||||
@ -849,9 +846,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||
return None;
|
||||
};
|
||||
|
||||
let found = tcx.any_free_region_meets(&tcx.type_of(region_parent).subst_identity(), |r| {
|
||||
*r == ty::ReEarlyBound(region)
|
||||
});
|
||||
let found = tcx
|
||||
.any_free_region_meets(&tcx.type_of(region_parent).instantiate_identity(), |r| {
|
||||
*r == ty::ReEarlyBound(region)
|
||||
});
|
||||
|
||||
Some(RegionName {
|
||||
name: self.synthesize_region_name(),
|
||||
|
@ -301,7 +301,7 @@ fn do_mir_borrowck<'tcx>(
|
||||
let movable_generator =
|
||||
// The first argument is the generator type passed by value
|
||||
if let Some(local) = body.local_decls.raw.get(1)
|
||||
// Get the interior types and substs which typeck computed
|
||||
// Get the interior types and args which typeck computed
|
||||
&& let ty::Generator(_, _, hir::Movability::Static) = local.ty.kind()
|
||||
{
|
||||
false
|
||||
|
@ -1115,7 +1115,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
) -> Option<ClosureOutlivesSubject<'tcx>> {
|
||||
let tcx = infcx.tcx;
|
||||
|
||||
// Opaque types' substs may include useless lifetimes.
|
||||
// Opaque types' args may include useless lifetimes.
|
||||
// We will replace them with ReStatic.
|
||||
struct OpaqueFolder<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
@ -1127,19 +1127,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
use ty::TypeSuperFoldable as _;
|
||||
let tcx = self.tcx;
|
||||
let &ty::Alias(ty::Opaque, ty::AliasTy { substs, def_id, .. }) = t.kind() else {
|
||||
let &ty::Alias(ty::Opaque, ty::AliasTy { args, def_id, .. }) = t.kind() else {
|
||||
return t.super_fold_with(self);
|
||||
};
|
||||
let substs =
|
||||
std::iter::zip(substs, tcx.variances_of(def_id)).map(|(arg, v)| {
|
||||
match (arg.unpack(), v) {
|
||||
(ty::GenericArgKind::Lifetime(_), ty::Bivariant) => {
|
||||
tcx.lifetimes.re_static.into()
|
||||
}
|
||||
_ => arg.fold_with(self),
|
||||
let args = std::iter::zip(args, tcx.variances_of(def_id)).map(|(arg, v)| {
|
||||
match (arg.unpack(), v) {
|
||||
(ty::GenericArgKind::Lifetime(_), ty::Bivariant) => {
|
||||
tcx.lifetimes.re_static.into()
|
||||
}
|
||||
});
|
||||
Ty::new_opaque(tcx, def_id, tcx.mk_substs_from_iter(substs))
|
||||
_ => arg.fold_with(self),
|
||||
}
|
||||
});
|
||||
Ty::new_opaque(tcx, def_id, tcx.mk_args_from_iter(args))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,9 +6,9 @@ use rustc_infer::infer::InferCtxt;
|
||||
use rustc_infer::infer::TyCtxtInferExt as _;
|
||||
use rustc_infer::traits::{Obligation, ObligationCause};
|
||||
use rustc_middle::traits::DefiningAnchor;
|
||||
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
|
||||
use rustc_middle::ty::visit::TypeVisitableExt;
|
||||
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_middle::ty::{GenericArgKind, GenericArgs};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::traits::ObligationCtxt;
|
||||
@ -38,15 +38,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
/// back to concrete lifetimes: `'static`, `ReEarlyBound` or `ReFree`.
|
||||
///
|
||||
/// First we map all the lifetimes in the concrete type to an equal
|
||||
/// universal region that occurs in the concrete type's substs, in this case
|
||||
/// this would result in `&'1 i32`. We only consider regions in the substs
|
||||
/// universal region that occurs in the concrete type's args, in this case
|
||||
/// this would result in `&'1 i32`. We only consider regions in the args
|
||||
/// in case there is an equal region that does not. For example, this should
|
||||
/// be allowed:
|
||||
/// `fn f<'a: 'b, 'b: 'a>(x: *mut &'b i32) -> impl Sized + 'a { x }`
|
||||
///
|
||||
/// Then we map the regions in both the type and the subst to their
|
||||
/// `external_name` giving `concrete_type = &'a i32`,
|
||||
/// `substs = ['static, 'a]`. This will then allow
|
||||
/// `args = ['static, 'a]`. This will then allow
|
||||
/// `infer_opaque_definition_from_instantiation` to determine that
|
||||
/// `_Return<'_a> = &'_a i32`.
|
||||
///
|
||||
@ -73,8 +73,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
debug!(?member_constraints);
|
||||
|
||||
for (opaque_type_key, concrete_type) in opaque_ty_decls {
|
||||
let substs = opaque_type_key.substs;
|
||||
debug!(?concrete_type, ?substs);
|
||||
let args = opaque_type_key.args;
|
||||
debug!(?concrete_type, ?args);
|
||||
|
||||
let mut subst_regions = vec![self.universal_regions.fr_static];
|
||||
|
||||
@ -95,7 +95,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
ty::Region::new_error_with_message(
|
||||
infcx.tcx,
|
||||
concrete_type.span,
|
||||
"opaque type with non-universal region substs",
|
||||
"opaque type with non-universal region args",
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -110,17 +110,17 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
}
|
||||
debug!(?subst_regions);
|
||||
|
||||
// Next, insert universal regions from substs, so we can translate regions that appear
|
||||
// in them but are not subject to member constraints, for instance closure substs.
|
||||
let universal_substs = infcx.tcx.fold_regions(substs, |region, _| {
|
||||
// Next, insert universal regions from args, so we can translate regions that appear
|
||||
// in them but are not subject to member constraints, for instance closure args.
|
||||
let universal_args = infcx.tcx.fold_regions(args, |region, _| {
|
||||
if let ty::RePlaceholder(..) = region.kind() {
|
||||
// Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs.
|
||||
// Higher kinded regions don't need remapping, they don't refer to anything outside of this the args.
|
||||
return region;
|
||||
}
|
||||
let vid = self.to_region_vid(region);
|
||||
to_universal_region(vid, &mut subst_regions)
|
||||
});
|
||||
debug!(?universal_substs);
|
||||
debug!(?universal_args);
|
||||
debug!(?subst_regions);
|
||||
|
||||
// Deduplicate the set of regions while keeping the chosen order.
|
||||
@ -139,7 +139,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
debug!(?universal_concrete_type);
|
||||
|
||||
let opaque_type_key =
|
||||
OpaqueTypeKey { def_id: opaque_type_key.def_id, substs: universal_substs };
|
||||
OpaqueTypeKey { def_id: opaque_type_key.def_id, args: universal_args };
|
||||
let ty = infcx.infer_opaque_definition_from_instantiation(
|
||||
opaque_type_key,
|
||||
universal_concrete_type,
|
||||
@ -175,7 +175,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
|
||||
/// Map the regions in the type to named regions. This is similar to what
|
||||
/// `infer_opaque_types` does, but can infer any universal region, not only
|
||||
/// ones from the substs for the opaque type. It also doesn't double check
|
||||
/// ones from the args for the opaque type. It also doesn't double check
|
||||
/// that the regions produced are in fact equal to the named region they are
|
||||
/// replaced with. This is fine because this function is only to improve the
|
||||
/// region names in error messages.
|
||||
@ -238,7 +238,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
/// # Parameters
|
||||
///
|
||||
/// - `def_id`, the `impl Trait` type
|
||||
/// - `substs`, the substs used to instantiate this opaque type
|
||||
/// - `args`, the args used to instantiate this opaque type
|
||||
/// - `instantiated_ty`, the inferred type C1 -- fully resolved, lifted version of
|
||||
/// `opaque_defn.concrete_ty`
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
@ -309,11 +309,11 @@ fn check_opaque_type_well_formed<'tcx>(
|
||||
})
|
||||
.build();
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
let identity_substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
let identity_args = GenericArgs::identity_for_item(tcx, def_id);
|
||||
|
||||
// Require that the hidden type actually fulfills all the bounds of the opaque type, even without
|
||||
// the bounds that the function supplies.
|
||||
let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), identity_substs);
|
||||
let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), identity_args);
|
||||
ocx.eq(&ObligationCause::misc(definition_span, def_id), param_env, opaque_ty, definition_ty)
|
||||
.map_err(|err| {
|
||||
infcx
|
||||
@ -384,7 +384,7 @@ fn check_opaque_type_parameter_valid(
|
||||
}
|
||||
let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
|
||||
let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default();
|
||||
for (i, arg) in opaque_type_key.substs.iter().enumerate() {
|
||||
for (i, arg) in opaque_type_key.args.iter().enumerate() {
|
||||
let arg_is_param = match arg.unpack() {
|
||||
GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)),
|
||||
GenericArgKind::Lifetime(lt) => {
|
||||
|
@ -6,7 +6,7 @@ use rustc_infer::infer::NllRegionVariableOrigin;
|
||||
use rustc_middle::mir::visit::{MutVisitor, TyContext};
|
||||
use rustc_middle::mir::Constant;
|
||||
use rustc_middle::mir::{Body, Location, Promoted};
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
||||
@ -94,10 +94,10 @@ impl<'a, 'tcx> MutVisitor<'tcx> for RegionRenumberer<'a, 'tcx> {
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, location: Location) {
|
||||
*substs = self.renumber_regions(*substs, || RegionCtxt::Location(location));
|
||||
fn visit_args(&mut self, args: &mut GenericArgsRef<'tcx>, location: Location) {
|
||||
*args = self.renumber_regions(*args, || RegionCtxt::Location(location));
|
||||
|
||||
debug!(?substs);
|
||||
debug!(?args);
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
|
@ -5,7 +5,7 @@ use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelega
|
||||
use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
|
||||
use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
|
||||
use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
|
||||
use rustc_middle::ty::subst::GenericArgKind;
|
||||
use rustc_middle::ty::GenericArgKind;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_middle::ty::{TypeFoldable, TypeVisitableExt};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
@ -89,20 +89,20 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
|
||||
|
||||
/// Given an instance of the closure type, this method instantiates the "extra" requirements
|
||||
/// that we computed for the closure. This has the effect of adding new outlives obligations
|
||||
/// to existing region variables in `closure_substs`.
|
||||
/// to existing region variables in `closure_args`.
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
pub fn apply_closure_requirements(
|
||||
&mut self,
|
||||
closure_requirements: &ClosureRegionRequirements<'tcx>,
|
||||
closure_def_id: DefId,
|
||||
closure_substs: ty::SubstsRef<'tcx>,
|
||||
closure_args: ty::GenericArgsRef<'tcx>,
|
||||
) {
|
||||
// Extract the values of the free regions in `closure_substs`
|
||||
// Extract the values of the free regions in `closure_args`
|
||||
// into a vector. These are the regions that we will be
|
||||
// relating to one another.
|
||||
let closure_mapping = &UniversalRegions::closure_mapping(
|
||||
self.tcx,
|
||||
closure_substs,
|
||||
closure_args,
|
||||
closure_requirements.num_external_vids,
|
||||
closure_def_id.expect_local(),
|
||||
);
|
||||
|
@ -2,7 +2,7 @@ use crate::def_use::{self, DefUse};
|
||||
use crate::location::{LocationIndex, LocationTable};
|
||||
use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
|
||||
use rustc_middle::mir::{Body, Local, Location, Place};
|
||||
use rustc_middle::ty::subst::GenericArg;
|
||||
use rustc_middle::ty::GenericArg;
|
||||
use rustc_mir_dataflow::move_paths::{LookupResult, MoveData, MovePathIndex};
|
||||
|
||||
use super::TypeChecker;
|
||||
|
@ -30,12 +30,12 @@ use rustc_middle::traits::query::NoSolution;
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||
use rustc_middle::ty::cast::CastTy;
|
||||
use rustc_middle::ty::subst::{SubstsRef, UserSubsts};
|
||||
use rustc_middle::ty::visit::TypeVisitableExt;
|
||||
use rustc_middle::ty::{
|
||||
self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, Dynamic,
|
||||
OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, UserTypeAnnotationIndex,
|
||||
};
|
||||
use rustc_middle::ty::{GenericArgsRef, UserArgs};
|
||||
use rustc_span::def_id::CRATE_DEF_ID;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
@ -389,15 +389,12 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
||||
} else {
|
||||
self.cx.ascribe_user_type(
|
||||
constant.literal.ty(),
|
||||
UserType::TypeOf(
|
||||
uv.def,
|
||||
UserSubsts { substs: uv.substs, user_self_ty: None },
|
||||
),
|
||||
UserType::TypeOf(uv.def, UserArgs { args: uv.args, user_self_ty: None }),
|
||||
locations.span(&self.cx.body),
|
||||
);
|
||||
}
|
||||
} else if let Some(static_def_id) = constant.check_static_ptr(tcx) {
|
||||
let unnormalized_ty = tcx.type_of(static_def_id).subst_identity();
|
||||
let unnormalized_ty = tcx.type_of(static_def_id).instantiate_identity();
|
||||
let normalized_ty = self.cx.normalize(unnormalized_ty, locations);
|
||||
let literal_ty = constant.literal.ty().builtin_deref(true).unwrap().ty;
|
||||
|
||||
@ -411,11 +408,11 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
if let ty::FnDef(def_id, substs) = *constant.literal.ty().kind() {
|
||||
if let ty::FnDef(def_id, args) = *constant.literal.ty().kind() {
|
||||
// const_trait_impl: use a non-const param env when checking that a FnDef type is well formed.
|
||||
// this is because the well-formedness of the function does not need to be proved to have `const`
|
||||
// impls for trait bounds.
|
||||
let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs);
|
||||
let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, args);
|
||||
let prev = self.cx.param_env;
|
||||
self.cx.param_env = prev.without_const();
|
||||
self.cx.normalize_and_prove_instantiated_predicates(
|
||||
@ -666,7 +663,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||
})
|
||||
}
|
||||
ProjectionElem::Downcast(maybe_name, index) => match base_ty.kind() {
|
||||
ty::Adt(adt_def, _substs) if adt_def.is_enum() => {
|
||||
ty::Adt(adt_def, _args) if adt_def.is_enum() => {
|
||||
if index.as_usize() >= adt_def.variants().len() {
|
||||
PlaceTy::from_ty(span_mirbug_and_err!(
|
||||
self,
|
||||
@ -776,16 +773,16 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||
) -> Result<Ty<'tcx>, FieldAccessError> {
|
||||
let tcx = self.tcx();
|
||||
|
||||
let (variant, substs) = match base_ty {
|
||||
let (variant, args) = match base_ty {
|
||||
PlaceTy { ty, variant_index: Some(variant_index) } => match *ty.kind() {
|
||||
ty::Adt(adt_def, substs) => (adt_def.variant(variant_index), substs),
|
||||
ty::Generator(def_id, substs, _) => {
|
||||
let mut variants = substs.as_generator().state_tys(def_id, tcx);
|
||||
ty::Adt(adt_def, args) => (adt_def.variant(variant_index), args),
|
||||
ty::Generator(def_id, args, _) => {
|
||||
let mut variants = args.as_generator().state_tys(def_id, tcx);
|
||||
let Some(mut variant) = variants.nth(variant_index.into()) else {
|
||||
bug!(
|
||||
"variant_index of generator out of range: {:?}/{:?}",
|
||||
variant_index,
|
||||
substs.as_generator().state_tys(def_id, tcx).count()
|
||||
args.as_generator().state_tys(def_id, tcx).count()
|
||||
);
|
||||
};
|
||||
return match variant.nth(field.index()) {
|
||||
@ -796,11 +793,11 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||
_ => bug!("can't have downcast of non-adt non-generator type"),
|
||||
},
|
||||
PlaceTy { ty, variant_index: None } => match *ty.kind() {
|
||||
ty::Adt(adt_def, substs) if !adt_def.is_enum() => {
|
||||
(adt_def.variant(FIRST_VARIANT), substs)
|
||||
ty::Adt(adt_def, args) if !adt_def.is_enum() => {
|
||||
(adt_def.variant(FIRST_VARIANT), args)
|
||||
}
|
||||
ty::Closure(_, substs) => {
|
||||
return match substs
|
||||
ty::Closure(_, args) => {
|
||||
return match args
|
||||
.as_closure()
|
||||
.tupled_upvars_ty()
|
||||
.tuple_fields()
|
||||
@ -808,17 +805,17 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||
{
|
||||
Some(&ty) => Ok(ty),
|
||||
None => Err(FieldAccessError::OutOfRange {
|
||||
field_count: substs.as_closure().upvar_tys().count(),
|
||||
field_count: args.as_closure().upvar_tys().count(),
|
||||
}),
|
||||
};
|
||||
}
|
||||
ty::Generator(_, substs, _) => {
|
||||
ty::Generator(_, args, _) => {
|
||||
// Only prefix fields (upvars and current state) are
|
||||
// accessible without a variant index.
|
||||
return match substs.as_generator().prefix_tys().nth(field.index()) {
|
||||
return match args.as_generator().prefix_tys().nth(field.index()) {
|
||||
Some(ty) => Ok(ty),
|
||||
None => Err(FieldAccessError::OutOfRange {
|
||||
field_count: substs.as_generator().prefix_tys().count(),
|
||||
field_count: args.as_generator().prefix_tys().count(),
|
||||
}),
|
||||
};
|
||||
}
|
||||
@ -840,7 +837,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||
};
|
||||
|
||||
if let Some(field) = variant.fields.get(field) {
|
||||
Ok(self.cx.normalize(field.ty(tcx, substs), location))
|
||||
Ok(self.cx.normalize(field.ty(tcx, args), location))
|
||||
} else {
|
||||
Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() })
|
||||
}
|
||||
@ -1065,7 +1062,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
|
||||
ocx.infcx.add_item_bounds_for_hidden_type(
|
||||
opaque_type_key.def_id.to_def_id(),
|
||||
opaque_type_key.substs,
|
||||
opaque_type_key.args,
|
||||
cause,
|
||||
param_env,
|
||||
hidden_ty.ty,
|
||||
@ -1770,32 +1767,32 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
let tcx = self.tcx();
|
||||
|
||||
match *ak {
|
||||
AggregateKind::Adt(adt_did, variant_index, substs, _, active_field_index) => {
|
||||
AggregateKind::Adt(adt_did, variant_index, args, _, active_field_index) => {
|
||||
let def = tcx.adt_def(adt_did);
|
||||
let variant = &def.variant(variant_index);
|
||||
let adj_field_index = active_field_index.unwrap_or(field_index);
|
||||
if let Some(field) = variant.fields.get(adj_field_index) {
|
||||
Ok(self.normalize(field.ty(tcx, substs), location))
|
||||
Ok(self.normalize(field.ty(tcx, args), location))
|
||||
} else {
|
||||
Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() })
|
||||
}
|
||||
}
|
||||
AggregateKind::Closure(_, substs) => {
|
||||
match substs.as_closure().upvar_tys().nth(field_index.as_usize()) {
|
||||
AggregateKind::Closure(_, args) => {
|
||||
match args.as_closure().upvar_tys().nth(field_index.as_usize()) {
|
||||
Some(ty) => Ok(ty),
|
||||
None => Err(FieldAccessError::OutOfRange {
|
||||
field_count: substs.as_closure().upvar_tys().count(),
|
||||
field_count: args.as_closure().upvar_tys().count(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
AggregateKind::Generator(_, substs, _) => {
|
||||
AggregateKind::Generator(_, args, _) => {
|
||||
// It doesn't make sense to look at a field beyond the prefix;
|
||||
// these require a variant index, and are not initialized in
|
||||
// aggregate rvalues.
|
||||
match substs.as_generator().prefix_tys().nth(field_index.as_usize()) {
|
||||
match args.as_generator().prefix_tys().nth(field_index.as_usize()) {
|
||||
Some(ty) => Ok(ty),
|
||||
None => Err(FieldAccessError::OutOfRange {
|
||||
field_count: substs.as_generator().prefix_tys().count(),
|
||||
field_count: args.as_generator().prefix_tys().count(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
@ -1821,8 +1818,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
let def_id = uv.def;
|
||||
if tcx.def_kind(def_id) == DefKind::InlineConst {
|
||||
let def_id = def_id.expect_local();
|
||||
let predicates =
|
||||
self.prove_closure_bounds(tcx, def_id, uv.substs, location);
|
||||
let predicates = self.prove_closure_bounds(tcx, def_id, uv.args, location);
|
||||
self.normalize_and_prove_instantiated_predicates(
|
||||
def_id.to_def_id(),
|
||||
predicates,
|
||||
@ -1939,7 +1935,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
|
||||
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(unsafety)) => {
|
||||
let sig = match op.ty(body, tcx).kind() {
|
||||
ty::Closure(_, substs) => substs.as_closure().sig(),
|
||||
ty::Closure(_, args) => args.as_closure().sig(),
|
||||
_ => bug!(),
|
||||
};
|
||||
let ty_fn_ptr_from =
|
||||
@ -2591,8 +2587,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
);
|
||||
|
||||
let (def_id, instantiated_predicates) = match *aggregate_kind {
|
||||
AggregateKind::Adt(adt_did, _, substs, _, _) => {
|
||||
(adt_did, tcx.predicates_of(adt_did).instantiate(tcx, substs))
|
||||
AggregateKind::Adt(adt_did, _, args, _, _) => {
|
||||
(adt_did, tcx.predicates_of(adt_did).instantiate(tcx, args))
|
||||
}
|
||||
|
||||
// For closures, we have some **extra requirements** we
|
||||
@ -2614,9 +2610,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
// desugaring. A closure gets desugared to a struct, and
|
||||
// these extra requirements are basically like where
|
||||
// clauses on the struct.
|
||||
AggregateKind::Closure(def_id, substs)
|
||||
| AggregateKind::Generator(def_id, substs, _) => {
|
||||
(def_id, self.prove_closure_bounds(tcx, def_id.expect_local(), substs, location))
|
||||
AggregateKind::Closure(def_id, args) | AggregateKind::Generator(def_id, args, _) => {
|
||||
(def_id, self.prove_closure_bounds(tcx, def_id.expect_local(), args, location))
|
||||
}
|
||||
|
||||
AggregateKind::Array(_) | AggregateKind::Tuple => {
|
||||
@ -2635,7 +2630,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
&mut self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: LocalDefId,
|
||||
substs: SubstsRef<'tcx>,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
location: Location,
|
||||
) -> ty::InstantiatedPredicates<'tcx> {
|
||||
if let Some(closure_requirements) = &tcx.mir_borrowck(def_id).closure_requirements {
|
||||
@ -2653,26 +2648,26 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
.apply_closure_requirements(
|
||||
&closure_requirements,
|
||||
def_id.to_def_id(),
|
||||
substs,
|
||||
args,
|
||||
);
|
||||
}
|
||||
|
||||
// Now equate closure substs to regions inherited from `typeck_root_def_id`. Fixes #98589.
|
||||
// Now equate closure args to regions inherited from `typeck_root_def_id`. Fixes #98589.
|
||||
let typeck_root_def_id = tcx.typeck_root_def_id(self.body.source.def_id());
|
||||
let typeck_root_substs = ty::InternalSubsts::identity_for_item(tcx, typeck_root_def_id);
|
||||
let typeck_root_args = ty::GenericArgs::identity_for_item(tcx, typeck_root_def_id);
|
||||
|
||||
let parent_substs = match tcx.def_kind(def_id) {
|
||||
DefKind::Closure => substs.as_closure().parent_substs(),
|
||||
DefKind::Generator => substs.as_generator().parent_substs(),
|
||||
DefKind::InlineConst => substs.as_inline_const().parent_substs(),
|
||||
let parent_args = match tcx.def_kind(def_id) {
|
||||
DefKind::Closure => args.as_closure().parent_args(),
|
||||
DefKind::Generator => args.as_generator().parent_args(),
|
||||
DefKind::InlineConst => args.as_inline_const().parent_args(),
|
||||
other => bug!("unexpected item {:?}", other),
|
||||
};
|
||||
let parent_substs = tcx.mk_substs(parent_substs);
|
||||
let parent_args = tcx.mk_args(parent_args);
|
||||
|
||||
assert_eq!(typeck_root_substs.len(), parent_substs.len());
|
||||
if let Err(_) = self.eq_substs(
|
||||
typeck_root_substs,
|
||||
parent_substs,
|
||||
assert_eq!(typeck_root_args.len(), parent_args.len());
|
||||
if let Err(_) = self.eq_args(
|
||||
typeck_root_args,
|
||||
parent_args,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::BoringNoLocation,
|
||||
) {
|
||||
@ -2680,12 +2675,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
self,
|
||||
def_id,
|
||||
"could not relate closure to parent {:?} != {:?}",
|
||||
typeck_root_substs,
|
||||
parent_substs
|
||||
typeck_root_args,
|
||||
parent_args
|
||||
);
|
||||
}
|
||||
|
||||
tcx.predicates_of(def_id).instantiate(tcx, substs)
|
||||
tcx.predicates_of(def_id).instantiate(tcx, args)
|
||||
}
|
||||
|
||||
#[instrument(skip(self, body), level = "debug")]
|
||||
|
@ -42,10 +42,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
|
||||
/// Add sufficient constraints to ensure `a == b`. See also [Self::relate_types].
|
||||
pub(super) fn eq_substs(
|
||||
pub(super) fn eq_args(
|
||||
&mut self,
|
||||
a: ty::SubstsRef<'tcx>,
|
||||
b: ty::SubstsRef<'tcx>,
|
||||
a: ty::GenericArgsRef<'tcx>,
|
||||
b: ty::GenericArgsRef<'tcx>,
|
||||
locations: Locations,
|
||||
category: ConstraintCategory<'tcx>,
|
||||
) -> Result<(), NoSolution> {
|
||||
|
@ -22,8 +22,8 @@ use rustc_hir::BodyOwnerKind;
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_infer::infer::NllRegionVariableOrigin;
|
||||
use rustc_middle::ty::fold::TypeFoldable;
|
||||
use rustc_middle::ty::{self, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{InternalSubsts, SubstsRef};
|
||||
use rustc_middle::ty::{self, InlineConstArgs, InlineConstArgsParts, RegionVid, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{GenericArgs, GenericArgsRef};
|
||||
use rustc_span::symbol::{kw, sym};
|
||||
use rustc_span::Symbol;
|
||||
use std::iter;
|
||||
@ -88,26 +88,26 @@ pub struct UniversalRegions<'tcx> {
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum DefiningTy<'tcx> {
|
||||
/// The MIR is a closure. The signature is found via
|
||||
/// `ClosureSubsts::closure_sig_ty`.
|
||||
Closure(DefId, SubstsRef<'tcx>),
|
||||
/// `ClosureArgs::closure_sig_ty`.
|
||||
Closure(DefId, GenericArgsRef<'tcx>),
|
||||
|
||||
/// The MIR is a generator. The signature is that generators take
|
||||
/// no parameters and return the result of
|
||||
/// `ClosureSubsts::generator_return_ty`.
|
||||
Generator(DefId, SubstsRef<'tcx>, hir::Movability),
|
||||
/// `ClosureArgs::generator_return_ty`.
|
||||
Generator(DefId, GenericArgsRef<'tcx>, hir::Movability),
|
||||
|
||||
/// The MIR is a fn item with the given `DefId` and substs. The signature
|
||||
/// The MIR is a fn item with the given `DefId` and args. The signature
|
||||
/// of the function can be bound then with the `fn_sig` query.
|
||||
FnDef(DefId, SubstsRef<'tcx>),
|
||||
FnDef(DefId, GenericArgsRef<'tcx>),
|
||||
|
||||
/// The MIR represents some form of constant. The signature then
|
||||
/// is that it has no inputs and a single return value, which is
|
||||
/// the value of the constant.
|
||||
Const(DefId, SubstsRef<'tcx>),
|
||||
Const(DefId, GenericArgsRef<'tcx>),
|
||||
|
||||
/// The MIR represents an inline const. The signature has no inputs and a
|
||||
/// single return value found via `InlineConstSubsts::ty`.
|
||||
InlineConst(DefId, SubstsRef<'tcx>),
|
||||
/// single return value found via `InlineConstArgs::ty`.
|
||||
InlineConst(DefId, GenericArgsRef<'tcx>),
|
||||
}
|
||||
|
||||
impl<'tcx> DefiningTy<'tcx> {
|
||||
@ -117,9 +117,9 @@ impl<'tcx> DefiningTy<'tcx> {
|
||||
/// match up with the upvar order in the HIR, typesystem, and MIR.
|
||||
pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
|
||||
match self {
|
||||
DefiningTy::Closure(_, substs) => Either::Left(substs.as_closure().upvar_tys()),
|
||||
DefiningTy::Generator(_, substs, _) => {
|
||||
Either::Right(Either::Left(substs.as_generator().upvar_tys()))
|
||||
DefiningTy::Closure(_, args) => Either::Left(args.as_closure().upvar_tys()),
|
||||
DefiningTy::Generator(_, args, _) => {
|
||||
Either::Right(Either::Left(args.as_generator().upvar_tys()))
|
||||
}
|
||||
DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => {
|
||||
Either::Right(Either::Right(iter::empty()))
|
||||
@ -164,9 +164,9 @@ struct UniversalRegionIndices<'tcx> {
|
||||
/// used because trait matching and type-checking will feed us
|
||||
/// region constraints that reference those regions and we need to
|
||||
/// be able to map them to our internal `RegionVid`. This is
|
||||
/// basically equivalent to an `InternalSubsts`, except that it also
|
||||
/// basically equivalent to an `GenericArgs`, except that it also
|
||||
/// contains an entry for `ReStatic` -- it might be nice to just
|
||||
/// use a substs, and then handle `ReStatic` another way.
|
||||
/// use a args, and then handle `ReStatic` another way.
|
||||
indices: FxHashMap<ty::Region<'tcx>, RegionVid>,
|
||||
|
||||
/// The vid assigned to `'static`. Used only for diagnostics.
|
||||
@ -243,13 +243,13 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||
/// `V[1]: V[2]`.
|
||||
pub fn closure_mapping(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
closure_substs: SubstsRef<'tcx>,
|
||||
closure_args: GenericArgsRef<'tcx>,
|
||||
expected_num_vars: usize,
|
||||
closure_def_id: LocalDefId,
|
||||
) -> IndexVec<RegionVid, ty::Region<'tcx>> {
|
||||
let mut region_mapping = IndexVec::with_capacity(expected_num_vars);
|
||||
region_mapping.push(tcx.lifetimes.re_static);
|
||||
tcx.for_each_free_region(&closure_substs, |fr| {
|
||||
tcx.for_each_free_region(&closure_args, |fr| {
|
||||
region_mapping.push(fr);
|
||||
});
|
||||
|
||||
@ -334,11 +334,11 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||
/// state.
|
||||
pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) {
|
||||
match self.defining_ty {
|
||||
DefiningTy::Closure(def_id, substs) => {
|
||||
DefiningTy::Closure(def_id, args) => {
|
||||
err.note(format!(
|
||||
"defining type: {} with closure substs {:#?}",
|
||||
tcx.def_path_str_with_substs(def_id, substs),
|
||||
&substs[tcx.generics_of(def_id).parent_count..],
|
||||
"defining type: {} with closure args {:#?}",
|
||||
tcx.def_path_str_with_args(def_id, args),
|
||||
&args[tcx.generics_of(def_id).parent_count..],
|
||||
));
|
||||
|
||||
// FIXME: It'd be nice to print the late-bound regions
|
||||
@ -350,11 +350,11 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||
err.note(format!("late-bound region is {:?}", self.to_region_vid(r)));
|
||||
});
|
||||
}
|
||||
DefiningTy::Generator(def_id, substs, _) => {
|
||||
DefiningTy::Generator(def_id, args, _) => {
|
||||
err.note(format!(
|
||||
"defining type: {} with generator substs {:#?}",
|
||||
tcx.def_path_str_with_substs(def_id, substs),
|
||||
&substs[tcx.generics_of(def_id).parent_count..],
|
||||
"defining type: {} with generator args {:#?}",
|
||||
tcx.def_path_str_with_args(def_id, args),
|
||||
&args[tcx.generics_of(def_id).parent_count..],
|
||||
));
|
||||
|
||||
// FIXME: As above, we'd like to print out the region
|
||||
@ -364,22 +364,19 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||
err.note(format!("late-bound region is {:?}", self.to_region_vid(r)));
|
||||
});
|
||||
}
|
||||
DefiningTy::FnDef(def_id, substs) => {
|
||||
err.note(format!(
|
||||
"defining type: {}",
|
||||
tcx.def_path_str_with_substs(def_id, substs),
|
||||
));
|
||||
DefiningTy::FnDef(def_id, args) => {
|
||||
err.note(format!("defining type: {}", tcx.def_path_str_with_args(def_id, args),));
|
||||
}
|
||||
DefiningTy::Const(def_id, substs) => {
|
||||
DefiningTy::Const(def_id, args) => {
|
||||
err.note(format!(
|
||||
"defining constant type: {}",
|
||||
tcx.def_path_str_with_substs(def_id, substs),
|
||||
tcx.def_path_str_with_args(def_id, args),
|
||||
));
|
||||
}
|
||||
DefiningTy::InlineConst(def_id, substs) => {
|
||||
DefiningTy::InlineConst(def_id, args) => {
|
||||
err.note(format!(
|
||||
"defining inline constant type: {}",
|
||||
tcx.def_path_str_with_substs(def_id, substs),
|
||||
tcx.def_path_str_with_args(def_id, args),
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -501,8 +498,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
.as_var();
|
||||
|
||||
let region = ty::Region::new_var(self.infcx.tcx, reg_vid);
|
||||
let va_list_ty =
|
||||
self.infcx.tcx.type_of(va_list_did).subst(self.infcx.tcx, &[region.into()]);
|
||||
let va_list_ty = self
|
||||
.infcx
|
||||
.tcx
|
||||
.type_of(va_list_did)
|
||||
.instantiate(self.infcx.tcx, &[region.into()]);
|
||||
|
||||
unnormalized_input_tys = self.infcx.tcx.mk_type_list_from_iter(
|
||||
unnormalized_input_tys.iter().copied().chain(iter::once(va_list_ty)),
|
||||
@ -522,7 +522,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
debug!("build: local regions = {}..{}", first_local_index, num_universals);
|
||||
|
||||
let yield_ty = match defining_ty {
|
||||
DefiningTy::Generator(_, substs, _) => Some(substs.as_generator().yield_ty()),
|
||||
DefiningTy::Generator(_, args, _) => Some(args.as_generator().yield_ty()),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
@ -548,7 +548,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
|
||||
match tcx.hir().body_owner_kind(self.mir_def) {
|
||||
BodyOwnerKind::Closure | BodyOwnerKind::Fn => {
|
||||
let defining_ty = tcx.type_of(self.mir_def).subst_identity();
|
||||
let defining_ty = tcx.type_of(self.mir_def).instantiate_identity();
|
||||
|
||||
debug!("defining_ty (pre-replacement): {:?}", defining_ty);
|
||||
|
||||
@ -556,11 +556,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
self.infcx.replace_free_regions_with_nll_infer_vars(FR, defining_ty);
|
||||
|
||||
match *defining_ty.kind() {
|
||||
ty::Closure(def_id, substs) => DefiningTy::Closure(def_id, substs),
|
||||
ty::Generator(def_id, substs, movability) => {
|
||||
DefiningTy::Generator(def_id, substs, movability)
|
||||
ty::Closure(def_id, args) => DefiningTy::Closure(def_id, args),
|
||||
ty::Generator(def_id, args, movability) => {
|
||||
DefiningTy::Generator(def_id, args, movability)
|
||||
}
|
||||
ty::FnDef(def_id, substs) => DefiningTy::FnDef(def_id, substs),
|
||||
ty::FnDef(def_id, args) => DefiningTy::FnDef(def_id, args),
|
||||
_ => span_bug!(
|
||||
tcx.def_span(self.mir_def),
|
||||
"expected defining type for `{:?}`: `{:?}`",
|
||||
@ -571,11 +571,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
}
|
||||
|
||||
BodyOwnerKind::Const | BodyOwnerKind::Static(..) => {
|
||||
let identity_substs = InternalSubsts::identity_for_item(tcx, typeck_root_def_id);
|
||||
let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id);
|
||||
if self.mir_def.to_def_id() == typeck_root_def_id {
|
||||
let substs =
|
||||
self.infcx.replace_free_regions_with_nll_infer_vars(FR, identity_substs);
|
||||
DefiningTy::Const(self.mir_def.to_def_id(), substs)
|
||||
let args =
|
||||
self.infcx.replace_free_regions_with_nll_infer_vars(FR, identity_args);
|
||||
DefiningTy::Const(self.mir_def.to_def_id(), args)
|
||||
} else {
|
||||
// FIXME this line creates a dependency between borrowck and typeck.
|
||||
//
|
||||
@ -584,18 +584,18 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
// into borrowck, which is ICE #78174.
|
||||
//
|
||||
// As a workaround, inline consts have an additional generic param (`ty`
|
||||
// below), so that `type_of(inline_const_def_id).substs(substs)` uses the
|
||||
// below), so that `type_of(inline_const_def_id).args(args)` uses the
|
||||
// proper type with NLL infer vars.
|
||||
let ty = tcx
|
||||
.typeck(self.mir_def)
|
||||
.node_type(tcx.local_def_id_to_hir_id(self.mir_def));
|
||||
let substs = InlineConstSubsts::new(
|
||||
let args = InlineConstArgs::new(
|
||||
tcx,
|
||||
InlineConstSubstsParts { parent_substs: identity_substs, ty },
|
||||
InlineConstArgsParts { parent_args: identity_args, ty },
|
||||
)
|
||||
.substs;
|
||||
let substs = self.infcx.replace_free_regions_with_nll_infer_vars(FR, substs);
|
||||
DefiningTy::InlineConst(self.mir_def.to_def_id(), substs)
|
||||
.args;
|
||||
let args = self.infcx.replace_free_regions_with_nll_infer_vars(FR, args);
|
||||
DefiningTy::InlineConst(self.mir_def.to_def_id(), args)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -612,29 +612,29 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
) -> UniversalRegionIndices<'tcx> {
|
||||
let tcx = self.infcx.tcx;
|
||||
let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id());
|
||||
let identity_substs = InternalSubsts::identity_for_item(tcx, typeck_root_def_id);
|
||||
let fr_substs = match defining_ty {
|
||||
DefiningTy::Closure(_, substs)
|
||||
| DefiningTy::Generator(_, substs, _)
|
||||
| DefiningTy::InlineConst(_, substs) => {
|
||||
let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id);
|
||||
let fr_args = match defining_ty {
|
||||
DefiningTy::Closure(_, args)
|
||||
| DefiningTy::Generator(_, args, _)
|
||||
| DefiningTy::InlineConst(_, args) => {
|
||||
// In the case of closures, we rely on the fact that
|
||||
// the first N elements in the ClosureSubsts are
|
||||
// the first N elements in the ClosureArgs are
|
||||
// inherited from the `typeck_root_def_id`.
|
||||
// Therefore, when we zip together (below) with
|
||||
// `identity_substs`, we will get only those regions
|
||||
// `identity_args`, we will get only those regions
|
||||
// that correspond to early-bound regions declared on
|
||||
// the `typeck_root_def_id`.
|
||||
assert!(substs.len() >= identity_substs.len());
|
||||
assert_eq!(substs.regions().count(), identity_substs.regions().count());
|
||||
substs
|
||||
assert!(args.len() >= identity_args.len());
|
||||
assert_eq!(args.regions().count(), identity_args.regions().count());
|
||||
args
|
||||
}
|
||||
|
||||
DefiningTy::FnDef(_, substs) | DefiningTy::Const(_, substs) => substs,
|
||||
DefiningTy::FnDef(_, args) | DefiningTy::Const(_, args) => args,
|
||||
};
|
||||
|
||||
let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static));
|
||||
let subst_mapping =
|
||||
iter::zip(identity_substs.regions(), fr_substs.regions().map(|r| r.as_var()));
|
||||
iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var()));
|
||||
|
||||
UniversalRegionIndices { indices: global_mapping.chain(subst_mapping).collect(), fr_static }
|
||||
}
|
||||
@ -646,9 +646,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
) -> ty::Binder<'tcx, &'tcx ty::List<Ty<'tcx>>> {
|
||||
let tcx = self.infcx.tcx;
|
||||
match defining_ty {
|
||||
DefiningTy::Closure(def_id, substs) => {
|
||||
DefiningTy::Closure(def_id, args) => {
|
||||
assert_eq!(self.mir_def.to_def_id(), def_id);
|
||||
let closure_sig = substs.as_closure().sig();
|
||||
let closure_sig = args.as_closure().sig();
|
||||
let inputs_and_output = closure_sig.inputs_and_output();
|
||||
let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
|
||||
inputs_and_output
|
||||
@ -661,7 +661,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
kind: ty::BrEnv,
|
||||
};
|
||||
let env_region = ty::Region::new_late_bound(tcx, ty::INNERMOST, br);
|
||||
let closure_ty = tcx.closure_env_ty(def_id, substs, env_region).unwrap();
|
||||
let closure_ty = tcx.closure_env_ty(def_id, args, env_region).unwrap();
|
||||
|
||||
// The "inputs" of the closure in the
|
||||
// signature appear as a tuple. The MIR side
|
||||
@ -681,18 +681,18 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
)
|
||||
}
|
||||
|
||||
DefiningTy::Generator(def_id, substs, movability) => {
|
||||
DefiningTy::Generator(def_id, args, movability) => {
|
||||
assert_eq!(self.mir_def.to_def_id(), def_id);
|
||||
let resume_ty = substs.as_generator().resume_ty();
|
||||
let output = substs.as_generator().return_ty();
|
||||
let generator_ty = Ty::new_generator(tcx, def_id, substs, movability);
|
||||
let resume_ty = args.as_generator().resume_ty();
|
||||
let output = args.as_generator().return_ty();
|
||||
let generator_ty = Ty::new_generator(tcx, def_id, args, movability);
|
||||
let inputs_and_output =
|
||||
self.infcx.tcx.mk_type_list(&[generator_ty, resume_ty, output]);
|
||||
ty::Binder::dummy(inputs_and_output)
|
||||
}
|
||||
|
||||
DefiningTy::FnDef(def_id, _) => {
|
||||
let sig = tcx.fn_sig(def_id).subst_identity();
|
||||
let sig = tcx.fn_sig(def_id).instantiate_identity();
|
||||
let sig = indices.fold_to_region_vids(tcx, sig);
|
||||
sig.inputs_and_output()
|
||||
}
|
||||
@ -701,14 +701,14 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
// For a constant body, there are no inputs, and one
|
||||
// "output" (the type of the constant).
|
||||
assert_eq!(self.mir_def.to_def_id(), def_id);
|
||||
let ty = tcx.type_of(self.mir_def).subst_identity();
|
||||
let ty = tcx.type_of(self.mir_def).instantiate_identity();
|
||||
let ty = indices.fold_to_region_vids(tcx, ty);
|
||||
ty::Binder::dummy(tcx.mk_type_list(&[ty]))
|
||||
}
|
||||
|
||||
DefiningTy::InlineConst(def_id, substs) => {
|
||||
DefiningTy::InlineConst(def_id, args) => {
|
||||
assert_eq!(self.mir_def.to_def_id(), def_id);
|
||||
let ty = substs.as_inline_const().ty();
|
||||
let ty = args.as_inline_const().ty();
|
||||
ty::Binder::dummy(tcx.mk_type_list(&[ty]))
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ pub(crate) fn get_function_sig<'tcx>(
|
||||
default_call_conv: CallConv,
|
||||
inst: Instance<'tcx>,
|
||||
) -> Signature {
|
||||
assert!(!inst.substs.has_infer());
|
||||
assert!(!inst.args.has_infer());
|
||||
clif_sig_from_fn_abi(
|
||||
tcx,
|
||||
default_call_conv,
|
||||
@ -377,16 +377,16 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
||||
let ret_place = codegen_place(fx, destination);
|
||||
|
||||
// Handle special calls like intrinsics and empty drop glue.
|
||||
let instance = if let ty::FnDef(def_id, substs) = *func.layout().ty.kind() {
|
||||
let instance = if let ty::FnDef(def_id, fn_args) = *func.layout().ty.kind() {
|
||||
let instance =
|
||||
ty::Instance::expect_resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, substs)
|
||||
ty::Instance::expect_resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, fn_args)
|
||||
.polymorphize(fx.tcx);
|
||||
|
||||
if fx.tcx.symbol_name(instance).name.starts_with("llvm.") {
|
||||
crate::intrinsics::codegen_llvm_intrinsic_call(
|
||||
fx,
|
||||
&fx.tcx.symbol_name(instance).name,
|
||||
substs,
|
||||
fn_args,
|
||||
args,
|
||||
ret_place,
|
||||
target,
|
||||
@ -611,7 +611,7 @@ pub(crate) fn codegen_drop<'tcx>(
|
||||
// `Instance::resolve_drop_in_place`?
|
||||
let virtual_drop = Instance {
|
||||
def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0),
|
||||
substs: drop_instance.substs,
|
||||
args: drop_instance.args,
|
||||
};
|
||||
let fn_abi =
|
||||
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, ty::List::empty());
|
||||
@ -648,7 +648,7 @@ pub(crate) fn codegen_drop<'tcx>(
|
||||
|
||||
let virtual_drop = Instance {
|
||||
def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0),
|
||||
substs: drop_instance.substs,
|
||||
args: drop_instance.args,
|
||||
};
|
||||
let fn_abi =
|
||||
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, ty::List::empty());
|
||||
|
@ -28,7 +28,7 @@ pub(crate) fn codegen_fn<'tcx>(
|
||||
module: &mut dyn Module,
|
||||
instance: Instance<'tcx>,
|
||||
) -> CodegenedFunction {
|
||||
debug_assert!(!instance.substs.has_infer());
|
||||
debug_assert!(!instance.args.has_infer());
|
||||
|
||||
let symbol_name = tcx.symbol_name(instance).name.to_string();
|
||||
let _timer = tcx.prof.generic_activity_with_arg("codegen fn", &*symbol_name);
|
||||
@ -578,13 +578,13 @@ fn codegen_stmt<'tcx>(
|
||||
let from_ty = fx.monomorphize(operand.ty(&fx.mir.local_decls, fx.tcx));
|
||||
let to_layout = fx.layout_of(fx.monomorphize(to_ty));
|
||||
match *from_ty.kind() {
|
||||
ty::FnDef(def_id, substs) => {
|
||||
ty::FnDef(def_id, args) => {
|
||||
let func_ref = fx.get_function_ref(
|
||||
Instance::resolve_for_fn_ptr(
|
||||
fx.tcx,
|
||||
ParamEnv::reveal_all(),
|
||||
def_id,
|
||||
substs,
|
||||
args,
|
||||
)
|
||||
.unwrap()
|
||||
.polymorphize(fx.tcx),
|
||||
@ -668,11 +668,11 @@ fn codegen_stmt<'tcx>(
|
||||
) => {
|
||||
let operand = codegen_operand(fx, operand);
|
||||
match *operand.layout().ty.kind() {
|
||||
ty::Closure(def_id, substs) => {
|
||||
ty::Closure(def_id, args) => {
|
||||
let instance = Instance::resolve_closure(
|
||||
fx.tcx,
|
||||
def_id,
|
||||
substs,
|
||||
args,
|
||||
ty::ClosureKind::FnOnce,
|
||||
)
|
||||
.expect("failed to normalize and resolve closure during codegen")
|
||||
|
@ -57,7 +57,7 @@ pub(crate) fn codegen_tls_ref<'tcx>(
|
||||
let tls_ptr = if !def_id.is_local() && fx.tcx.needs_thread_local_shim(def_id) {
|
||||
let instance = ty::Instance {
|
||||
def: ty::InstanceDef::ThreadLocalShim(def_id),
|
||||
substs: ty::InternalSubsts::empty(),
|
||||
args: ty::GenericArgs::empty(),
|
||||
};
|
||||
let func_ref = fx.get_function_ref(instance);
|
||||
let call = fx.bcx.ins().call(func_ref, &[]);
|
||||
|
@ -42,7 +42,7 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
|
||||
InlineAsmOperand::SymFn { anon_const } => {
|
||||
let ty = tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id);
|
||||
let instance = match ty.kind() {
|
||||
&ty::FnDef(def_id, substs) => Instance::new(def_id, substs),
|
||||
&ty::FnDef(def_id, args) => Instance::new(def_id, args),
|
||||
_ => span_bug!(op_sp, "asm sym is not a function"),
|
||||
};
|
||||
let symbol = tcx.symbol_name(instance);
|
||||
|
@ -254,12 +254,12 @@ pub(crate) fn codegen_inline_asm<'tcx>(
|
||||
}
|
||||
InlineAsmOperand::SymFn { ref value } => {
|
||||
let literal = fx.monomorphize(value.literal);
|
||||
if let ty::FnDef(def_id, substs) = *literal.ty().kind() {
|
||||
if let ty::FnDef(def_id, args) = *literal.ty().kind() {
|
||||
let instance = ty::Instance::resolve_for_fn_ptr(
|
||||
fx.tcx,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
def_id,
|
||||
substs,
|
||||
args,
|
||||
)
|
||||
.unwrap();
|
||||
let symbol = fx.tcx.symbol_name(instance);
|
||||
|
@ -3,23 +3,35 @@
|
||||
use crate::intrinsics::*;
|
||||
use crate::prelude::*;
|
||||
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
|
||||
pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
intrinsic: &str,
|
||||
substs: SubstsRef<'tcx>,
|
||||
generic_args: GenericArgsRef<'tcx>,
|
||||
args: &[mir::Operand<'tcx>],
|
||||
ret: CPlace<'tcx>,
|
||||
target: Option<BasicBlock>,
|
||||
) {
|
||||
if intrinsic.starts_with("llvm.aarch64") {
|
||||
return llvm_aarch64::codegen_aarch64_llvm_intrinsic_call(
|
||||
fx, intrinsic, substs, args, ret, target,
|
||||
fx,
|
||||
intrinsic,
|
||||
generic_args,
|
||||
args,
|
||||
ret,
|
||||
target,
|
||||
);
|
||||
}
|
||||
if intrinsic.starts_with("llvm.x86") {
|
||||
return llvm_x86::codegen_x86_llvm_intrinsic_call(fx, intrinsic, substs, args, ret, target);
|
||||
return llvm_x86::codegen_x86_llvm_intrinsic_call(
|
||||
fx,
|
||||
intrinsic,
|
||||
generic_args,
|
||||
args,
|
||||
ret,
|
||||
target,
|
||||
);
|
||||
}
|
||||
|
||||
match intrinsic {
|
||||
|
@ -3,12 +3,12 @@
|
||||
use crate::intrinsics::*;
|
||||
use crate::prelude::*;
|
||||
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
|
||||
pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
intrinsic: &str,
|
||||
_substs: SubstsRef<'tcx>,
|
||||
_args: GenericArgsRef<'tcx>,
|
||||
args: &[mir::Operand<'tcx>],
|
||||
ret: CPlace<'tcx>,
|
||||
target: Option<BasicBlock>,
|
||||
|
@ -3,12 +3,12 @@
|
||||
use crate::intrinsics::*;
|
||||
use crate::prelude::*;
|
||||
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
|
||||
pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
intrinsic: &str,
|
||||
_substs: SubstsRef<'tcx>,
|
||||
_args: GenericArgsRef<'tcx>,
|
||||
args: &[mir::Operand<'tcx>],
|
||||
ret: CPlace<'tcx>,
|
||||
target: Option<BasicBlock>,
|
||||
|
@ -24,7 +24,7 @@ pub(crate) use llvm::codegen_llvm_intrinsic_call;
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::layout::{HasParamEnv, ValidityRequirement};
|
||||
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
|
||||
use crate::prelude::*;
|
||||
@ -213,13 +213,13 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
|
||||
source_info: mir::SourceInfo,
|
||||
) {
|
||||
let intrinsic = fx.tcx.item_name(instance.def_id());
|
||||
let substs = instance.substs;
|
||||
let instance_args = instance.args;
|
||||
|
||||
if intrinsic.as_str().starts_with("simd_") {
|
||||
self::simd::codegen_simd_intrinsic_call(
|
||||
fx,
|
||||
intrinsic,
|
||||
substs,
|
||||
instance_args,
|
||||
args,
|
||||
destination,
|
||||
target.expect("target for simd intrinsic"),
|
||||
@ -233,7 +233,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
|
||||
fx,
|
||||
instance,
|
||||
intrinsic,
|
||||
substs,
|
||||
instance_args,
|
||||
args,
|
||||
destination,
|
||||
target,
|
||||
@ -365,7 +365,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
instance: Instance<'tcx>,
|
||||
intrinsic: Symbol,
|
||||
substs: SubstsRef<'tcx>,
|
||||
generic_args: GenericArgsRef<'tcx>,
|
||||
args: &[mir::Operand<'tcx>],
|
||||
ret: CPlace<'tcx>,
|
||||
destination: Option<BasicBlock>,
|
||||
@ -394,7 +394,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
let dst = dst.load_scalar(fx);
|
||||
let count = count.load_scalar(fx);
|
||||
|
||||
let elem_ty = substs.type_at(0);
|
||||
let elem_ty = generic_args.type_at(0);
|
||||
let elem_size: u64 = fx.layout_of(elem_ty).size.bytes();
|
||||
assert_eq!(args.len(), 3);
|
||||
let byte_amount =
|
||||
@ -410,7 +410,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
let src = src.load_scalar(fx);
|
||||
let count = count.load_scalar(fx);
|
||||
|
||||
let elem_ty = substs.type_at(0);
|
||||
let elem_ty = generic_args.type_at(0);
|
||||
let elem_size: u64 = fx.layout_of(elem_ty).size.bytes();
|
||||
assert_eq!(args.len(), 3);
|
||||
let byte_amount =
|
||||
@ -428,7 +428,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
sym::size_of_val => {
|
||||
intrinsic_args!(fx, args => (ptr); intrinsic);
|
||||
|
||||
let layout = fx.layout_of(substs.type_at(0));
|
||||
let layout = fx.layout_of(generic_args.type_at(0));
|
||||
// Note: Can't use is_unsized here as truly unsized types need to take the fixed size
|
||||
// branch
|
||||
let size = if let Abi::ScalarPair(_, _) = ptr.layout().abi {
|
||||
@ -443,7 +443,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
sym::min_align_of_val => {
|
||||
intrinsic_args!(fx, args => (ptr); intrinsic);
|
||||
|
||||
let layout = fx.layout_of(substs.type_at(0));
|
||||
let layout = fx.layout_of(generic_args.type_at(0));
|
||||
// Note: Can't use is_unsized here as truly unsized types need to take the fixed size
|
||||
// branch
|
||||
let align = if let Abi::ScalarPair(_, _) = ptr.layout().abi {
|
||||
@ -602,7 +602,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
sym::assert_inhabited | sym::assert_zero_valid | sym::assert_mem_uninitialized_valid => {
|
||||
intrinsic_args!(fx, args => (); intrinsic);
|
||||
|
||||
let ty = substs.type_at(0);
|
||||
let ty = generic_args.type_at(0);
|
||||
|
||||
let requirement = ValidityRequirement::from_intrinsic(intrinsic);
|
||||
|
||||
@ -674,7 +674,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
intrinsic_args!(fx, args => (ptr, base); intrinsic);
|
||||
let ptr = ptr.load_scalar(fx);
|
||||
let base = base.load_scalar(fx);
|
||||
let ty = substs.type_at(0);
|
||||
let ty = generic_args.type_at(0);
|
||||
|
||||
let pointee_size: u64 = fx.layout_of(ty).size.bytes();
|
||||
let diff_bytes = fx.bcx.ins().isub(ptr, base);
|
||||
@ -720,7 +720,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
intrinsic_args!(fx, args => (ptr); intrinsic);
|
||||
let ptr = ptr.load_scalar(fx);
|
||||
|
||||
let ty = substs.type_at(0);
|
||||
let ty = generic_args.type_at(0);
|
||||
match ty.kind() {
|
||||
ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => {
|
||||
// FIXME implement 128bit atomics
|
||||
@ -751,7 +751,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
intrinsic_args!(fx, args => (ptr, val); intrinsic);
|
||||
let ptr = ptr.load_scalar(fx);
|
||||
|
||||
let ty = substs.type_at(0);
|
||||
let ty = generic_args.type_at(0);
|
||||
match ty.kind() {
|
||||
ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => {
|
||||
// FIXME implement 128bit atomics
|
||||
@ -1128,7 +1128,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
let lhs_ref = lhs_ref.load_scalar(fx);
|
||||
let rhs_ref = rhs_ref.load_scalar(fx);
|
||||
|
||||
let size = fx.layout_of(substs.type_at(0)).layout.size();
|
||||
let size = fx.layout_of(generic_args.type_at(0)).layout.size();
|
||||
// FIXME add and use emit_small_memcmp
|
||||
let is_eq_value = if size == Size::ZERO {
|
||||
// No bytes means they're trivially equal
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Codegen `extern "platform-intrinsic"` intrinsics.
|
||||
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::abi::Endian;
|
||||
|
||||
@ -21,7 +21,7 @@ fn report_simd_type_validation_error(
|
||||
pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
intrinsic: Symbol,
|
||||
_substs: SubstsRef<'tcx>,
|
||||
_args: GenericArgsRef<'tcx>,
|
||||
args: &[mir::Operand<'tcx>],
|
||||
ret: CPlace<'tcx>,
|
||||
target: BasicBlock,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use rustc_hir::LangItem;
|
||||
use rustc_middle::ty::subst::GenericArg;
|
||||
use rustc_middle::ty::AssocKind;
|
||||
use rustc_middle::ty::GenericArg;
|
||||
use rustc_session::config::{sigpipe, EntryFnType};
|
||||
use rustc_span::symbol::Ident;
|
||||
|
||||
@ -119,7 +119,7 @@ pub(crate) fn maybe_create_entry_wrapper(
|
||||
tcx,
|
||||
ParamEnv::reveal_all(),
|
||||
report.def_id,
|
||||
tcx.mk_substs(&[GenericArg::from(main_ret_ty)]),
|
||||
tcx.mk_args(&[GenericArg::from(main_ret_ty)]),
|
||||
)
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
@ -146,7 +146,7 @@ pub(crate) fn maybe_create_entry_wrapper(
|
||||
tcx,
|
||||
ParamEnv::reveal_all(),
|
||||
start_def_id,
|
||||
tcx.mk_substs(&[main_ret_ty.into()]),
|
||||
tcx.mk_args(&[main_ret_ty.into()]),
|
||||
)
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
|
@ -9,7 +9,7 @@
|
||||
//!
|
||||
//! function u0:22(i64) -> i8, i8 system_v {
|
||||
//! ; symbol _ZN97_$LT$example..IsNotEmpty$u20$as$u20$mini_core..FnOnce$LT$$LP$$RF$$RF$$u5b$u16$u5d$$C$$RP$$GT$$GT$9call_once17hd517c453d67c0915E
|
||||
//! ; instance Instance { def: Item(WithOptConstParam { did: DefId(0:42 ~ example[4e51]::{impl#0}::call_once), const_param_did: None }), substs: [ReErased, ReErased] }
|
||||
//! ; instance Instance { def: Item(WithOptConstParam { did: DefId(0:42 ~ example[4e51]::{impl#0}::call_once), const_param_did: None }), args: [ReErased, ReErased] }
|
||||
//! ; abi FnAbi { args: [ArgAbi { layout: TyAndLayout { ty: IsNotEmpty, layout: Layout { size: Size(0 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, abi: Aggregate { sized: true }, fields: Arbitrary { offsets: [], memory_index: [] }, largest_niche: None, variants: Single { index: 0 } } }, mode: Ignore }, ArgAbi { layout: TyAndLayout { ty: &&[u16], layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), variants: Single { index: 0 } } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(8 bytes)) }) }], ret: ArgAbi { layout: TyAndLayout { ty: (u8, u8), layout: Layout { size: Size(2 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, abi: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=255 }, Initialized { value: Int(I8, false), valid_range: 0..=255 }), fields: Arbitrary { offsets: [Size(0 bytes), Size(1 bytes)], memory_index: [0, 1] }, largest_niche: None, variants: Single { index: 0 } } }, mode: Pair(ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }, ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }) }, c_variadic: false, fixed_count: 1, conv: Rust, can_unwind: false }
|
||||
//!
|
||||
//! ; kind loc.idx param pass mode ty
|
||||
@ -25,7 +25,7 @@
|
||||
//!
|
||||
//! ss0 = explicit_slot 16
|
||||
//! sig0 = (i64, i64) -> i8, i8 system_v
|
||||
//! fn0 = colocated u0:23 sig0 ; Instance { def: Item(WithOptConstParam { did: DefId(0:46 ~ example[4e51]::{impl#1}::call_mut), const_param_did: None }), substs: [ReErased, ReErased] }
|
||||
//! fn0 = colocated u0:23 sig0 ; Instance { def: Item(WithOptConstParam { did: DefId(0:46 ~ example[4e51]::{impl#1}::call_mut), const_param_did: None }), args: [ReErased, ReErased] }
|
||||
//!
|
||||
//! block0(v0: i64):
|
||||
//! nop
|
||||
@ -261,7 +261,7 @@ pub(crate) fn write_clif_file(
|
||||
|
||||
impl fmt::Debug for FunctionCx<'_, '_, '_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(f, "{:?}", self.instance.substs)?;
|
||||
writeln!(f, "{:?}", self.instance.args)?;
|
||||
writeln!(f, "{:?}", self.local_map)?;
|
||||
|
||||
let mut clif = String::new();
|
||||
|
@ -850,11 +850,11 @@ pub(crate) fn assert_assignable<'tcx>(
|
||||
}
|
||||
}
|
||||
}
|
||||
(&ty::Adt(adt_def_a, substs_a), &ty::Adt(adt_def_b, substs_b))
|
||||
(&ty::Adt(adt_def_a, args_a), &ty::Adt(adt_def_b, args_b))
|
||||
if adt_def_a.did() == adt_def_b.did() =>
|
||||
{
|
||||
let mut types_a = substs_a.types();
|
||||
let mut types_b = substs_b.types();
|
||||
let mut types_a = args_a.types();
|
||||
let mut types_b = args_b.types();
|
||||
loop {
|
||||
match (types_a.next(), types_b.next()) {
|
||||
(Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),
|
||||
@ -864,11 +864,11 @@ pub(crate) fn assert_assignable<'tcx>(
|
||||
}
|
||||
}
|
||||
(ty::Array(a, _), ty::Array(b, _)) => assert_assignable(fx, *a, *b, limit - 1),
|
||||
(&ty::Closure(def_id_a, substs_a), &ty::Closure(def_id_b, substs_b))
|
||||
(&ty::Closure(def_id_a, args_a), &ty::Closure(def_id_b, args_b))
|
||||
if def_id_a == def_id_b =>
|
||||
{
|
||||
let mut types_a = substs_a.types();
|
||||
let mut types_b = substs_b.types();
|
||||
let mut types_a = args_a.types();
|
||||
let mut types_b = args_b.types();
|
||||
loop {
|
||||
match (types_a.next(), types_b.next()) {
|
||||
(Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),
|
||||
|
@ -17,8 +17,8 @@ use crate::context::CodegenCx;
|
||||
pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>) -> Function<'gcc> {
|
||||
let tcx = cx.tcx();
|
||||
|
||||
assert!(!instance.substs.has_infer());
|
||||
assert!(!instance.substs.has_escaping_bound_vars());
|
||||
assert!(!instance.args.has_infer());
|
||||
assert!(!instance.args.has_escaping_bound_vars());
|
||||
|
||||
let sym = tcx.symbol_name(instance).name;
|
||||
|
||||
@ -100,7 +100,7 @@ pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>)
|
||||
// whether we are sharing generics or not. The important thing here is
|
||||
// that the visibility we apply to the declaration is the same one that
|
||||
// has been applied to the definition (wherever that definition may be).
|
||||
let is_generic = instance.substs.non_erasable_generics().next().is_some();
|
||||
let is_generic = instance.args.non_erasable_generics().next().is_some();
|
||||
|
||||
if is_generic {
|
||||
// This is a monomorphization. Its expected visibility depends
|
||||
|
@ -92,8 +92,8 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||
let tcx = self.tcx;
|
||||
let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
|
||||
|
||||
let (def_id, substs) = match *callee_ty.kind() {
|
||||
ty::FnDef(def_id, substs) => (def_id, substs),
|
||||
let (def_id, fn_args) = match *callee_ty.kind() {
|
||||
ty::FnDef(def_id, fn_args) => (def_id, fn_args),
|
||||
_ => bug!("expected fn item type, found {}", callee_ty),
|
||||
};
|
||||
|
||||
@ -142,7 +142,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||
}
|
||||
|
||||
sym::volatile_load | sym::unaligned_volatile_load => {
|
||||
let tp_ty = substs.type_at(0);
|
||||
let tp_ty = fn_args.type_at(0);
|
||||
let mut ptr = args[0].immediate();
|
||||
if let PassMode::Cast(ty, _) = &fn_abi.ret.mode {
|
||||
ptr = self.pointercast(ptr, self.type_ptr_to(ty.gcc_type(self)));
|
||||
@ -264,7 +264,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||
|
||||
sym::raw_eq => {
|
||||
use rustc_target::abi::Abi::*;
|
||||
let tp_ty = substs.type_at(0);
|
||||
let tp_ty = fn_args.type_at(0);
|
||||
let layout = self.layout_of(tp_ty).layout;
|
||||
let _use_integer_compare = match layout.abi() {
|
||||
Scalar(_) | ScalarPair(_, _) => true,
|
||||
|
@ -31,7 +31,7 @@ impl<'gcc, 'tcx> PreDefineMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
|
||||
|
||||
#[cfg_attr(not(feature="master"), allow(unused_variables))]
|
||||
fn predefine_fn(&self, instance: Instance<'tcx>, linkage: Linkage, visibility: Visibility, symbol_name: &str) {
|
||||
assert!(!instance.substs.has_infer());
|
||||
assert!(!instance.args.has_infer());
|
||||
|
||||
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
|
||||
self.linkage.set(base::linkage_to_gcc(linkage));
|
||||
|
@ -101,7 +101,7 @@ fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout
|
||||
if let (&ty::Generator(_, _, _), &Variants::Single { index }) =
|
||||
(layout.ty.kind(), &layout.variants)
|
||||
{
|
||||
write!(&mut name, "::{}", ty::GeneratorSubsts::variant_name(index)).unwrap();
|
||||
write!(&mut name, "::{}", ty::GeneratorArgs::variant_name(index)).unwrap();
|
||||
}
|
||||
Some(name)
|
||||
}
|
||||
@ -282,7 +282,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
|
||||
}
|
||||
// only wide pointer boxes are handled as pointers
|
||||
// thin pointer boxes with scalar allocators are handled by the general logic below
|
||||
ty::Adt(def, substs) if def.is_box() && cx.layout_of(substs.type_at(1)).is_zst() => {
|
||||
ty::Adt(def, args) if def.is_box() && cx.layout_of(args.type_at(1)).is_zst() => {
|
||||
let ptr_ty = Ty::new_mut_ptr(cx.tcx,self.ty.boxed_ty());
|
||||
return cx.layout_of(ptr_ty).scalar_pair_element_gcc_type(cx, index, immediate);
|
||||
}
|
||||
|
@ -27,8 +27,8 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) ->
|
||||
|
||||
debug!("get_fn(instance={:?})", instance);
|
||||
|
||||
assert!(!instance.substs.has_infer());
|
||||
assert!(!instance.substs.has_escaping_bound_vars());
|
||||
assert!(!instance.args.has_infer());
|
||||
assert!(!instance.args.has_escaping_bound_vars());
|
||||
|
||||
if let Some(&llfn) = cx.instances.borrow().get(&instance) {
|
||||
return llfn;
|
||||
@ -129,7 +129,7 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) ->
|
||||
unsafe {
|
||||
llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
|
||||
|
||||
let is_generic = instance.substs.non_erasable_generics().next().is_some();
|
||||
let is_generic = instance.args.non_erasable_generics().next().is_some();
|
||||
|
||||
if is_generic {
|
||||
// This is a monomorphization. Its expected visibility depends
|
||||
|
@ -22,7 +22,7 @@ use rustc_middle::mir::coverage::{
|
||||
use rustc_middle::mir::Coverage;
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
|
||||
use rustc_middle::ty::subst::InternalSubsts;
|
||||
use rustc_middle::ty::GenericArgs;
|
||||
use rustc_middle::ty::Instance;
|
||||
use rustc_middle::ty::Ty;
|
||||
|
||||
@ -250,7 +250,7 @@ fn declare_unused_fn<'tcx>(cx: &CodegenCx<'_, 'tcx>, def_id: DefId) -> Instance<
|
||||
|
||||
let instance = Instance::new(
|
||||
def_id,
|
||||
InternalSubsts::for_item(tcx, def_id, |param, _| {
|
||||
GenericArgs::for_item(tcx, def_id, |param, _| {
|
||||
if let ty::GenericParamDefKind::Lifetime = param.kind {
|
||||
tcx.lifetimes.re_erased.into()
|
||||
} else {
|
||||
|
@ -91,7 +91,7 @@ fn make_mir_scope<'ll, 'tcx>(
|
||||
// FIXME(eddyb) this would be `self.monomorphize(&callee)`
|
||||
// if this is moved to `rustc_codegen_ssa::mir::debuginfo`.
|
||||
let callee = cx.tcx.subst_and_normalize_erasing_regions(
|
||||
instance.substs,
|
||||
instance.args,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
ty::EarlyBinder::bind(callee),
|
||||
);
|
||||
|
@ -449,7 +449,7 @@ pub fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll D
|
||||
}
|
||||
// Box<T, A> may have a non-ZST allocator A. In that case, we
|
||||
// cannot treat Box<T, A> as just an owned alias of `*mut T`.
|
||||
ty::Adt(def, substs) if def.is_box() && cx.layout_of(substs.type_at(1)).is_zst() => {
|
||||
ty::Adt(def, args) if def.is_box() && cx.layout_of(args.type_at(1)).is_zst() => {
|
||||
build_pointer_or_reference_di_node(cx, t, t.boxed_ty(), unique_type_id)
|
||||
}
|
||||
ty::FnDef(..) | ty::FnPtr(_) => build_subroutine_type_di_node(cx, unique_type_id),
|
||||
@ -1007,12 +1007,12 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>(
|
||||
closure_or_generator_di_node: &'ll DIType,
|
||||
) -> SmallVec<&'ll DIType> {
|
||||
let (&def_id, up_var_tys) = match closure_or_generator_ty.kind() {
|
||||
ty::Generator(def_id, substs, _) => {
|
||||
let upvar_tys: SmallVec<_> = substs.as_generator().prefix_tys().collect();
|
||||
ty::Generator(def_id, args, _) => {
|
||||
let upvar_tys: SmallVec<_> = args.as_generator().prefix_tys().collect();
|
||||
(def_id, upvar_tys)
|
||||
}
|
||||
ty::Closure(def_id, substs) => {
|
||||
let upvar_tys: SmallVec<_> = substs.as_closure().upvar_tys().collect();
|
||||
ty::Closure(def_id, args) => {
|
||||
let upvar_tys: SmallVec<_> = args.as_closure().upvar_tys().collect();
|
||||
(def_id, upvar_tys)
|
||||
}
|
||||
_ => {
|
||||
@ -1102,7 +1102,7 @@ fn build_closure_env_di_node<'ll, 'tcx>(
|
||||
unique_type_id: UniqueTypeId<'tcx>,
|
||||
) -> DINodeCreationResult<'ll> {
|
||||
let closure_env_type = unique_type_id.expect_ty();
|
||||
let &ty::Closure(def_id, _substs) = closure_env_type.kind() else {
|
||||
let &ty::Closure(def_id, _args) = closure_env_type.kind() else {
|
||||
bug!("build_closure_env_di_node() called with non-closure-type: {:?}", closure_env_type)
|
||||
};
|
||||
let containing_scope = get_namespace_for_item(cx, def_id);
|
||||
@ -1180,11 +1180,11 @@ fn build_generic_type_param_di_nodes<'ll, 'tcx>(
|
||||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> SmallVec<&'ll DIType> {
|
||||
if let ty::Adt(def, substs) = *ty.kind() {
|
||||
if substs.types().next().is_some() {
|
||||
if let ty::Adt(def, args) = *ty.kind() {
|
||||
if args.types().next().is_some() {
|
||||
let generics = cx.tcx.generics_of(def.did());
|
||||
let names = get_parameter_names(cx, generics);
|
||||
let template_params: SmallVec<_> = iter::zip(substs, names)
|
||||
let template_params: SmallVec<_> = iter::zip(args, names)
|
||||
.filter_map(|(kind, name)| {
|
||||
kind.as_type().map(|ty| {
|
||||
let actual_type =
|
||||
|
@ -12,7 +12,7 @@ use rustc_middle::{
|
||||
ty::{
|
||||
self,
|
||||
layout::{LayoutOf, TyAndLayout},
|
||||
AdtDef, GeneratorSubsts, Ty,
|
||||
AdtDef, GeneratorArgs, Ty,
|
||||
},
|
||||
};
|
||||
use rustc_target::abi::{Align, Endian, Size, TagEncoding, VariantIdx, Variants};
|
||||
@ -673,15 +673,15 @@ fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>(
|
||||
bug!("This function only supports layouts with directly encoded tags.")
|
||||
};
|
||||
|
||||
let (generator_def_id, generator_substs) = match generator_type_and_layout.ty.kind() {
|
||||
&ty::Generator(def_id, substs, _) => (def_id, substs.as_generator()),
|
||||
let (generator_def_id, generator_args) = match generator_type_and_layout.ty.kind() {
|
||||
&ty::Generator(def_id, args, _) => (def_id, args.as_generator()),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let generator_layout = cx.tcx.optimized_mir(generator_def_id).generator_layout().unwrap();
|
||||
|
||||
let common_upvar_names = cx.tcx.closure_saved_names_of_captured_variables(generator_def_id);
|
||||
let variant_range = generator_substs.variant_range(generator_def_id, cx.tcx);
|
||||
let variant_range = generator_args.variant_range(generator_def_id, cx.tcx);
|
||||
let variant_count = (variant_range.start.as_u32()..variant_range.end.as_u32()).len();
|
||||
|
||||
let tag_base_type = tag_base_type(cx, generator_type_and_layout);
|
||||
@ -691,11 +691,11 @@ fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>(
|
||||
generator_type_di_node,
|
||||
variant_range
|
||||
.clone()
|
||||
.map(|variant_index| (variant_index, GeneratorSubsts::variant_name(variant_index))),
|
||||
.map(|variant_index| (variant_index, GeneratorArgs::variant_name(variant_index))),
|
||||
);
|
||||
|
||||
let discriminants: IndexVec<VariantIdx, DiscrResult> = {
|
||||
let discriminants_iter = generator_substs.discriminants(generator_def_id, cx.tcx);
|
||||
let discriminants_iter = generator_args.discriminants(generator_def_id, cx.tcx);
|
||||
let mut discriminants: IndexVec<VariantIdx, DiscrResult> =
|
||||
IndexVec::with_capacity(variant_count);
|
||||
for (variant_index, discr) in discriminants_iter {
|
||||
|
@ -10,7 +10,7 @@ use rustc_middle::{
|
||||
ty::{
|
||||
self,
|
||||
layout::{IntegerExt, LayoutOf, PrimitiveExt, TyAndLayout},
|
||||
AdtDef, GeneratorSubsts, Ty, VariantDef,
|
||||
AdtDef, GeneratorArgs, Ty, VariantDef,
|
||||
},
|
||||
};
|
||||
use rustc_span::Symbol;
|
||||
@ -325,7 +325,7 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>(
|
||||
generator_layout: &GeneratorLayout<'tcx>,
|
||||
common_upvar_names: &IndexSlice<FieldIdx, Symbol>,
|
||||
) -> &'ll DIType {
|
||||
let variant_name = GeneratorSubsts::variant_name(variant_index);
|
||||
let variant_name = GeneratorArgs::variant_name(variant_index);
|
||||
let unique_type_id = UniqueTypeId::for_enum_variant_struct_type(
|
||||
cx.tcx,
|
||||
generator_type_and_layout.ty,
|
||||
@ -334,8 +334,8 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>(
|
||||
|
||||
let variant_layout = generator_type_and_layout.for_variant(cx, variant_index);
|
||||
|
||||
let generator_substs = match generator_type_and_layout.ty.kind() {
|
||||
ty::Generator(_, substs, _) => substs.as_generator(),
|
||||
let generator_args = match generator_type_and_layout.ty.kind() {
|
||||
ty::Generator(_, args, _) => args.as_generator(),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
@ -377,7 +377,7 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>(
|
||||
.collect();
|
||||
|
||||
// Fields that are common to all states
|
||||
let common_fields: SmallVec<_> = generator_substs
|
||||
let common_fields: SmallVec<_> = generator_args
|
||||
.prefix_tys()
|
||||
.zip(common_upvar_names)
|
||||
.enumerate()
|
||||
|
@ -175,7 +175,7 @@ pub(super) fn build_generator_di_node<'ll, 'tcx>(
|
||||
.indices()
|
||||
.map(|variant_index| {
|
||||
// FIXME: This is problematic because just a number is not a valid identifier.
|
||||
// GeneratorSubsts::variant_name(variant_index), would be consistent
|
||||
// GeneratorArgs::variant_name(variant_index), would be consistent
|
||||
// with enums?
|
||||
let variant_name = format!("{}", variant_index.as_usize()).into();
|
||||
|
||||
|
@ -27,7 +27,7 @@ use rustc_hir::def_id::{DefId, DefIdMap};
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TypeVisitableExt};
|
||||
use rustc_session::config::{self, DebugInfo};
|
||||
use rustc_session::Session;
|
||||
@ -338,19 +338,19 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
// Find the enclosing function, in case this is a closure.
|
||||
let enclosing_fn_def_id = tcx.typeck_root_def_id(def_id);
|
||||
|
||||
// We look up the generics of the enclosing function and truncate the substs
|
||||
// We look up the generics of the enclosing function and truncate the args
|
||||
// to their length in order to cut off extra stuff that might be in there for
|
||||
// closures or generators.
|
||||
let generics = tcx.generics_of(enclosing_fn_def_id);
|
||||
let substs = instance.substs.truncate_to(tcx, generics);
|
||||
let args = instance.args.truncate_to(tcx, generics);
|
||||
|
||||
type_names::push_generic_params(
|
||||
tcx,
|
||||
tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substs),
|
||||
tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args),
|
||||
&mut name,
|
||||
);
|
||||
|
||||
let template_parameters = get_template_parameters(self, generics, substs);
|
||||
let template_parameters = get_template_parameters(self, generics, args);
|
||||
|
||||
let linkage_name = &mangled_name_of_instance(self, instance).name;
|
||||
// Omit the linkage_name if it is the same as subprogram name.
|
||||
@ -471,16 +471,16 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
fn get_template_parameters<'ll, 'tcx>(
|
||||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
generics: &ty::Generics,
|
||||
substs: SubstsRef<'tcx>,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
) -> &'ll DIArray {
|
||||
if substs.types().next().is_none() {
|
||||
if args.types().next().is_none() {
|
||||
return create_DIArray(DIB(cx), &[]);
|
||||
}
|
||||
|
||||
// Again, only create type information if full debuginfo is enabled
|
||||
let template_params: Vec<_> = if cx.sess().opts.debuginfo == DebugInfo::Full {
|
||||
let names = get_parameter_names(cx, generics);
|
||||
iter::zip(substs, names)
|
||||
iter::zip(args, names)
|
||||
.filter_map(|(kind, name)| {
|
||||
kind.as_type().map(|ty| {
|
||||
let actual_type =
|
||||
@ -527,7 +527,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
// If the method does *not* belong to a trait, proceed
|
||||
if cx.tcx.trait_id_of_impl(impl_def_id).is_none() {
|
||||
let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions(
|
||||
instance.substs,
|
||||
instance.args,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
cx.tcx.type_of(impl_def_id),
|
||||
);
|
||||
|
@ -90,7 +90,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
||||
let tcx = self.tcx;
|
||||
let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
|
||||
|
||||
let ty::FnDef(def_id, substs) = *callee_ty.kind() else {
|
||||
let ty::FnDef(def_id, fn_args) = *callee_ty.kind() else {
|
||||
bug!("expected fn item type, found {}", callee_ty);
|
||||
};
|
||||
|
||||
@ -163,7 +163,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
||||
}
|
||||
|
||||
sym::volatile_load | sym::unaligned_volatile_load => {
|
||||
let tp_ty = substs.type_at(0);
|
||||
let tp_ty = fn_args.type_at(0);
|
||||
let ptr = args[0].immediate();
|
||||
let load = if let PassMode::Cast(ty, _) = &fn_abi.ret.mode {
|
||||
let llty = ty.llvm_type(self);
|
||||
@ -298,7 +298,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
||||
|
||||
sym::raw_eq => {
|
||||
use abi::Abi::*;
|
||||
let tp_ty = substs.type_at(0);
|
||||
let tp_ty = fn_args.type_at(0);
|
||||
let layout = self.layout_of(tp_ty).layout;
|
||||
let use_integer_compare = match layout.abi() {
|
||||
Scalar(_) | ScalarPair(_, _) => true,
|
||||
|
@ -48,7 +48,7 @@ impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'_, 'tcx> {
|
||||
visibility: Visibility,
|
||||
symbol_name: &str,
|
||||
) {
|
||||
assert!(!instance.substs.has_infer());
|
||||
assert!(!instance.args.has_infer());
|
||||
|
||||
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
|
||||
let lldecl = self.declare_fn(symbol_name, fn_abi, Some(instance));
|
||||
|
@ -57,7 +57,7 @@ fn uncached_llvm_type<'a, 'tcx>(
|
||||
if let (&ty::Generator(_, _, _), &Variants::Single { index }) =
|
||||
(layout.ty.kind(), &layout.variants)
|
||||
{
|
||||
write!(&mut name, "::{}", ty::GeneratorSubsts::variant_name(index)).unwrap();
|
||||
write!(&mut name, "::{}", ty::GeneratorArgs::variant_name(index)).unwrap();
|
||||
}
|
||||
Some(name)
|
||||
}
|
||||
@ -336,7 +336,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
|
||||
}
|
||||
// only wide pointer boxes are handled as pointers
|
||||
// thin pointer boxes with scalar allocators are handled by the general logic below
|
||||
ty::Adt(def, substs) if def.is_box() && cx.layout_of(substs.type_at(1)).is_zst() => {
|
||||
ty::Adt(def, args) if def.is_box() && cx.layout_of(args.type_at(1)).is_zst() => {
|
||||
let ptr_ty = Ty::new_mut_ptr(cx.tcx, self.ty.boxed_ty());
|
||||
return cx.layout_of(ptr_ty).scalar_pair_element_llvm_type(cx, index, immediate);
|
||||
}
|
||||
|
@ -12,9 +12,9 @@ use rustc_middle::middle::exported_symbols::{
|
||||
};
|
||||
use rustc_middle::query::LocalCrate;
|
||||
use rustc_middle::query::{ExternProviders, Providers};
|
||||
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
|
||||
use rustc_middle::ty::Instance;
|
||||
use rustc_middle::ty::{self, SymbolName, TyCtxt};
|
||||
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
|
||||
use rustc_session::config::{CrateType, OomStrategy};
|
||||
use rustc_target::spec::SanitizerSet;
|
||||
|
||||
@ -342,9 +342,9 @@ fn exported_symbols_provider_local(
|
||||
}
|
||||
|
||||
match *mono_item {
|
||||
MonoItem::Fn(Instance { def: InstanceDef::Item(def), substs }) => {
|
||||
if substs.non_erasable_generics().next().is_some() {
|
||||
let symbol = ExportedSymbol::Generic(def, substs);
|
||||
MonoItem::Fn(Instance { def: InstanceDef::Item(def), args }) => {
|
||||
if args.non_erasable_generics().next().is_some() {
|
||||
let symbol = ExportedSymbol::Generic(def, args);
|
||||
symbols.push((
|
||||
symbol,
|
||||
SymbolExportInfo {
|
||||
@ -355,10 +355,10 @@ fn exported_symbols_provider_local(
|
||||
));
|
||||
}
|
||||
}
|
||||
MonoItem::Fn(Instance { def: InstanceDef::DropGlue(_, Some(ty)), substs }) => {
|
||||
MonoItem::Fn(Instance { def: InstanceDef::DropGlue(_, Some(ty)), args }) => {
|
||||
// A little sanity-check
|
||||
debug_assert_eq!(
|
||||
substs.non_erasable_generics().next(),
|
||||
args.non_erasable_generics().next(),
|
||||
Some(GenericArgKind::Type(ty))
|
||||
);
|
||||
symbols.push((
|
||||
@ -386,7 +386,7 @@ fn exported_symbols_provider_local(
|
||||
fn upstream_monomorphizations_provider(
|
||||
tcx: TyCtxt<'_>,
|
||||
(): (),
|
||||
) -> DefIdMap<FxHashMap<SubstsRef<'_>, CrateNum>> {
|
||||
) -> DefIdMap<FxHashMap<GenericArgsRef<'_>, CrateNum>> {
|
||||
let cnums = tcx.crates(());
|
||||
|
||||
let mut instances: DefIdMap<FxHashMap<_, _>> = Default::default();
|
||||
@ -395,11 +395,11 @@ fn upstream_monomorphizations_provider(
|
||||
|
||||
for &cnum in cnums.iter() {
|
||||
for (exported_symbol, _) in tcx.exported_symbols(cnum).iter() {
|
||||
let (def_id, substs) = match *exported_symbol {
|
||||
ExportedSymbol::Generic(def_id, substs) => (def_id, substs),
|
||||
let (def_id, args) = match *exported_symbol {
|
||||
ExportedSymbol::Generic(def_id, args) => (def_id, args),
|
||||
ExportedSymbol::DropGlue(ty) => {
|
||||
if let Some(drop_in_place_fn_def_id) = drop_in_place_fn_def_id {
|
||||
(drop_in_place_fn_def_id, tcx.mk_substs(&[ty.into()]))
|
||||
(drop_in_place_fn_def_id, tcx.mk_args(&[ty.into()]))
|
||||
} else {
|
||||
// `drop_in_place` in place does not exist, don't try
|
||||
// to use it.
|
||||
@ -414,9 +414,9 @@ fn upstream_monomorphizations_provider(
|
||||
}
|
||||
};
|
||||
|
||||
let substs_map = instances.entry(def_id).or_default();
|
||||
let args_map = instances.entry(def_id).or_default();
|
||||
|
||||
match substs_map.entry(substs) {
|
||||
match args_map.entry(args) {
|
||||
Occupied(mut e) => {
|
||||
// If there are multiple monomorphizations available,
|
||||
// we select one deterministically.
|
||||
@ -438,17 +438,17 @@ fn upstream_monomorphizations_provider(
|
||||
fn upstream_monomorphizations_for_provider(
|
||||
tcx: TyCtxt<'_>,
|
||||
def_id: DefId,
|
||||
) -> Option<&FxHashMap<SubstsRef<'_>, CrateNum>> {
|
||||
) -> Option<&FxHashMap<GenericArgsRef<'_>, CrateNum>> {
|
||||
debug_assert!(!def_id.is_local());
|
||||
tcx.upstream_monomorphizations(()).get(&def_id)
|
||||
}
|
||||
|
||||
fn upstream_drop_glue_for_provider<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
) -> Option<CrateNum> {
|
||||
if let Some(def_id) = tcx.lang_items().drop_in_place_fn() {
|
||||
tcx.upstream_monomorphizations_for(def_id).and_then(|monos| monos.get(&substs).cloned())
|
||||
tcx.upstream_monomorphizations_for(def_id).and_then(|monos| monos.get(&args).cloned())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -521,10 +521,10 @@ pub fn symbol_name_for_instance_in_crate<'tcx>(
|
||||
instantiating_crate,
|
||||
)
|
||||
}
|
||||
ExportedSymbol::Generic(def_id, substs) => {
|
||||
ExportedSymbol::Generic(def_id, args) => {
|
||||
rustc_symbol_mangling::symbol_name_for_instance_in_crate(
|
||||
tcx,
|
||||
Instance::new(def_id, substs),
|
||||
Instance::new(def_id, args),
|
||||
instantiating_crate,
|
||||
)
|
||||
}
|
||||
@ -533,7 +533,7 @@ pub fn symbol_name_for_instance_in_crate<'tcx>(
|
||||
tcx,
|
||||
ty::Instance {
|
||||
def: ty::InstanceDef::ThreadLocalShim(def_id),
|
||||
substs: ty::InternalSubsts::empty(),
|
||||
args: ty::GenericArgs::empty(),
|
||||
},
|
||||
instantiating_crate,
|
||||
)
|
||||
@ -580,7 +580,7 @@ pub fn linking_symbol_name_for_instance_in_crate<'tcx>(
|
||||
None
|
||||
}
|
||||
ExportedSymbol::NonGeneric(def_id) => Some(Instance::mono(tcx, def_id)),
|
||||
ExportedSymbol::Generic(def_id, substs) => Some(Instance::new(def_id, substs)),
|
||||
ExportedSymbol::Generic(def_id, args) => Some(Instance::new(def_id, args)),
|
||||
// DropGlue always use the Rust calling convention and thus follow the target's default
|
||||
// symbol decoration scheme.
|
||||
ExportedSymbol::DropGlue(..) => None,
|
||||
|
@ -499,7 +499,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
cx.tcx(),
|
||||
ty::ParamEnv::reveal_all(),
|
||||
start_def_id,
|
||||
cx.tcx().mk_substs(&[main_ret_ty.into()]),
|
||||
cx.tcx().mk_args(&[main_ret_ty.into()]),
|
||||
)
|
||||
.unwrap()
|
||||
.unwrap(),
|
||||
|
@ -17,8 +17,8 @@ use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData};
|
||||
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Mutability};
|
||||
use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
|
||||
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
|
||||
use rustc_middle::ty::{self, ExistentialProjection, ParamEnv, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
|
||||
use rustc_target::abi::Integer;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
@ -77,7 +77,7 @@ fn push_debuginfo_type_name<'tcx>(
|
||||
ty::Uint(uint_ty) => output.push_str(uint_ty.name_str()),
|
||||
ty::Float(float_ty) => output.push_str(float_ty.name_str()),
|
||||
ty::Foreign(def_id) => push_item_name(tcx, def_id, qualified, output),
|
||||
ty::Adt(def, substs) => {
|
||||
ty::Adt(def, args) => {
|
||||
// `layout_for_cpp_like_fallback` will be `Some` if we want to use the fallback encoding.
|
||||
let layout_for_cpp_like_fallback = if cpp_like_debuginfo && def.is_enum() {
|
||||
match tcx.layout_of(ParamEnv::reveal_all().and(t)) {
|
||||
@ -106,14 +106,14 @@ fn push_debuginfo_type_name<'tcx>(
|
||||
ty_and_layout,
|
||||
&|output, visited| {
|
||||
push_item_name(tcx, def.did(), true, output);
|
||||
push_generic_params_internal(tcx, substs, output, visited);
|
||||
push_generic_params_internal(tcx, args, output, visited);
|
||||
},
|
||||
output,
|
||||
visited,
|
||||
);
|
||||
} else {
|
||||
push_item_name(tcx, def.did(), qualified, output);
|
||||
push_generic_params_internal(tcx, substs, output, visited);
|
||||
push_generic_params_internal(tcx, args, output, visited);
|
||||
}
|
||||
}
|
||||
ty::Tuple(component_types) => {
|
||||
@ -238,7 +238,7 @@ fn push_debuginfo_type_name<'tcx>(
|
||||
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), principal);
|
||||
push_item_name(tcx, principal.def_id, qualified, output);
|
||||
let principal_has_generic_params =
|
||||
push_generic_params_internal(tcx, principal.substs, output, visited);
|
||||
push_generic_params_internal(tcx, principal.args, output, visited);
|
||||
|
||||
let projection_bounds: SmallVec<[_; 4]> = trait_data
|
||||
.projection_bounds()
|
||||
@ -393,7 +393,7 @@ fn push_debuginfo_type_name<'tcx>(
|
||||
// processing
|
||||
visited.remove(&t);
|
||||
}
|
||||
ty::Closure(def_id, substs) | ty::Generator(def_id, substs, ..) => {
|
||||
ty::Closure(def_id, args) | ty::Generator(def_id, args, ..) => {
|
||||
// Name will be "{closure_env#0}<T1, T2, ...>", "{generator_env#0}<T1, T2, ...>", or
|
||||
// "{async_fn_env#0}<T1, T2, ...>", etc.
|
||||
// In the case of cpp-like debuginfo, the name additionally gets wrapped inside of
|
||||
@ -403,13 +403,13 @@ fn push_debuginfo_type_name<'tcx>(
|
||||
msvc_enum_fallback(
|
||||
ty_and_layout,
|
||||
&|output, visited| {
|
||||
push_closure_or_generator_name(tcx, def_id, substs, true, output, visited);
|
||||
push_closure_or_generator_name(tcx, def_id, args, true, output, visited);
|
||||
},
|
||||
output,
|
||||
visited,
|
||||
);
|
||||
} else {
|
||||
push_closure_or_generator_name(tcx, def_id, substs, qualified, output, visited);
|
||||
push_closure_or_generator_name(tcx, def_id, args, qualified, output, visited);
|
||||
}
|
||||
}
|
||||
// Type parameters from polymorphized functions.
|
||||
@ -516,7 +516,7 @@ pub fn compute_debuginfo_vtable_name<'tcx>(
|
||||
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), trait_ref);
|
||||
push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name);
|
||||
visited.clear();
|
||||
push_generic_params_internal(tcx, trait_ref.substs, &mut vtable_name, &mut visited);
|
||||
push_generic_params_internal(tcx, trait_ref.args, &mut vtable_name, &mut visited);
|
||||
} else {
|
||||
vtable_name.push('_');
|
||||
}
|
||||
@ -609,21 +609,21 @@ fn push_unqualified_item_name(
|
||||
|
||||
fn push_generic_params_internal<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
output: &mut String,
|
||||
visited: &mut FxHashSet<Ty<'tcx>>,
|
||||
) -> bool {
|
||||
if substs.non_erasable_generics().next().is_none() {
|
||||
if args.non_erasable_generics().next().is_none() {
|
||||
return false;
|
||||
}
|
||||
|
||||
debug_assert_eq!(substs, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substs));
|
||||
debug_assert_eq!(args, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args));
|
||||
|
||||
let cpp_like_debuginfo = cpp_like_debuginfo(tcx);
|
||||
|
||||
output.push('<');
|
||||
|
||||
for type_parameter in substs.non_erasable_generics() {
|
||||
for type_parameter in args.non_erasable_generics() {
|
||||
match type_parameter {
|
||||
GenericArgKind::Type(type_parameter) => {
|
||||
push_debuginfo_type_name(tcx, type_parameter, true, output, visited);
|
||||
@ -688,16 +688,20 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub fn push_generic_params<'tcx>(tcx: TyCtxt<'tcx>, substs: SubstsRef<'tcx>, output: &mut String) {
|
||||
pub fn push_generic_params<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
output: &mut String,
|
||||
) {
|
||||
let _prof = tcx.prof.generic_activity("compute_debuginfo_type_name");
|
||||
let mut visited = FxHashSet::default();
|
||||
push_generic_params_internal(tcx, substs, output, &mut visited);
|
||||
push_generic_params_internal(tcx, args, output, &mut visited);
|
||||
}
|
||||
|
||||
fn push_closure_or_generator_name<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: DefId,
|
||||
substs: SubstsRef<'tcx>,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
qualified: bool,
|
||||
output: &mut String,
|
||||
visited: &mut FxHashSet<Ty<'tcx>>,
|
||||
@ -731,10 +735,10 @@ fn push_closure_or_generator_name<'tcx>(
|
||||
let enclosing_fn_def_id = tcx.typeck_root_def_id(def_id);
|
||||
let generics = tcx.generics_of(enclosing_fn_def_id);
|
||||
|
||||
// Truncate the substs to the length of the above generics. This will cut off
|
||||
// Truncate the args to the length of the above generics. This will cut off
|
||||
// anything closure- or generator-specific.
|
||||
let substs = substs.truncate_to(tcx, generics);
|
||||
push_generic_params_internal(tcx, substs, output, visited);
|
||||
let args = args.truncate_to(tcx, generics);
|
||||
push_generic_params_internal(tcx, args, output, visited);
|
||||
}
|
||||
|
||||
fn push_close_angle_bracket(cpp_like_debuginfo: bool, output: &mut String) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::traits::*;
|
||||
|
||||
use rustc_middle::ty::{self, subst::GenericArgKind, Ty};
|
||||
use rustc_middle::ty::{self, GenericArgKind, Ty};
|
||||
use rustc_session::config::Lto;
|
||||
use rustc_symbol_mangling::typeid_for_trait_ref;
|
||||
use rustc_target::abi::call::FnAbi;
|
||||
|
@ -491,7 +491,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
//
|
||||
let virtual_drop = Instance {
|
||||
def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
|
||||
substs: drop_fn.substs,
|
||||
args: drop_fn.args,
|
||||
};
|
||||
debug!("ty = {:?}", ty);
|
||||
debug!("drop_fn = {:?}", drop_fn);
|
||||
@ -531,7 +531,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
// SO THEN WE CAN USE THE ABOVE CODE.
|
||||
let virtual_drop = Instance {
|
||||
def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
|
||||
substs: drop_fn.substs,
|
||||
args: drop_fn.args,
|
||||
};
|
||||
debug!("ty = {:?}", ty);
|
||||
debug!("drop_fn = {:?}", drop_fn);
|
||||
@ -687,7 +687,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
// which mentions the offending type, even from a const context.
|
||||
let panic_intrinsic = intrinsic.and_then(|s| ValidityRequirement::from_intrinsic(s));
|
||||
if let Some(requirement) = panic_intrinsic {
|
||||
let ty = instance.unwrap().substs.type_at(0);
|
||||
let ty = instance.unwrap().args.type_at(0);
|
||||
|
||||
let do_panic = !bx
|
||||
.tcx()
|
||||
@ -760,13 +760,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
let callee = self.codegen_operand(bx, func);
|
||||
|
||||
let (instance, mut llfn) = match *callee.layout.ty.kind() {
|
||||
ty::FnDef(def_id, substs) => (
|
||||
ty::FnDef(def_id, args) => (
|
||||
Some(
|
||||
ty::Instance::expect_resolve(
|
||||
bx.tcx(),
|
||||
ty::ParamEnv::reveal_all(),
|
||||
def_id,
|
||||
substs,
|
||||
args,
|
||||
)
|
||||
.polymorphize(bx.tcx()),
|
||||
),
|
||||
@ -1125,12 +1125,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
}
|
||||
mir::InlineAsmOperand::SymFn { ref value } => {
|
||||
let literal = self.monomorphize(value.literal);
|
||||
if let ty::FnDef(def_id, substs) = *literal.ty().kind() {
|
||||
if let ty::FnDef(def_id, args) = *literal.ty().kind() {
|
||||
let instance = ty::Instance::resolve_for_fn_ptr(
|
||||
bx.tcx(),
|
||||
ty::ParamEnv::reveal_all(),
|
||||
def_id,
|
||||
substs,
|
||||
args,
|
||||
)
|
||||
.unwrap();
|
||||
InlineAsmOperandRef::SymFn { instance }
|
||||
|
@ -64,7 +64,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
) {
|
||||
let callee_ty = instance.ty(bx.tcx(), ty::ParamEnv::reveal_all());
|
||||
|
||||
let ty::FnDef(def_id, substs) = *callee_ty.kind() else {
|
||||
let ty::FnDef(def_id, fn_args) = *callee_ty.kind() else {
|
||||
bug!("expected fn item type, found {}", callee_ty);
|
||||
};
|
||||
|
||||
@ -87,7 +87,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
sym::va_start => bx.va_start(args[0].immediate()),
|
||||
sym::va_end => bx.va_end(args[0].immediate()),
|
||||
sym::size_of_val => {
|
||||
let tp_ty = substs.type_at(0);
|
||||
let tp_ty = fn_args.type_at(0);
|
||||
if let OperandValue::Pair(_, meta) = args[0].val {
|
||||
let (llsize, _) = glue::size_and_align_of_dst(bx, tp_ty, Some(meta));
|
||||
llsize
|
||||
@ -96,7 +96,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
}
|
||||
}
|
||||
sym::min_align_of_val => {
|
||||
let tp_ty = substs.type_at(0);
|
||||
let tp_ty = fn_args.type_at(0);
|
||||
if let OperandValue::Pair(_, meta) = args[0].val {
|
||||
let (_, llalign) = glue::size_and_align_of_dst(bx, tp_ty, Some(meta));
|
||||
llalign
|
||||
@ -136,7 +136,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
OperandRef::from_const(bx, value, ret_ty).immediate_or_packed_pair(bx)
|
||||
}
|
||||
sym::arith_offset => {
|
||||
let ty = substs.type_at(0);
|
||||
let ty = fn_args.type_at(0);
|
||||
let layout = bx.layout_of(ty);
|
||||
let ptr = args[0].immediate();
|
||||
let offset = args[1].immediate();
|
||||
@ -147,7 +147,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
bx,
|
||||
true,
|
||||
false,
|
||||
substs.type_at(0),
|
||||
fn_args.type_at(0),
|
||||
args[1].immediate(),
|
||||
args[0].immediate(),
|
||||
args[2].immediate(),
|
||||
@ -158,7 +158,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
memset_intrinsic(
|
||||
bx,
|
||||
false,
|
||||
substs.type_at(0),
|
||||
fn_args.type_at(0),
|
||||
args[0].immediate(),
|
||||
args[1].immediate(),
|
||||
args[2].immediate(),
|
||||
@ -171,7 +171,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
bx,
|
||||
false,
|
||||
true,
|
||||
substs.type_at(0),
|
||||
fn_args.type_at(0),
|
||||
args[0].immediate(),
|
||||
args[1].immediate(),
|
||||
args[2].immediate(),
|
||||
@ -183,7 +183,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
bx,
|
||||
true,
|
||||
true,
|
||||
substs.type_at(0),
|
||||
fn_args.type_at(0),
|
||||
args[0].immediate(),
|
||||
args[1].immediate(),
|
||||
args[2].immediate(),
|
||||
@ -194,7 +194,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
memset_intrinsic(
|
||||
bx,
|
||||
true,
|
||||
substs.type_at(0),
|
||||
fn_args.type_at(0),
|
||||
args[0].immediate(),
|
||||
args[1].immediate(),
|
||||
args[2].immediate(),
|
||||
@ -307,7 +307,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
let Some((success, failure)) = ordering.split_once('_') else {
|
||||
bx.sess().emit_fatal(errors::AtomicCompareExchange);
|
||||
};
|
||||
let ty = substs.type_at(0);
|
||||
let ty = fn_args.type_at(0);
|
||||
if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
|
||||
let weak = instruction == "cxchgweak";
|
||||
let mut dst = args[0].immediate();
|
||||
@ -338,7 +338,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
}
|
||||
|
||||
"load" => {
|
||||
let ty = substs.type_at(0);
|
||||
let ty = fn_args.type_at(0);
|
||||
if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
|
||||
let layout = bx.layout_of(ty);
|
||||
let size = layout.size;
|
||||
@ -361,7 +361,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
}
|
||||
|
||||
"store" => {
|
||||
let ty = substs.type_at(0);
|
||||
let ty = fn_args.type_at(0);
|
||||
if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
|
||||
let size = bx.layout_of(ty).size;
|
||||
let mut val = args[1].immediate();
|
||||
@ -407,7 +407,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
_ => bx.sess().emit_fatal(errors::UnknownAtomicOperation),
|
||||
};
|
||||
|
||||
let ty = substs.type_at(0);
|
||||
let ty = fn_args.type_at(0);
|
||||
if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
|
||||
let mut ptr = args[0].immediate();
|
||||
let mut val = args[1].immediate();
|
||||
@ -439,7 +439,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
}
|
||||
|
||||
sym::ptr_offset_from | sym::ptr_offset_from_unsigned => {
|
||||
let ty = substs.type_at(0);
|
||||
let ty = fn_args.type_at(0);
|
||||
let pointee_size = bx.layout_of(ty).size;
|
||||
|
||||
let a = args[0].immediate();
|
||||
|
@ -159,7 +159,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
cx: &'a Bx::CodegenCx,
|
||||
instance: Instance<'tcx>,
|
||||
) {
|
||||
assert!(!instance.substs.has_infer());
|
||||
assert!(!instance.args.has_infer());
|
||||
|
||||
let llfn = cx.get_fn(instance);
|
||||
|
||||
|
@ -417,12 +417,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
}
|
||||
mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
|
||||
match *operand.layout.ty.kind() {
|
||||
ty::FnDef(def_id, substs) => {
|
||||
ty::FnDef(def_id, args) => {
|
||||
let instance = ty::Instance::resolve_for_fn_ptr(
|
||||
bx.tcx(),
|
||||
ty::ParamEnv::reveal_all(),
|
||||
def_id,
|
||||
substs,
|
||||
args,
|
||||
)
|
||||
.unwrap()
|
||||
.polymorphize(bx.cx().tcx());
|
||||
@ -433,11 +433,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
}
|
||||
mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)) => {
|
||||
match *operand.layout.ty.kind() {
|
||||
ty::Closure(def_id, substs) => {
|
||||
ty::Closure(def_id, args) => {
|
||||
let instance = Instance::resolve_closure(
|
||||
bx.cx().tcx(),
|
||||
def_id,
|
||||
substs,
|
||||
args,
|
||||
ty::ClosureKind::FnOnce,
|
||||
)
|
||||
.expect("failed to normalize and resolve closure during codegen")
|
||||
@ -711,7 +711,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
{
|
||||
let instance = ty::Instance {
|
||||
def: ty::InstanceDef::ThreadLocalShim(def_id),
|
||||
substs: ty::InternalSubsts::empty(),
|
||||
args: ty::GenericArgs::empty(),
|
||||
};
|
||||
let fn_ptr = bx.get_fn_addr(instance);
|
||||
let fn_abi = bx.fn_abi_of_instance(instance, ty::List::empty());
|
||||
|
@ -64,7 +64,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
|
||||
.typeck_body(anon_const.body)
|
||||
.node_type(anon_const.hir_id);
|
||||
let instance = match ty.kind() {
|
||||
&ty::FnDef(def_id, substs) => Instance::new(def_id, substs),
|
||||
&ty::FnDef(def_id, args) => Instance::new(def_id, args),
|
||||
_ => span_bug!(*op_sp, "asm sym is not a function"),
|
||||
};
|
||||
|
||||
@ -138,7 +138,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
|
||||
fn to_raw_string(&self) -> String {
|
||||
match *self {
|
||||
MonoItem::Fn(instance) => {
|
||||
format!("Fn({:?}, {})", instance.def, instance.substs.as_ptr().addr())
|
||||
format!("Fn({:?}, {})", instance.def, instance.args.as_ptr().addr())
|
||||
}
|
||||
MonoItem::Static(id) => format!("Static({:?})", id),
|
||||
MonoItem::GlobalAsm(id) => format!("GlobalAsm({:?})", id),
|
||||
|
@ -45,7 +45,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
|
||||
"Unexpected DefKind: {:?}",
|
||||
ecx.tcx.def_kind(cid.instance.def_id())
|
||||
);
|
||||
let layout = ecx.layout_of(body.bound_return_ty().subst(tcx, cid.instance.substs))?;
|
||||
let layout = ecx.layout_of(body.bound_return_ty().instantiate(tcx, cid.instance.args))?;
|
||||
assert!(layout.is_sized());
|
||||
let ret = ecx.allocate(layout, MemoryKind::Stack)?;
|
||||
|
||||
@ -245,10 +245,10 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
|
||||
// Catch such calls and evaluate them instead of trying to load a constant's MIR.
|
||||
if let ty::InstanceDef::Intrinsic(def_id) = key.value.instance.def {
|
||||
let ty = key.value.instance.ty(tcx, key.param_env);
|
||||
let ty::FnDef(_, substs) = ty.kind() else {
|
||||
let ty::FnDef(_, args) = ty.kind() else {
|
||||
bug!("intrinsic with type {:?}", ty);
|
||||
};
|
||||
return eval_nullary_intrinsic(tcx, key.param_env, def_id, substs).map_err(|error| {
|
||||
return eval_nullary_intrinsic(tcx, key.param_env, def_id, args).map_err(|error| {
|
||||
let span = tcx.def_span(def_id);
|
||||
|
||||
super::report(
|
||||
@ -328,10 +328,10 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
|
||||
("static", String::new())
|
||||
} else {
|
||||
// If the current item has generics, we'd like to enrich the message with the
|
||||
// instance and its substs: to show the actual compile-time values, in addition to
|
||||
// instance and its args: to show the actual compile-time values, in addition to
|
||||
// the expression, leading to the const eval error.
|
||||
let instance = &key.value.instance;
|
||||
if !instance.substs.is_empty() {
|
||||
if !instance.args.is_empty() {
|
||||
let instance = with_no_trimmed_paths!(instance.to_string());
|
||||
("const_with_path", instance)
|
||||
} else {
|
||||
|
@ -230,7 +230,7 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> {
|
||||
*self.tcx,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
const_def_id,
|
||||
instance.substs,
|
||||
instance.args,
|
||||
)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
@ -105,7 +105,7 @@ pub(crate) fn try_destructure_mir_constant_for_diagnostics<'tcx>(
|
||||
let down = ecx.operand_downcast(&op, variant).ok()?;
|
||||
(def.variants()[variant].fields.len(), Some(variant), down)
|
||||
}
|
||||
ty::Tuple(substs) => (substs.len(), None, op),
|
||||
ty::Tuple(args) => (args.len(), None, op),
|
||||
_ => bug!("cannot destructure mir constant {:?}", val),
|
||||
};
|
||||
|
||||
|
@ -416,9 +416,9 @@ fn valtree_into_mplace<'tcx>(
|
||||
debug!(?unsized_inner_ty);
|
||||
|
||||
let inner_ty = match ty.kind() {
|
||||
ty::Adt(def, substs) => {
|
||||
ty::Adt(def, args) => {
|
||||
let i = FieldIdx::from_usize(i);
|
||||
def.variant(FIRST_VARIANT).fields[i].ty(tcx, substs)
|
||||
def.variant(FIRST_VARIANT).fields[i].ty(tcx, args)
|
||||
}
|
||||
ty::Tuple(inner_tys) => inner_tys[i],
|
||||
_ => bug!("unexpected unsized type {:?}", ty),
|
||||
|
@ -75,12 +75,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
|
||||
// The src operand does not matter, just its type
|
||||
match *src.layout.ty.kind() {
|
||||
ty::FnDef(def_id, substs) => {
|
||||
ty::FnDef(def_id, args) => {
|
||||
let instance = ty::Instance::resolve_for_fn_ptr(
|
||||
*self.tcx,
|
||||
self.param_env,
|
||||
def_id,
|
||||
substs,
|
||||
args,
|
||||
)
|
||||
.ok_or_else(|| err_inval!(TooGeneric))?;
|
||||
|
||||
@ -108,11 +108,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
|
||||
// The src operand does not matter, just its type
|
||||
match *src.layout.ty.kind() {
|
||||
ty::Closure(def_id, substs) => {
|
||||
ty::Closure(def_id, args) => {
|
||||
let instance = ty::Instance::resolve_closure(
|
||||
*self.tcx,
|
||||
def_id,
|
||||
substs,
|
||||
args,
|
||||
ty::ClosureKind::FnOnce,
|
||||
)
|
||||
.ok_or_else(|| err_inval!(TooGeneric))?;
|
||||
|
@ -164,11 +164,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
ty::Adt(adt, _) => {
|
||||
adt.discriminants(*self.tcx).find(|(_, var)| var.val == discr_bits)
|
||||
}
|
||||
ty::Generator(def_id, substs, _) => {
|
||||
let substs = substs.as_generator();
|
||||
substs
|
||||
.discriminants(def_id, *self.tcx)
|
||||
.find(|(_, var)| var.val == discr_bits)
|
||||
ty::Generator(def_id, args, _) => {
|
||||
let args = args.as_generator();
|
||||
args.discriminants(def_id, *self.tcx).find(|(_, var)| var.val == discr_bits)
|
||||
}
|
||||
_ => span_bug!(self.cur_span(), "tagged layout for non-adt non-generator"),
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ use rustc_middle::ty::layout::{
|
||||
self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers,
|
||||
TyAndLayout,
|
||||
};
|
||||
use rustc_middle::ty::{self, subst::SubstsRef, ParamEnv, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_mir_dataflow::storage::always_storage_live_locals;
|
||||
use rustc_session::Limit;
|
||||
use rustc_span::Span;
|
||||
@ -91,7 +91,7 @@ pub struct Frame<'mir, 'tcx, Prov: Provenance = AllocId, Extra = ()> {
|
||||
/// The MIR for the function called on this frame.
|
||||
pub body: &'mir mir::Body<'tcx>,
|
||||
|
||||
/// The def_id and substs of the current function.
|
||||
/// The def_id and args of the current function.
|
||||
pub instance: ty::Instance<'tcx>,
|
||||
|
||||
/// Extra data for the machine.
|
||||
@ -529,16 +529,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
.map_err(|_| err_inval!(TooGeneric))
|
||||
}
|
||||
|
||||
/// The `substs` are assumed to already be in our interpreter "universe" (param_env).
|
||||
/// The `args` are assumed to already be in our interpreter "universe" (param_env).
|
||||
pub(super) fn resolve(
|
||||
&self,
|
||||
def: DefId,
|
||||
substs: SubstsRef<'tcx>,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
) -> InterpResult<'tcx, ty::Instance<'tcx>> {
|
||||
trace!("resolve: {:?}, {:#?}", def, substs);
|
||||
trace!("resolve: {:?}, {:#?}", def, args);
|
||||
trace!("param_env: {:#?}", self.param_env);
|
||||
trace!("substs: {:#?}", substs);
|
||||
match ty::Instance::resolve(*self.tcx, self.param_env, def, substs) {
|
||||
trace!("args: {:#?}", args);
|
||||
match ty::Instance::resolve(*self.tcx, self.param_env, def, args) {
|
||||
Ok(Some(instance)) => Ok(instance),
|
||||
Ok(None) => throw_inval!(TooGeneric),
|
||||
|
||||
@ -684,7 +684,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
return_to_block: StackPopCleanup,
|
||||
) -> InterpResult<'tcx> {
|
||||
trace!("body: {:#?}", body);
|
||||
// First push a stack frame so we have access to the local substs
|
||||
// First push a stack frame so we have access to the local args
|
||||
let pre_frame = Frame {
|
||||
body,
|
||||
loc: Right(body.span), // Span used for errors caused during preamble.
|
||||
|
@ -12,7 +12,7 @@ use rustc_middle::mir::{
|
||||
};
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::layout::{LayoutOf as _, ValidityRequirement};
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
use rustc_middle::ty::{Ty, TyCtxt};
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
use rustc_target::abi::{Abi, Align, Primitive, Size};
|
||||
@ -56,9 +56,9 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
def_id: DefId,
|
||||
substs: SubstsRef<'tcx>,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
) -> InterpResult<'tcx, ConstValue<'tcx>> {
|
||||
let tp_ty = substs.type_at(0);
|
||||
let tp_ty = args.type_at(0);
|
||||
let name = tcx.item_name(def_id);
|
||||
Ok(match name {
|
||||
sym::type_name => {
|
||||
@ -123,7 +123,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
dest: &PlaceTy<'tcx, M::Provenance>,
|
||||
ret: Option<mir::BasicBlock>,
|
||||
) -> InterpResult<'tcx, bool> {
|
||||
let substs = instance.substs;
|
||||
let instance_args = instance.args;
|
||||
let intrinsic_name = self.tcx.item_name(instance.def_id());
|
||||
|
||||
// First handle intrinsics without return place.
|
||||
@ -187,7 +187,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
| sym::ctlz_nonzero
|
||||
| sym::bswap
|
||||
| sym::bitreverse => {
|
||||
let ty = substs.type_at(0);
|
||||
let ty = instance_args.type_at(0);
|
||||
let layout_of = self.layout_of(ty)?;
|
||||
let val = self.read_scalar(&args[0])?;
|
||||
let bits = val.to_bits(layout_of.size)?;
|
||||
@ -237,7 +237,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
sym::rotate_left | sym::rotate_right => {
|
||||
// rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW))
|
||||
// rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
|
||||
let layout = self.layout_of(substs.type_at(0))?;
|
||||
let layout = self.layout_of(instance_args.type_at(0))?;
|
||||
let val = self.read_scalar(&args[0])?;
|
||||
let val_bits = val.to_bits(layout.size)?;
|
||||
let raw_shift = self.read_scalar(&args[1])?;
|
||||
@ -263,7 +263,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
sym::arith_offset => {
|
||||
let ptr = self.read_pointer(&args[0])?;
|
||||
let offset_count = self.read_target_isize(&args[1])?;
|
||||
let pointee_ty = substs.type_at(0);
|
||||
let pointee_ty = instance_args.type_at(0);
|
||||
|
||||
let pointee_size = i64::try_from(self.layout_of(pointee_ty)?.size.bytes()).unwrap();
|
||||
let offset_bytes = offset_count.wrapping_mul(pointee_size);
|
||||
@ -368,7 +368,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
assert!(self.target_isize_min() <= dist && dist <= self.target_isize_max());
|
||||
isize_layout
|
||||
};
|
||||
let pointee_layout = self.layout_of(substs.type_at(0))?;
|
||||
let pointee_layout = self.layout_of(instance_args.type_at(0))?;
|
||||
// If ret_layout is unsigned, we checked that so is the distance, so we are good.
|
||||
let val = ImmTy::from_int(dist, ret_layout);
|
||||
let size = ImmTy::from_int(pointee_layout.size.bytes(), ret_layout);
|
||||
@ -378,7 +378,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
sym::assert_inhabited
|
||||
| sym::assert_zero_valid
|
||||
| sym::assert_mem_uninitialized_valid => {
|
||||
let ty = instance.substs.type_at(0);
|
||||
let ty = instance.args.type_at(0);
|
||||
let requirement = ValidityRequirement::from_intrinsic(intrinsic_name).unwrap();
|
||||
|
||||
let should_panic = !self
|
||||
|
@ -96,7 +96,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
let loc_ty = self
|
||||
.tcx
|
||||
.type_of(self.tcx.require_lang_item(LangItem::PanicLocation, None))
|
||||
.subst(*self.tcx, self.tcx.mk_substs(&[self.tcx.lifetimes.re_erased.into()]));
|
||||
.instantiate(*self.tcx, self.tcx.mk_args(&[self.tcx.lifetimes.re_erased.into()]));
|
||||
let loc_layout = self.layout_of(loc_ty).unwrap();
|
||||
let location = self.allocate(loc_layout, MemoryKind::CallerLocation).unwrap();
|
||||
|
||||
|
@ -590,7 +590,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
throw_inval!(AlreadyReported(reported.into()))
|
||||
}
|
||||
ty::ConstKind::Unevaluated(uv) => {
|
||||
let instance = self.resolve(uv.def, uv.substs)?;
|
||||
let instance = self.resolve(uv.def, uv.args)?;
|
||||
let cid = GlobalId { instance, promoted: None };
|
||||
self.ctfe_query(span, |tcx| {
|
||||
tcx.eval_to_valtree(self.param_env.with_const().and(cid))
|
||||
@ -619,7 +619,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
}
|
||||
mir::ConstantKind::Val(val, ty) => self.const_val_to_op(val, ty, layout),
|
||||
mir::ConstantKind::Unevaluated(uv, _) => {
|
||||
let instance = self.resolve(uv.def, uv.substs)?;
|
||||
let instance = self.resolve(uv.def, uv.args)?;
|
||||
Ok(self.eval_global(GlobalId { instance, promoted: uv.promoted }, span)?.into())
|
||||
}
|
||||
}
|
||||
|
@ -135,8 +135,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
let fn_val = self.get_ptr_fn(fn_ptr)?;
|
||||
(fn_val, self.fn_abi_of_fn_ptr(fn_sig_binder, extra_args)?, false)
|
||||
}
|
||||
ty::FnDef(def_id, substs) => {
|
||||
let instance = self.resolve(def_id, substs)?;
|
||||
ty::FnDef(def_id, args) => {
|
||||
let instance = self.resolve(def_id, args)?;
|
||||
(
|
||||
FnVal::Instance(instance),
|
||||
self.fn_abi_of_instance(instance, extra_args)?,
|
||||
@ -748,7 +748,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
|
||||
let trait_def_id = tcx.trait_of_item(def_id).unwrap();
|
||||
let virtual_trait_ref =
|
||||
ty::TraitRef::from_method(tcx, trait_def_id, instance.substs);
|
||||
ty::TraitRef::from_method(tcx, trait_def_id, instance.args);
|
||||
let existential_trait_ref =
|
||||
ty::ExistentialTraitRef::erase_self_ty(tcx, virtual_trait_ref);
|
||||
let concrete_trait_ref = existential_trait_ref.with_self_ty(tcx, dyn_ty);
|
||||
@ -757,7 +757,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
tcx,
|
||||
self.param_env,
|
||||
def_id,
|
||||
instance.substs.rebase_onto(tcx, trait_def_id, concrete_trait_ref.substs),
|
||||
instance.args.rebase_onto(tcx, trait_def_id, concrete_trait_ref.args),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(fn_inst, concrete_method);
|
||||
|
@ -33,12 +33,12 @@ where
|
||||
|
||||
match *ty.kind() {
|
||||
ty::Param(_) => ControlFlow::Break(FoundParam),
|
||||
ty::Closure(def_id, substs)
|
||||
| ty::Generator(def_id, substs, ..)
|
||||
| ty::FnDef(def_id, substs) => {
|
||||
ty::Closure(def_id, args)
|
||||
| ty::Generator(def_id, args, ..)
|
||||
| ty::FnDef(def_id, args) => {
|
||||
let instance = ty::InstanceDef::Item(def_id);
|
||||
let unused_params = self.tcx.unused_generic_params(instance);
|
||||
for (index, subst) in substs.into_iter().enumerate() {
|
||||
for (index, subst) in args.into_iter().enumerate() {
|
||||
let index = index
|
||||
.try_into()
|
||||
.expect("more generic parameters than can fit into a `u32`");
|
||||
|
@ -8,8 +8,8 @@ use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
|
||||
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
|
||||
use rustc_middle::ty::{self, adjustment::PointerCoercion, Instance, InstanceDef, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{GenericArgKind, GenericArgs};
|
||||
use rustc_middle::ty::{TraitRef, TypeVisitableExt};
|
||||
use rustc_mir_dataflow::{self, Analysis};
|
||||
use rustc_span::{sym, Span, Symbol};
|
||||
@ -701,8 +701,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
|
||||
let fn_ty = func.ty(body, tcx);
|
||||
|
||||
let (mut callee, mut substs) = match *fn_ty.kind() {
|
||||
ty::FnDef(def_id, substs) => (def_id, substs),
|
||||
let (mut callee, mut fn_args) = match *fn_ty.kind() {
|
||||
ty::FnDef(def_id, fn_args) => (def_id, fn_args),
|
||||
|
||||
ty::FnPtr(_) => {
|
||||
self.check_op(ops::FnCallIndirect);
|
||||
@ -721,7 +721,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
|
||||
let predicates = tcx.predicates_of(callee).instantiate(tcx, substs);
|
||||
let predicates = tcx.predicates_of(callee).instantiate(tcx, fn_args);
|
||||
let cause = ObligationCause::new(
|
||||
terminator.source_info.span,
|
||||
self.body.source.def_id().expect_local(),
|
||||
@ -746,7 +746,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
self.check_op(ops::FnCallNonConst {
|
||||
caller,
|
||||
callee,
|
||||
substs,
|
||||
args: fn_args,
|
||||
span: *fn_span,
|
||||
call_source: *call_source,
|
||||
feature: Some(sym::const_trait_impl),
|
||||
@ -754,7 +754,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
return;
|
||||
}
|
||||
|
||||
let trait_ref = TraitRef::from_method(tcx, trait_id, substs);
|
||||
let trait_ref = TraitRef::from_method(tcx, trait_id, fn_args);
|
||||
let trait_ref = trait_ref.with_constness(ty::BoundConstness::ConstIfConst);
|
||||
let obligation =
|
||||
Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref);
|
||||
@ -778,7 +778,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
if trait_ref.self_ty().is_closure()
|
||||
&& tcx.fn_trait_kind_from_def_id(trait_id).is_some() =>
|
||||
{
|
||||
let ty::Closure(closure_def_id, substs) = *trait_ref.self_ty().kind()
|
||||
let ty::Closure(closure_def_id, fn_args) = *trait_ref.self_ty().kind()
|
||||
else {
|
||||
unreachable!()
|
||||
};
|
||||
@ -786,7 +786,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
self.check_op(ops::FnCallNonConst {
|
||||
caller,
|
||||
callee,
|
||||
substs,
|
||||
args: fn_args,
|
||||
span: *fn_span,
|
||||
call_source: *call_source,
|
||||
feature: None,
|
||||
@ -802,9 +802,9 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
.iter()
|
||||
.find(|did| tcx.item_name(**did) == callee_name)
|
||||
{
|
||||
// using internal substs is ok here, since this is only
|
||||
// using internal args is ok here, since this is only
|
||||
// used for the `resolve` call below
|
||||
substs = InternalSubsts::identity_for_item(tcx, did);
|
||||
fn_args = GenericArgs::identity_for_item(tcx, did);
|
||||
callee = did;
|
||||
}
|
||||
|
||||
@ -812,7 +812,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
self.check_op(ops::FnCallNonConst {
|
||||
caller,
|
||||
callee,
|
||||
substs,
|
||||
args: fn_args,
|
||||
span: *fn_span,
|
||||
call_source: *call_source,
|
||||
feature: None,
|
||||
@ -828,7 +828,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
&& tcx.has_attr(callee_trait, sym::const_trait)
|
||||
&& Some(callee_trait) == tcx.trait_of_item(caller.to_def_id())
|
||||
// Can only call methods when it's `<Self as TheTrait>::f`.
|
||||
&& tcx.types.self_param == substs.type_at(0)
|
||||
&& tcx.types.self_param == fn_args.type_at(0)
|
||||
{
|
||||
nonconst_call_permission = true;
|
||||
}
|
||||
@ -855,7 +855,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
self.check_op(ops::FnCallNonConst {
|
||||
caller,
|
||||
callee,
|
||||
substs,
|
||||
args: fn_args,
|
||||
span: *fn_span,
|
||||
call_source: *call_source,
|
||||
feature: None,
|
||||
@ -868,7 +868,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
|
||||
// Resolve a trait method call to its concrete implementation, which may be in a
|
||||
// `const` trait impl.
|
||||
let instance = Instance::resolve(tcx, param_env, callee, substs);
|
||||
let instance = Instance::resolve(tcx, param_env, callee, fn_args);
|
||||
debug!("Resolving ({:?}) -> {:?}", callee, instance);
|
||||
if let Ok(Some(func)) = instance {
|
||||
if let InstanceDef::Item(def) = func.def {
|
||||
@ -915,7 +915,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
self.check_op(ops::FnCallNonConst {
|
||||
caller,
|
||||
callee,
|
||||
substs,
|
||||
args: fn_args,
|
||||
span: *fn_span,
|
||||
call_source: *call_source,
|
||||
feature: None,
|
||||
|
@ -68,11 +68,11 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> {
|
||||
pub fn fn_sig(&self) -> PolyFnSig<'tcx> {
|
||||
let did = self.def_id().to_def_id();
|
||||
if self.tcx.is_closure(did) {
|
||||
let ty = self.tcx.type_of(did).subst_identity();
|
||||
let ty::Closure(_, substs) = ty.kind() else { bug!("type_of closure not ty::Closure") };
|
||||
substs.as_closure().sig()
|
||||
let ty = self.tcx.type_of(did).instantiate_identity();
|
||||
let ty::Closure(_, args) = ty.kind() else { bug!("type_of closure not ty::Closure") };
|
||||
args.as_closure().sig()
|
||||
} else {
|
||||
self.tcx.fn_sig(did).subst_identity()
|
||||
self.tcx.fn_sig(did).instantiate_identity()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,9 +9,9 @@ use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
|
||||
use rustc_middle::mir::{self, CallSource};
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
|
||||
use rustc_middle::ty::TraitRef;
|
||||
use rustc_middle::ty::{suggest_constraining_type_param, Adt, Closure, FnDef, FnPtr, Param, Ty};
|
||||
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
|
||||
use rustc_middle::util::{call_kind, CallDesugaringKind, CallKind};
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::symbol::sym;
|
||||
@ -98,7 +98,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallIndirect {
|
||||
pub struct FnCallNonConst<'tcx> {
|
||||
pub caller: LocalDefId,
|
||||
pub callee: DefId,
|
||||
pub substs: SubstsRef<'tcx>,
|
||||
pub args: GenericArgsRef<'tcx>,
|
||||
pub span: Span,
|
||||
pub call_source: CallSource,
|
||||
pub feature: Option<Symbol>,
|
||||
@ -110,11 +110,11 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||
ccx: &ConstCx<'_, 'tcx>,
|
||||
_: Span,
|
||||
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
||||
let FnCallNonConst { caller, callee, substs, span, call_source, feature } = *self;
|
||||
let FnCallNonConst { caller, callee, args, span, call_source, feature } = *self;
|
||||
let ConstCx { tcx, param_env, .. } = *ccx;
|
||||
|
||||
let diag_trait = |err, self_ty: Ty<'_>, trait_id| {
|
||||
let trait_ref = TraitRef::from_method(tcx, trait_id, substs);
|
||||
let trait_ref = TraitRef::from_method(tcx, trait_id, args);
|
||||
|
||||
match self_ty.kind() {
|
||||
Param(param_ty) => {
|
||||
@ -154,7 +154,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||
};
|
||||
|
||||
let call_kind =
|
||||
call_kind(tcx, ccx.param_env, callee, substs, span, call_source.from_hir_call(), None);
|
||||
call_kind(tcx, ccx.param_env, callee, args, span, call_source.from_hir_call(), None);
|
||||
|
||||
debug!(?call_kind);
|
||||
|
||||
@ -226,7 +226,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||
let mut sugg = None;
|
||||
|
||||
if Some(trait_id) == ccx.tcx.lang_items().eq_trait() {
|
||||
match (substs[0].unpack(), substs[1].unpack()) {
|
||||
match (args[0].unpack(), args[1].unpack()) {
|
||||
(GenericArgKind::Type(self_ty), GenericArgKind::Type(rhs_ty))
|
||||
if self_ty == rhs_ty
|
||||
&& self_ty.is_ref()
|
||||
@ -297,7 +297,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||
.create_err(errors::NonConstFmtMacroCall { span, kind: ccx.const_kind() }),
|
||||
_ => ccx.tcx.sess.create_err(errors::NonConstFnCall {
|
||||
span,
|
||||
def_path_str: ccx.tcx.def_path_str_with_substs(callee, substs),
|
||||
def_path_str: ccx.tcx.def_path_str_with_args(callee, args),
|
||||
kind: ccx.const_kind(),
|
||||
}),
|
||||
};
|
||||
|
@ -7,7 +7,7 @@ use rustc_hir::LangItem;
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::{self, subst::SubstsRef, AdtDef, Ty};
|
||||
use rustc_middle::ty::{self, AdtDef, GenericArgsRef, Ty};
|
||||
use rustc_trait_selection::traits::{
|
||||
self, ImplSource, Obligation, ObligationCause, ObligationCtxt, SelectionContext,
|
||||
};
|
||||
@ -72,7 +72,7 @@ pub trait Qualif {
|
||||
fn in_adt_inherently<'tcx>(
|
||||
cx: &ConstCx<'_, 'tcx>,
|
||||
adt: AdtDef<'tcx>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
) -> bool;
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ impl Qualif for HasMutInterior {
|
||||
fn in_adt_inherently<'tcx>(
|
||||
_cx: &ConstCx<'_, 'tcx>,
|
||||
adt: AdtDef<'tcx>,
|
||||
_: SubstsRef<'tcx>,
|
||||
_: GenericArgsRef<'tcx>,
|
||||
) -> bool {
|
||||
// Exactly one type, `UnsafeCell`, has the `HasMutInterior` qualif inherently.
|
||||
// It arises structurally for all other types.
|
||||
@ -127,7 +127,7 @@ impl Qualif for NeedsDrop {
|
||||
fn in_adt_inherently<'tcx>(
|
||||
cx: &ConstCx<'_, 'tcx>,
|
||||
adt: AdtDef<'tcx>,
|
||||
_: SubstsRef<'tcx>,
|
||||
_: GenericArgsRef<'tcx>,
|
||||
) -> bool {
|
||||
adt.has_dtor(cx.tcx)
|
||||
}
|
||||
@ -193,7 +193,7 @@ impl Qualif for NeedsNonConstDrop {
|
||||
fn in_adt_inherently<'tcx>(
|
||||
cx: &ConstCx<'_, 'tcx>,
|
||||
adt: AdtDef<'tcx>,
|
||||
_: SubstsRef<'tcx>,
|
||||
_: GenericArgsRef<'tcx>,
|
||||
) -> bool {
|
||||
adt.has_non_const_dtor(cx.tcx)
|
||||
}
|
||||
@ -221,9 +221,9 @@ impl Qualif for CustomEq {
|
||||
fn in_adt_inherently<'tcx>(
|
||||
cx: &ConstCx<'_, 'tcx>,
|
||||
def: AdtDef<'tcx>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
) -> bool {
|
||||
let ty = Ty::new_adt(cx.tcx, def, substs);
|
||||
let ty = Ty::new_adt(cx.tcx, def, args);
|
||||
!ty.is_structural_eq_shallow(cx.tcx)
|
||||
}
|
||||
}
|
||||
@ -276,9 +276,9 @@ where
|
||||
Rvalue::Aggregate(kind, operands) => {
|
||||
// Return early if we know that the struct or enum being constructed is always
|
||||
// qualified.
|
||||
if let AggregateKind::Adt(adt_did, _, substs, ..) = **kind {
|
||||
if let AggregateKind::Adt(adt_did, _, args, ..) = **kind {
|
||||
let def = cx.tcx.adt_def(adt_did);
|
||||
if Q::in_adt_inherently(cx, def, substs) {
|
||||
if Q::in_adt_inherently(cx, def, args) {
|
||||
return true;
|
||||
}
|
||||
if def.is_union() && Q::in_any_value_of_ty(cx, rvalue.ty(cx.body, cx.tcx)) {
|
||||
@ -360,7 +360,7 @@ where
|
||||
ConstantKind::Val(..) => None,
|
||||
};
|
||||
|
||||
if let Some(mir::UnevaluatedConst { def, substs: _, promoted }) = uneval {
|
||||
if let Some(mir::UnevaluatedConst { def, args: _, promoted }) = uneval {
|
||||
// Use qualifs of the type for the promoted. Promoteds in MIR body should be possible
|
||||
// only for `NeedsNonConstDrop` with precise drop checking. This is the only const
|
||||
// check performed after the promotion. Verify that with an assertion.
|
||||
|
@ -16,7 +16,7 @@ use rustc_hir as hir;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::subst::InternalSubsts;
|
||||
use rustc_middle::ty::GenericArgs;
|
||||
use rustc_middle::ty::{self, List, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_span::Span;
|
||||
|
||||
@ -841,8 +841,8 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
||||
let mut promoted_operand = |ty, span| {
|
||||
promoted.span = span;
|
||||
promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span);
|
||||
let substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def));
|
||||
let uneval = mir::UnevaluatedConst { def, substs, promoted: Some(promoted_id) };
|
||||
let args = tcx.erase_regions(GenericArgs::identity_for_item(tcx, def));
|
||||
let uneval = mir::UnevaluatedConst { def, args, promoted: Some(promoted_id) };
|
||||
|
||||
Operand::Constant(Box::new(Constant {
|
||||
span,
|
||||
|
@ -358,8 +358,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||
};
|
||||
|
||||
let kind = match parent_ty.ty.kind() {
|
||||
&ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
|
||||
self.tcx.type_of(def_id).subst(self.tcx, substs).kind()
|
||||
&ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
|
||||
self.tcx.type_of(def_id).instantiate(self.tcx, args).kind()
|
||||
}
|
||||
kind => kind,
|
||||
};
|
||||
@ -372,23 +372,23 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||
};
|
||||
check_equal(self, location, *f_ty);
|
||||
}
|
||||
ty::Adt(adt_def, substs) => {
|
||||
ty::Adt(adt_def, args) => {
|
||||
let var = parent_ty.variant_index.unwrap_or(FIRST_VARIANT);
|
||||
let Some(field) = adt_def.variant(var).fields.get(f) else {
|
||||
fail_out_of_bounds(self, location);
|
||||
return;
|
||||
};
|
||||
check_equal(self, location, field.ty(self.tcx, substs));
|
||||
check_equal(self, location, field.ty(self.tcx, args));
|
||||
}
|
||||
ty::Closure(_, substs) => {
|
||||
let substs = substs.as_closure();
|
||||
let Some(f_ty) = substs.upvar_tys().nth(f.as_usize()) else {
|
||||
ty::Closure(_, args) => {
|
||||
let args = args.as_closure();
|
||||
let Some(f_ty) = args.upvar_tys().nth(f.as_usize()) else {
|
||||
fail_out_of_bounds(self, location);
|
||||
return;
|
||||
};
|
||||
check_equal(self, location, f_ty);
|
||||
}
|
||||
&ty::Generator(def_id, substs, _) => {
|
||||
&ty::Generator(def_id, args, _) => {
|
||||
let f_ty = if let Some(var) = parent_ty.variant_index {
|
||||
let gen_body = if def_id == self.body.source.def_id() {
|
||||
self.body
|
||||
@ -419,8 +419,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||
|
||||
f_ty.ty
|
||||
} else {
|
||||
let Some(f_ty) = substs.as_generator().prefix_tys().nth(f.index())
|
||||
else {
|
||||
let Some(f_ty) = args.as_generator().prefix_tys().nth(f.index()) else {
|
||||
fail_out_of_bounds(self, location);
|
||||
return;
|
||||
};
|
||||
@ -735,7 +734,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||
|
||||
current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty);
|
||||
}
|
||||
ty::Adt(adt_def, substs) => {
|
||||
ty::Adt(adt_def, args) => {
|
||||
if adt_def.is_enum() {
|
||||
self.fail(
|
||||
location,
|
||||
@ -749,7 +748,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||
return;
|
||||
};
|
||||
|
||||
let f_ty = field.ty(self.tcx, substs);
|
||||
let f_ty = field.ty(self.tcx, args);
|
||||
current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty);
|
||||
}
|
||||
_ => {
|
||||
|
@ -4,8 +4,7 @@ use rustc_hir::definitions::DisambiguatedDefPathData;
|
||||
use rustc_middle::ty::{
|
||||
self,
|
||||
print::{PrettyPrinter, Print, Printer},
|
||||
subst::{GenericArg, GenericArgKind},
|
||||
Ty, TyCtxt,
|
||||
GenericArg, GenericArgKind, Ty, TyCtxt,
|
||||
};
|
||||
use std::fmt::Write;
|
||||
|
||||
@ -56,11 +55,11 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
|
||||
}
|
||||
|
||||
// Types with identity (print the module path).
|
||||
ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), substs)
|
||||
| ty::FnDef(def_id, substs)
|
||||
| ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, substs, .. })
|
||||
| ty::Closure(def_id, substs)
|
||||
| ty::Generator(def_id, substs, _) => self.print_def_path(def_id, substs),
|
||||
ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), args)
|
||||
| ty::FnDef(def_id, args)
|
||||
| ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. })
|
||||
| ty::Closure(def_id, args)
|
||||
| ty::Generator(def_id, args, _) => self.print_def_path(def_id, args),
|
||||
ty::Foreign(def_id) => self.print_def_path(def_id, &[]),
|
||||
|
||||
ty::Alias(ty::Weak, _) => bug!("type_name: unexpected weak projection"),
|
||||
|
@ -812,7 +812,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
||||
TEST, rustc_error, Normal,
|
||||
template!(Word, List: "delay_span_bug_from_inside_query"), WarnFollowingWordOnly
|
||||
),
|
||||
rustc_attr!(TEST, rustc_dump_user_substs, Normal, template!(Word), WarnFollowing),
|
||||
rustc_attr!(TEST, rustc_dump_user_args, Normal, template!(Word), WarnFollowing),
|
||||
rustc_attr!(TEST, rustc_evaluate_where_clauses, Normal, template!(Word), WarnFollowing),
|
||||
rustc_attr!(
|
||||
TEST, rustc_if_this_changed, Normal, template!(Word, List: "DepNode"), DuplicatesOk
|
||||
|
@ -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);
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user