mirror of https://github.com/rust-lang/rust.git
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,
|
Body, Local, Location, Place, PlaceRef, ProjectionElem, Rvalue, SourceInfo, Statement,
|
||||||
StatementKind, Terminator, TerminatorKind, UserTypeProjection,
|
StatementKind, Terminator, TerminatorKind, UserTypeProjection,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::subst::SubstsRef;
|
|
||||||
use rustc_middle::ty::visit::TypeVisitable;
|
use rustc_middle::ty::visit::TypeVisitable;
|
||||||
|
use rustc_middle::ty::GenericArgsRef;
|
||||||
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
|
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -49,11 +49,11 @@ struct ConstraintGeneration<'cg, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'cg, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'tcx> {
|
impl<'cg, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'tcx> {
|
||||||
/// We sometimes have `substs` within an rvalue, or within a
|
/// We sometimes have `args` within an rvalue, or within a
|
||||||
/// call. Make them live at the location where they appear.
|
/// call. Make them live at the location where they appear.
|
||||||
fn visit_substs(&mut self, substs: &SubstsRef<'tcx>, location: Location) {
|
fn visit_args(&mut self, args: &GenericArgsRef<'tcx>, location: Location) {
|
||||||
self.add_regular_live_constraint(*substs, location);
|
self.add_regular_live_constraint(*args, location);
|
||||||
self.super_substs(substs);
|
self.super_args(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// We sometimes have `region` within an rvalue, or within a
|
/// We sometimes have `region` within an rvalue, or within a
|
||||||
|
|
|
@ -702,11 +702,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
.iter()
|
.iter()
|
||||||
.copied()
|
.copied()
|
||||||
.find_map(find_fn_kind_from_did),
|
.find_map(find_fn_kind_from_did),
|
||||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => tcx
|
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => tcx
|
||||||
.explicit_item_bounds(def_id)
|
.explicit_item_bounds(def_id)
|
||||||
.subst_iter_copied(tcx, substs)
|
.arg_iter_copied(tcx, args)
|
||||||
.find_map(|(clause, span)| find_fn_kind_from_did((clause, span))),
|
.find_map(|(clause, span)| find_fn_kind_from_did((clause, span))),
|
||||||
ty::Closure(_, substs) => match substs.as_closure().kind() {
|
ty::Closure(_, args) => match args.as_closure().kind() {
|
||||||
ty::ClosureKind::Fn => Some(hir::Mutability::Not),
|
ty::ClosureKind::Fn => Some(hir::Mutability::Not),
|
||||||
ty::ClosureKind::FnMut => Some(hir::Mutability::Mut),
|
ty::ClosureKind::FnMut => Some(hir::Mutability::Mut),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -1448,11 +1448,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get closure's arguments
|
// Get closure's arguments
|
||||||
let ty::Closure(_, substs) = typeck_results.expr_ty(closure_expr).kind() else {
|
let ty::Closure(_, args) = typeck_results.expr_ty(closure_expr).kind() else {
|
||||||
/* hir::Closure can be a generator too */
|
/* hir::Closure can be a generator too */
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let sig = substs.as_closure().sig();
|
let sig = args.as_closure().sig();
|
||||||
let tupled_params =
|
let tupled_params =
|
||||||
tcx.erase_late_bound_regions(sig.inputs().iter().next().unwrap().map_bound(|&b| b));
|
tcx.erase_late_bound_regions(sig.inputs().iter().next().unwrap().map_bound(|&b| b));
|
||||||
let ty::Tuple(params) = tupled_params.kind() else { return };
|
let ty::Tuple(params) = tupled_params.kind() else { return };
|
||||||
|
@ -2676,7 +2676,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
kind: TerminatorKind::Call { call_source: CallSource::OverloadedOperator, .. },
|
kind: TerminatorKind::Call { call_source: CallSource::OverloadedOperator, .. },
|
||||||
..
|
..
|
||||||
}),
|
}),
|
||||||
Some((method_did, method_substs)),
|
Some((method_did, method_args)),
|
||||||
) = (
|
) = (
|
||||||
&self.body[loan.reserve_location.block].terminator,
|
&self.body[loan.reserve_location.block].terminator,
|
||||||
rustc_middle::util::find_self_call(
|
rustc_middle::util::find_self_call(
|
||||||
|
@ -2689,7 +2689,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
if tcx.is_diagnostic_item(sym::deref_method, method_did) {
|
if tcx.is_diagnostic_item(sym::deref_method, method_did) {
|
||||||
let deref_target =
|
let deref_target =
|
||||||
tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| {
|
tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| {
|
||||||
Instance::resolve(tcx, self.param_env, deref_target, method_substs)
|
Instance::resolve(tcx, self.param_env, deref_target, method_args)
|
||||||
.transpose()
|
.transpose()
|
||||||
});
|
});
|
||||||
if let Some(Ok(instance)) = deref_target {
|
if let Some(Ok(instance)) = deref_target {
|
||||||
|
@ -2856,11 +2856,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
if is_closure {
|
if is_closure {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let ty = self.infcx.tcx.type_of(self.mir_def_id()).subst_identity();
|
let ty = self.infcx.tcx.type_of(self.mir_def_id()).instantiate_identity();
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
ty::FnDef(_, _) | ty::FnPtr(_) => self.annotate_fn_sig(
|
ty::FnDef(_, _) | ty::FnPtr(_) => self.annotate_fn_sig(
|
||||||
self.mir_def_id(),
|
self.mir_def_id(),
|
||||||
self.infcx.tcx.fn_sig(self.mir_def_id()).subst_identity(),
|
self.infcx.tcx.fn_sig(self.mir_def_id()).instantiate_identity(),
|
||||||
),
|
),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
@ -2902,7 +2902,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
);
|
);
|
||||||
// Check if our `target` was captured by a closure.
|
// Check if our `target` was captured by a closure.
|
||||||
if let Rvalue::Aggregate(
|
if let Rvalue::Aggregate(
|
||||||
box AggregateKind::Closure(def_id, substs),
|
box AggregateKind::Closure(def_id, args),
|
||||||
operands,
|
operands,
|
||||||
) = rvalue
|
) = rvalue
|
||||||
{
|
{
|
||||||
|
@ -2933,7 +2933,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
// into a place then we should annotate the closure in
|
// into a place then we should annotate the closure in
|
||||||
// case it ends up being assigned into the return place.
|
// case it ends up being assigned into the return place.
|
||||||
annotated_closure =
|
annotated_closure =
|
||||||
self.annotate_fn_sig(def_id, substs.as_closure().sig());
|
self.annotate_fn_sig(def_id, args.as_closure().sig());
|
||||||
debug!(
|
debug!(
|
||||||
"annotate_argument_and_return_for_borrow: \
|
"annotate_argument_and_return_for_borrow: \
|
||||||
annotated_closure={:?} assigned_from_local={:?} \
|
annotated_closure={:?} assigned_from_local={:?} \
|
||||||
|
|
|
@ -168,17 +168,17 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
||||||
let local_decl = &body.local_decls[dropped_local];
|
let local_decl = &body.local_decls[dropped_local];
|
||||||
let mut ty = local_decl.ty;
|
let mut ty = local_decl.ty;
|
||||||
if local_decl.source_info.span.desugaring_kind() == Some(DesugaringKind::ForLoop) {
|
if local_decl.source_info.span.desugaring_kind() == Some(DesugaringKind::ForLoop) {
|
||||||
if let ty::Adt(adt, substs) = local_decl.ty.kind() {
|
if let ty::Adt(adt, args) = local_decl.ty.kind() {
|
||||||
if tcx.is_diagnostic_item(sym::Option, adt.did()) {
|
if tcx.is_diagnostic_item(sym::Option, adt.did()) {
|
||||||
// in for loop desugaring, only look at the `Some(..)` inner type
|
// in for loop desugaring, only look at the `Some(..)` inner type
|
||||||
ty = substs.type_at(0);
|
ty = args.type_at(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let (dtor_desc, type_desc) = match ty.kind() {
|
let (dtor_desc, type_desc) = match ty.kind() {
|
||||||
// If type is an ADT that implements Drop, then
|
// If type is an ADT that implements Drop, then
|
||||||
// simplify output by reporting just the ADT name.
|
// simplify output by reporting just the ADT name.
|
||||||
ty::Adt(adt, _substs) if adt.has_dtor(tcx) && !adt.is_box() => {
|
ty::Adt(adt, _args) if adt.has_dtor(tcx) && !adt.is_box() => {
|
||||||
("`Drop` code", format!("type `{}`", tcx.def_path_str(adt.did())))
|
("`Drop` code", format!("type `{}`", tcx.def_path_str(adt.did())))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -732,18 +732,18 @@ impl<'tcx> BorrowedContentSource<'tcx> {
|
||||||
|
|
||||||
fn from_call(func: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Option<Self> {
|
fn from_call(func: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Option<Self> {
|
||||||
match *func.kind() {
|
match *func.kind() {
|
||||||
ty::FnDef(def_id, substs) => {
|
ty::FnDef(def_id, args) => {
|
||||||
let trait_id = tcx.trait_of_item(def_id)?;
|
let trait_id = tcx.trait_of_item(def_id)?;
|
||||||
|
|
||||||
let lang_items = tcx.lang_items();
|
let lang_items = tcx.lang_items();
|
||||||
if Some(trait_id) == lang_items.deref_trait()
|
if Some(trait_id) == lang_items.deref_trait()
|
||||||
|| Some(trait_id) == lang_items.deref_mut_trait()
|
|| Some(trait_id) == lang_items.deref_mut_trait()
|
||||||
{
|
{
|
||||||
Some(BorrowedContentSource::OverloadedDeref(substs.type_at(0)))
|
Some(BorrowedContentSource::OverloadedDeref(args.type_at(0)))
|
||||||
} else if Some(trait_id) == lang_items.index_trait()
|
} else if Some(trait_id) == lang_items.index_trait()
|
||||||
|| Some(trait_id) == lang_items.index_mut_trait()
|
|| Some(trait_id) == lang_items.index_mut_trait()
|
||||||
{
|
{
|
||||||
Some(BorrowedContentSource::OverloadedIndex(substs.type_at(0)))
|
Some(BorrowedContentSource::OverloadedIndex(args.type_at(0)))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -847,7 +847,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
kind: TerminatorKind::Call { fn_span, call_source, .. }, ..
|
kind: TerminatorKind::Call { fn_span, call_source, .. }, ..
|
||||||
}) = &self.body[location.block].terminator
|
}) = &self.body[location.block].terminator
|
||||||
{
|
{
|
||||||
let Some((method_did, method_substs)) = rustc_middle::util::find_self_call(
|
let Some((method_did, method_args)) = rustc_middle::util::find_self_call(
|
||||||
self.infcx.tcx,
|
self.infcx.tcx,
|
||||||
&self.body,
|
&self.body,
|
||||||
target_temp,
|
target_temp,
|
||||||
|
@ -860,7 +860,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
self.infcx.tcx,
|
self.infcx.tcx,
|
||||||
self.param_env,
|
self.param_env,
|
||||||
method_did,
|
method_did,
|
||||||
method_substs,
|
method_args,
|
||||||
*fn_span,
|
*fn_span,
|
||||||
call_source.from_hir_call(),
|
call_source.from_hir_call(),
|
||||||
Some(self.infcx.tcx.fn_arg_names(method_did)[0]),
|
Some(self.infcx.tcx.fn_arg_names(method_did)[0]),
|
||||||
|
@ -1039,7 +1039,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CallKind::Normal { self_arg, desugaring, method_did, method_substs } => {
|
CallKind::Normal { self_arg, desugaring, method_did, method_args } => {
|
||||||
let self_arg = self_arg.unwrap();
|
let self_arg = self_arg.unwrap();
|
||||||
let tcx = self.infcx.tcx;
|
let tcx = self.infcx.tcx;
|
||||||
if let Some((CallDesugaringKind::ForLoopIntoIter, _)) = desugaring {
|
if let Some((CallDesugaringKind::ForLoopIntoIter, _)) = desugaring {
|
||||||
|
@ -1106,13 +1106,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
// Erase and shadow everything that could be passed to the new infcx.
|
// Erase and shadow everything that could be passed to the new infcx.
|
||||||
let ty = moved_place.ty(self.body, tcx).ty;
|
let ty = moved_place.ty(self.body, tcx).ty;
|
||||||
|
|
||||||
if let ty::Adt(def, substs) = ty.kind()
|
if let ty::Adt(def, args) = ty.kind()
|
||||||
&& Some(def.did()) == tcx.lang_items().pin_type()
|
&& Some(def.did()) == tcx.lang_items().pin_type()
|
||||||
&& let ty::Ref(_, _, hir::Mutability::Mut) = substs.type_at(0).kind()
|
&& let ty::Ref(_, _, hir::Mutability::Mut) = args.type_at(0).kind()
|
||||||
&& let self_ty = self.infcx.instantiate_binder_with_fresh_vars(
|
&& let self_ty = self.infcx.instantiate_binder_with_fresh_vars(
|
||||||
fn_call_span,
|
fn_call_span,
|
||||||
LateBoundRegionConversionTime::FnCall,
|
LateBoundRegionConversionTime::FnCall,
|
||||||
tcx.fn_sig(method_did).subst(tcx, method_substs).input(0),
|
tcx.fn_sig(method_did).instantiate(tcx, method_args).input(0),
|
||||||
)
|
)
|
||||||
&& self.infcx.can_eq(self.param_env, ty, self_ty)
|
&& self.infcx.can_eq(self.param_env, ty, self_ty)
|
||||||
{
|
{
|
||||||
|
@ -1161,7 +1161,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
let parent_self_ty =
|
let parent_self_ty =
|
||||||
matches!(tcx.def_kind(parent_did), rustc_hir::def::DefKind::Impl { .. })
|
matches!(tcx.def_kind(parent_did), rustc_hir::def::DefKind::Impl { .. })
|
||||||
.then_some(parent_did)
|
.then_some(parent_did)
|
||||||
.and_then(|did| match tcx.type_of(did).subst_identity().kind() {
|
.and_then(|did| match tcx.type_of(did).instantiate_identity().kind() {
|
||||||
ty::Adt(def, ..) => Some(def.did()),
|
ty::Adt(def, ..) => Some(def.did()),
|
||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
|
|
|
@ -324,10 +324,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
ty::Array(..) | ty::Slice(..) => {
|
ty::Array(..) | ty::Slice(..) => {
|
||||||
self.cannot_move_out_of_interior_noncopy(span, ty, None)
|
self.cannot_move_out_of_interior_noncopy(span, ty, None)
|
||||||
}
|
}
|
||||||
ty::Closure(def_id, closure_substs)
|
ty::Closure(def_id, closure_args)
|
||||||
if def_id.as_local() == Some(self.mir_def_id()) && upvar_field.is_some() =>
|
if def_id.as_local() == Some(self.mir_def_id()) && upvar_field.is_some() =>
|
||||||
{
|
{
|
||||||
let closure_kind_ty = closure_substs.as_closure().kind_ty();
|
let closure_kind_ty = closure_args.as_closure().kind_ty();
|
||||||
let closure_kind = match closure_kind_ty.to_opt_closure_kind() {
|
let closure_kind = match closure_kind_ty.to_opt_closure_kind() {
|
||||||
Some(kind @ (ty::ClosureKind::Fn | ty::ClosureKind::FnMut)) => kind,
|
Some(kind @ (ty::ClosureKind::Fn | ty::ClosureKind::FnMut)) => kind,
|
||||||
Some(ty::ClosureKind::FnOnce) => {
|
Some(ty::ClosureKind::FnOnce) => {
|
||||||
|
|
|
@ -22,7 +22,7 @@ use rustc_infer::infer::{
|
||||||
};
|
};
|
||||||
use rustc_middle::hir::place::PlaceBase;
|
use rustc_middle::hir::place::PlaceBase;
|
||||||
use rustc_middle::mir::{ConstraintCategory, ReturnConstraint};
|
use rustc_middle::mir::{ConstraintCategory, ReturnConstraint};
|
||||||
use rustc_middle::ty::subst::InternalSubsts;
|
use rustc_middle::ty::GenericArgs;
|
||||||
use rustc_middle::ty::TypeVisitor;
|
use rustc_middle::ty::TypeVisitor;
|
||||||
use rustc_middle::ty::{self, RegionVid, Ty};
|
use rustc_middle::ty::{self, RegionVid, Ty};
|
||||||
use rustc_middle::ty::{Region, TyCtxt};
|
use rustc_middle::ty::{Region, TyCtxt};
|
||||||
|
@ -183,9 +183,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
fn is_closure_fn_mut(&self, fr: RegionVid) -> bool {
|
fn is_closure_fn_mut(&self, fr: RegionVid) -> bool {
|
||||||
if let Some(ty::ReFree(free_region)) = self.to_error_region(fr).as_deref()
|
if let Some(ty::ReFree(free_region)) = self.to_error_region(fr).as_deref()
|
||||||
&& let ty::BoundRegionKind::BrEnv = free_region.bound_region
|
&& let ty::BoundRegionKind::BrEnv = free_region.bound_region
|
||||||
&& let DefiningTy::Closure(_, substs) = self.regioncx.universal_regions().defining_ty
|
&& let DefiningTy::Closure(_, args) = self.regioncx.universal_regions().defining_ty
|
||||||
{
|
{
|
||||||
return substs.as_closure().kind() == ty::ClosureKind::FnMut;
|
return args.as_closure().kind() == ty::ClosureKind::FnMut;
|
||||||
}
|
}
|
||||||
|
|
||||||
false
|
false
|
||||||
|
@ -502,12 +502,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
.to_string(),
|
.to_string(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ty::Adt(adt, substs) => {
|
ty::Adt(adt, args) => {
|
||||||
let generic_arg = substs[param_index as usize];
|
let generic_arg = args[param_index as usize];
|
||||||
let identity_substs =
|
let identity_args =
|
||||||
InternalSubsts::identity_for_item(self.infcx.tcx, adt.did());
|
GenericArgs::identity_for_item(self.infcx.tcx, adt.did());
|
||||||
let base_ty = Ty::new_adt(self.infcx.tcx, *adt, identity_substs);
|
let base_ty = Ty::new_adt(self.infcx.tcx, *adt, identity_args);
|
||||||
let base_generic_arg = identity_substs[param_index as usize];
|
let base_generic_arg = identity_args[param_index as usize];
|
||||||
let adt_desc = adt.descr();
|
let adt_desc = adt.descr();
|
||||||
|
|
||||||
let desc = format!(
|
let desc = format!(
|
||||||
|
@ -520,12 +520,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
ty::FnDef(def_id, _) => {
|
ty::FnDef(def_id, _) => {
|
||||||
let name = self.infcx.tcx.item_name(*def_id);
|
let name = self.infcx.tcx.item_name(*def_id);
|
||||||
let identity_substs =
|
let identity_args = GenericArgs::identity_for_item(self.infcx.tcx, *def_id);
|
||||||
InternalSubsts::identity_for_item(self.infcx.tcx, *def_id);
|
|
||||||
let desc = format!("a function pointer to `{name}`");
|
let desc = format!("a function pointer to `{name}`");
|
||||||
let note = format!(
|
let note = format!(
|
||||||
"the function `{name}` is invariant over the parameter `{}`",
|
"the function `{name}` is invariant over the parameter `{}`",
|
||||||
identity_substs[param_index as usize]
|
identity_args[param_index as usize]
|
||||||
);
|
);
|
||||||
(desc, note)
|
(desc, note)
|
||||||
}
|
}
|
||||||
|
@ -573,7 +572,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty;
|
let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty;
|
||||||
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *output_ty.kind() {
|
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *output_ty.kind() {
|
||||||
output_ty = self.infcx.tcx.type_of(def_id).subst_identity()
|
output_ty = self.infcx.tcx.type_of(def_id).instantiate_identity()
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("report_fnmut_error: output_ty={:?}", output_ty);
|
debug!("report_fnmut_error: output_ty={:?}", output_ty);
|
||||||
|
@ -899,14 +898,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
let tcx = self.infcx.tcx;
|
let tcx = self.infcx.tcx;
|
||||||
|
|
||||||
let instance = if let ConstraintCategory::CallArgument(Some(func_ty)) = category {
|
let instance = if let ConstraintCategory::CallArgument(Some(func_ty)) = category {
|
||||||
let (fn_did, substs) = match func_ty.kind() {
|
let (fn_did, args) = match func_ty.kind() {
|
||||||
ty::FnDef(fn_did, substs) => (fn_did, substs),
|
ty::FnDef(fn_did, args) => (fn_did, args),
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
debug!(?fn_did, ?substs);
|
debug!(?fn_did, ?args);
|
||||||
|
|
||||||
// Only suggest this on function calls, not closures
|
// Only suggest this on function calls, not closures
|
||||||
let ty = tcx.type_of(fn_did).subst_identity();
|
let ty = tcx.type_of(fn_did).instantiate_identity();
|
||||||
debug!("ty: {:?}, ty.kind: {:?}", ty, ty.kind());
|
debug!("ty: {:?}, ty.kind: {:?}", ty, ty.kind());
|
||||||
if let ty::Closure(_, _) = ty.kind() {
|
if let ty::Closure(_, _) = ty.kind() {
|
||||||
return;
|
return;
|
||||||
|
@ -916,7 +915,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
tcx,
|
tcx,
|
||||||
self.param_env,
|
self.param_env,
|
||||||
*fn_did,
|
*fn_did,
|
||||||
self.infcx.resolve_vars_if_possible(substs),
|
self.infcx.resolve_vars_if_possible(args),
|
||||||
) {
|
) {
|
||||||
instance
|
instance
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -5,8 +5,8 @@ use rustc_errors::Diagnostic;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_middle::ty::print::RegionHighlightMode;
|
use rustc_middle::ty::print::RegionHighlightMode;
|
||||||
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
|
|
||||||
use rustc_middle::ty::{self, RegionVid, Ty};
|
use rustc_middle::ty::{self, RegionVid, Ty};
|
||||||
|
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
|
||||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
|
|
||||||
|
@ -321,7 +321,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||||
ty::BoundRegionKind::BrEnv => {
|
ty::BoundRegionKind::BrEnv => {
|
||||||
let def_ty = self.regioncx.universal_regions().defining_ty;
|
let def_ty = self.regioncx.universal_regions().defining_ty;
|
||||||
|
|
||||||
let DefiningTy::Closure(_, substs) = def_ty else {
|
let DefiningTy::Closure(_, args) = def_ty else {
|
||||||
// Can't have BrEnv in functions, constants or generators.
|
// Can't have BrEnv in functions, constants or generators.
|
||||||
bug!("BrEnv outside of closure.");
|
bug!("BrEnv outside of closure.");
|
||||||
};
|
};
|
||||||
|
@ -332,7 +332,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||||
};
|
};
|
||||||
let region_name = self.synthesize_region_name();
|
let region_name = self.synthesize_region_name();
|
||||||
|
|
||||||
let closure_kind_ty = substs.as_closure().kind_ty();
|
let closure_kind_ty = args.as_closure().kind_ty();
|
||||||
let note = match closure_kind_ty.to_opt_closure_kind() {
|
let note = match closure_kind_ty.to_opt_closure_kind() {
|
||||||
Some(ty::ClosureKind::Fn) => {
|
Some(ty::ClosureKind::Fn) => {
|
||||||
"closure implements `Fn`, so references to captured variables \
|
"closure implements `Fn`, so references to captured variables \
|
||||||
|
@ -510,10 +510,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Match up something like `Foo<'1>`
|
// Match up something like `Foo<'1>`
|
||||||
(
|
(ty::Adt(_adt_def, args), hir::TyKind::Path(hir::QPath::Resolved(None, path))) => {
|
||||||
ty::Adt(_adt_def, substs),
|
|
||||||
hir::TyKind::Path(hir::QPath::Resolved(None, path)),
|
|
||||||
) => {
|
|
||||||
match path.res {
|
match path.res {
|
||||||
// Type parameters of the type alias have no reason to
|
// Type parameters of the type alias have no reason to
|
||||||
// be the same as those of the ADT.
|
// be the same as those of the ADT.
|
||||||
|
@ -523,7 +520,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||||
_ => {
|
_ => {
|
||||||
if let Some(last_segment) = path.segments.last() {
|
if let Some(last_segment) = path.segments.last() {
|
||||||
if let Some(highlight) = self.match_adt_and_segment(
|
if let Some(highlight) = self.match_adt_and_segment(
|
||||||
substs,
|
args,
|
||||||
needle_fr,
|
needle_fr,
|
||||||
last_segment,
|
last_segment,
|
||||||
search_stack,
|
search_stack,
|
||||||
|
@ -560,22 +557,22 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// We've found an enum/struct/union type with the substitutions
|
/// We've found an enum/struct/union type with the generic args
|
||||||
/// `substs` and -- in the HIR -- a path type with the final
|
/// `args` and -- in the HIR -- a path type with the final
|
||||||
/// segment `last_segment`. Try to find a `'_` to highlight in
|
/// segment `last_segment`. Try to find a `'_` to highlight in
|
||||||
/// the generic args (or, if not, to produce new zipped pairs of
|
/// the generic args (or, if not, to produce new zipped pairs of
|
||||||
/// types+hir to search through).
|
/// types+hir to search through).
|
||||||
fn match_adt_and_segment<'hir>(
|
fn match_adt_and_segment<'hir>(
|
||||||
&self,
|
&self,
|
||||||
substs: SubstsRef<'tcx>,
|
args: GenericArgsRef<'tcx>,
|
||||||
needle_fr: RegionVid,
|
needle_fr: RegionVid,
|
||||||
last_segment: &'hir hir::PathSegment<'hir>,
|
last_segment: &'hir hir::PathSegment<'hir>,
|
||||||
search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty<'hir>)>,
|
search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty<'hir>)>,
|
||||||
) -> Option<RegionNameHighlight> {
|
) -> Option<RegionNameHighlight> {
|
||||||
// Did the user give explicit arguments? (e.g., `Foo<..>`)
|
// Did the user give explicit arguments? (e.g., `Foo<..>`)
|
||||||
let args = last_segment.args.as_ref()?;
|
let explicit_args = last_segment.args.as_ref()?;
|
||||||
let lifetime =
|
let lifetime =
|
||||||
self.try_match_adt_and_generic_args(substs, needle_fr, args, search_stack)?;
|
self.try_match_adt_and_generic_args(args, needle_fr, explicit_args, search_stack)?;
|
||||||
if lifetime.is_anonymous() {
|
if lifetime.is_anonymous() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
@ -583,19 +580,19 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// We've found an enum/struct/union type with the substitutions
|
/// We've found an enum/struct/union type with the generic args
|
||||||
/// `substs` and -- in the HIR -- a path with the generic
|
/// `args` and -- in the HIR -- a path with the generic
|
||||||
/// arguments `args`. If `needle_fr` appears in the args, return
|
/// arguments `hir_args`. If `needle_fr` appears in the args, return
|
||||||
/// the `hir::Lifetime` that corresponds to it. If not, push onto
|
/// the `hir::Lifetime` that corresponds to it. If not, push onto
|
||||||
/// `search_stack` the types+hir to search through.
|
/// `search_stack` the types+hir to search through.
|
||||||
fn try_match_adt_and_generic_args<'hir>(
|
fn try_match_adt_and_generic_args<'hir>(
|
||||||
&self,
|
&self,
|
||||||
substs: SubstsRef<'tcx>,
|
args: GenericArgsRef<'tcx>,
|
||||||
needle_fr: RegionVid,
|
needle_fr: RegionVid,
|
||||||
args: &'hir hir::GenericArgs<'hir>,
|
hir_args: &'hir hir::GenericArgs<'hir>,
|
||||||
search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty<'hir>)>,
|
search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty<'hir>)>,
|
||||||
) -> Option<&'hir hir::Lifetime> {
|
) -> Option<&'hir hir::Lifetime> {
|
||||||
for (kind, hir_arg) in iter::zip(substs, args.args) {
|
for (kind, hir_arg) in iter::zip(args, hir_args.args) {
|
||||||
match (kind.unpack(), hir_arg) {
|
match (kind.unpack(), hir_arg) {
|
||||||
(GenericArgKind::Lifetime(r), hir::GenericArg::Lifetime(lt)) => {
|
(GenericArgKind::Lifetime(r), hir::GenericArg::Lifetime(lt)) => {
|
||||||
if r.as_var() == needle_fr {
|
if r.as_var() == needle_fr {
|
||||||
|
@ -849,9 +846,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
let found = tcx.any_free_region_meets(&tcx.type_of(region_parent).subst_identity(), |r| {
|
let found = tcx
|
||||||
*r == ty::ReEarlyBound(region)
|
.any_free_region_meets(&tcx.type_of(region_parent).instantiate_identity(), |r| {
|
||||||
});
|
*r == ty::ReEarlyBound(region)
|
||||||
|
});
|
||||||
|
|
||||||
Some(RegionName {
|
Some(RegionName {
|
||||||
name: self.synthesize_region_name(),
|
name: self.synthesize_region_name(),
|
||||||
|
|
|
@ -301,7 +301,7 @@ fn do_mir_borrowck<'tcx>(
|
||||||
let movable_generator =
|
let movable_generator =
|
||||||
// The first argument is the generator type passed by value
|
// The first argument is the generator type passed by value
|
||||||
if let Some(local) = body.local_decls.raw.get(1)
|
if let Some(local) = body.local_decls.raw.get(1)
|
||||||
// Get the interior types and substs which typeck computed
|
// Get the interior types and args which typeck computed
|
||||||
&& let ty::Generator(_, _, hir::Movability::Static) = local.ty.kind()
|
&& let ty::Generator(_, _, hir::Movability::Static) = local.ty.kind()
|
||||||
{
|
{
|
||||||
false
|
false
|
||||||
|
|
|
@ -1115,7 +1115,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
) -> Option<ClosureOutlivesSubject<'tcx>> {
|
) -> Option<ClosureOutlivesSubject<'tcx>> {
|
||||||
let tcx = infcx.tcx;
|
let tcx = infcx.tcx;
|
||||||
|
|
||||||
// Opaque types' substs may include useless lifetimes.
|
// Opaque types' args may include useless lifetimes.
|
||||||
// We will replace them with ReStatic.
|
// We will replace them with ReStatic.
|
||||||
struct OpaqueFolder<'tcx> {
|
struct OpaqueFolder<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
@ -1127,19 +1127,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
use ty::TypeSuperFoldable as _;
|
use ty::TypeSuperFoldable as _;
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let &ty::Alias(ty::Opaque, ty::AliasTy { substs, def_id, .. }) = t.kind() else {
|
let &ty::Alias(ty::Opaque, ty::AliasTy { args, def_id, .. }) = t.kind() else {
|
||||||
return t.super_fold_with(self);
|
return t.super_fold_with(self);
|
||||||
};
|
};
|
||||||
let substs =
|
let args = std::iter::zip(args, tcx.variances_of(def_id)).map(|(arg, v)| {
|
||||||
std::iter::zip(substs, tcx.variances_of(def_id)).map(|(arg, v)| {
|
match (arg.unpack(), v) {
|
||||||
match (arg.unpack(), v) {
|
(ty::GenericArgKind::Lifetime(_), ty::Bivariant) => {
|
||||||
(ty::GenericArgKind::Lifetime(_), ty::Bivariant) => {
|
tcx.lifetimes.re_static.into()
|
||||||
tcx.lifetimes.re_static.into()
|
|
||||||
}
|
|
||||||
_ => arg.fold_with(self),
|
|
||||||
}
|
}
|
||||||
});
|
_ => arg.fold_with(self),
|
||||||
Ty::new_opaque(tcx, def_id, tcx.mk_substs_from_iter(substs))
|
}
|
||||||
|
});
|
||||||
|
Ty::new_opaque(tcx, def_id, tcx.mk_args_from_iter(args))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,9 @@ use rustc_infer::infer::InferCtxt;
|
||||||
use rustc_infer::infer::TyCtxtInferExt as _;
|
use rustc_infer::infer::TyCtxtInferExt as _;
|
||||||
use rustc_infer::traits::{Obligation, ObligationCause};
|
use rustc_infer::traits::{Obligation, ObligationCause};
|
||||||
use rustc_middle::traits::DefiningAnchor;
|
use rustc_middle::traits::DefiningAnchor;
|
||||||
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
|
|
||||||
use rustc_middle::ty::visit::TypeVisitableExt;
|
use rustc_middle::ty::visit::TypeVisitableExt;
|
||||||
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable};
|
||||||
|
use rustc_middle::ty::{GenericArgKind, GenericArgs};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
|
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
|
||||||
use rustc_trait_selection::traits::ObligationCtxt;
|
use rustc_trait_selection::traits::ObligationCtxt;
|
||||||
|
@ -38,15 +38,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
/// back to concrete lifetimes: `'static`, `ReEarlyBound` or `ReFree`.
|
/// back to concrete lifetimes: `'static`, `ReEarlyBound` or `ReFree`.
|
||||||
///
|
///
|
||||||
/// First we map all the lifetimes in the concrete type to an equal
|
/// First we map all the lifetimes in the concrete type to an equal
|
||||||
/// universal region that occurs in the concrete type's substs, in this case
|
/// universal region that occurs in the concrete type's args, in this case
|
||||||
/// this would result in `&'1 i32`. We only consider regions in the substs
|
/// this would result in `&'1 i32`. We only consider regions in the args
|
||||||
/// in case there is an equal region that does not. For example, this should
|
/// in case there is an equal region that does not. For example, this should
|
||||||
/// be allowed:
|
/// be allowed:
|
||||||
/// `fn f<'a: 'b, 'b: 'a>(x: *mut &'b i32) -> impl Sized + 'a { x }`
|
/// `fn f<'a: 'b, 'b: 'a>(x: *mut &'b i32) -> impl Sized + 'a { x }`
|
||||||
///
|
///
|
||||||
/// Then we map the regions in both the type and the subst to their
|
/// Then we map the regions in both the type and the subst to their
|
||||||
/// `external_name` giving `concrete_type = &'a i32`,
|
/// `external_name` giving `concrete_type = &'a i32`,
|
||||||
/// `substs = ['static, 'a]`. This will then allow
|
/// `args = ['static, 'a]`. This will then allow
|
||||||
/// `infer_opaque_definition_from_instantiation` to determine that
|
/// `infer_opaque_definition_from_instantiation` to determine that
|
||||||
/// `_Return<'_a> = &'_a i32`.
|
/// `_Return<'_a> = &'_a i32`.
|
||||||
///
|
///
|
||||||
|
@ -73,8 +73,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
debug!(?member_constraints);
|
debug!(?member_constraints);
|
||||||
|
|
||||||
for (opaque_type_key, concrete_type) in opaque_ty_decls {
|
for (opaque_type_key, concrete_type) in opaque_ty_decls {
|
||||||
let substs = opaque_type_key.substs;
|
let args = opaque_type_key.args;
|
||||||
debug!(?concrete_type, ?substs);
|
debug!(?concrete_type, ?args);
|
||||||
|
|
||||||
let mut subst_regions = vec![self.universal_regions.fr_static];
|
let mut subst_regions = vec![self.universal_regions.fr_static];
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
ty::Region::new_error_with_message(
|
ty::Region::new_error_with_message(
|
||||||
infcx.tcx,
|
infcx.tcx,
|
||||||
concrete_type.span,
|
concrete_type.span,
|
||||||
"opaque type with non-universal region substs",
|
"opaque type with non-universal region args",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,17 +110,17 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
}
|
}
|
||||||
debug!(?subst_regions);
|
debug!(?subst_regions);
|
||||||
|
|
||||||
// Next, insert universal regions from substs, so we can translate regions that appear
|
// Next, insert universal regions from args, so we can translate regions that appear
|
||||||
// in them but are not subject to member constraints, for instance closure substs.
|
// in them but are not subject to member constraints, for instance closure args.
|
||||||
let universal_substs = infcx.tcx.fold_regions(substs, |region, _| {
|
let universal_args = infcx.tcx.fold_regions(args, |region, _| {
|
||||||
if let ty::RePlaceholder(..) = region.kind() {
|
if let ty::RePlaceholder(..) = region.kind() {
|
||||||
// Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs.
|
// Higher kinded regions don't need remapping, they don't refer to anything outside of this the args.
|
||||||
return region;
|
return region;
|
||||||
}
|
}
|
||||||
let vid = self.to_region_vid(region);
|
let vid = self.to_region_vid(region);
|
||||||
to_universal_region(vid, &mut subst_regions)
|
to_universal_region(vid, &mut subst_regions)
|
||||||
});
|
});
|
||||||
debug!(?universal_substs);
|
debug!(?universal_args);
|
||||||
debug!(?subst_regions);
|
debug!(?subst_regions);
|
||||||
|
|
||||||
// Deduplicate the set of regions while keeping the chosen order.
|
// Deduplicate the set of regions while keeping the chosen order.
|
||||||
|
@ -139,7 +139,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
debug!(?universal_concrete_type);
|
debug!(?universal_concrete_type);
|
||||||
|
|
||||||
let opaque_type_key =
|
let opaque_type_key =
|
||||||
OpaqueTypeKey { def_id: opaque_type_key.def_id, substs: universal_substs };
|
OpaqueTypeKey { def_id: opaque_type_key.def_id, args: universal_args };
|
||||||
let ty = infcx.infer_opaque_definition_from_instantiation(
|
let ty = infcx.infer_opaque_definition_from_instantiation(
|
||||||
opaque_type_key,
|
opaque_type_key,
|
||||||
universal_concrete_type,
|
universal_concrete_type,
|
||||||
|
@ -175,7 +175,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
|
|
||||||
/// Map the regions in the type to named regions. This is similar to what
|
/// Map the regions in the type to named regions. This is similar to what
|
||||||
/// `infer_opaque_types` does, but can infer any universal region, not only
|
/// `infer_opaque_types` does, but can infer any universal region, not only
|
||||||
/// ones from the substs for the opaque type. It also doesn't double check
|
/// ones from the args for the opaque type. It also doesn't double check
|
||||||
/// that the regions produced are in fact equal to the named region they are
|
/// that the regions produced are in fact equal to the named region they are
|
||||||
/// replaced with. This is fine because this function is only to improve the
|
/// replaced with. This is fine because this function is only to improve the
|
||||||
/// region names in error messages.
|
/// region names in error messages.
|
||||||
|
@ -238,7 +238,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
///
|
///
|
||||||
/// - `def_id`, the `impl Trait` type
|
/// - `def_id`, the `impl Trait` type
|
||||||
/// - `substs`, the substs used to instantiate this opaque type
|
/// - `args`, the args used to instantiate this opaque type
|
||||||
/// - `instantiated_ty`, the inferred type C1 -- fully resolved, lifted version of
|
/// - `instantiated_ty`, the inferred type C1 -- fully resolved, lifted version of
|
||||||
/// `opaque_defn.concrete_ty`
|
/// `opaque_defn.concrete_ty`
|
||||||
#[instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
|
@ -309,11 +309,11 @@ fn check_opaque_type_well_formed<'tcx>(
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
let ocx = ObligationCtxt::new(&infcx);
|
let ocx = ObligationCtxt::new(&infcx);
|
||||||
let identity_substs = InternalSubsts::identity_for_item(tcx, def_id);
|
let identity_args = GenericArgs::identity_for_item(tcx, def_id);
|
||||||
|
|
||||||
// Require that the hidden type actually fulfills all the bounds of the opaque type, even without
|
// Require that the hidden type actually fulfills all the bounds of the opaque type, even without
|
||||||
// the bounds that the function supplies.
|
// the bounds that the function supplies.
|
||||||
let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), identity_substs);
|
let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), identity_args);
|
||||||
ocx.eq(&ObligationCause::misc(definition_span, def_id), param_env, opaque_ty, definition_ty)
|
ocx.eq(&ObligationCause::misc(definition_span, def_id), param_env, opaque_ty, definition_ty)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
infcx
|
infcx
|
||||||
|
@ -384,7 +384,7 @@ fn check_opaque_type_parameter_valid(
|
||||||
}
|
}
|
||||||
let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
|
let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
|
||||||
let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default();
|
let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default();
|
||||||
for (i, arg) in opaque_type_key.substs.iter().enumerate() {
|
for (i, arg) in opaque_type_key.args.iter().enumerate() {
|
||||||
let arg_is_param = match arg.unpack() {
|
let arg_is_param = match arg.unpack() {
|
||||||
GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)),
|
GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)),
|
||||||
GenericArgKind::Lifetime(lt) => {
|
GenericArgKind::Lifetime(lt) => {
|
||||||
|
|
|
@ -6,7 +6,7 @@ use rustc_infer::infer::NllRegionVariableOrigin;
|
||||||
use rustc_middle::mir::visit::{MutVisitor, TyContext};
|
use rustc_middle::mir::visit::{MutVisitor, TyContext};
|
||||||
use rustc_middle::mir::Constant;
|
use rustc_middle::mir::Constant;
|
||||||
use rustc_middle::mir::{Body, Location, Promoted};
|
use rustc_middle::mir::{Body, Location, Promoted};
|
||||||
use rustc_middle::ty::subst::SubstsRef;
|
use rustc_middle::ty::GenericArgsRef;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||||
use rustc_span::{Span, Symbol};
|
use rustc_span::{Span, Symbol};
|
||||||
|
|
||||||
|
@ -94,10 +94,10 @@ impl<'a, 'tcx> MutVisitor<'tcx> for RegionRenumberer<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(self), level = "debug")]
|
#[instrument(skip(self), level = "debug")]
|
||||||
fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, location: Location) {
|
fn visit_args(&mut self, args: &mut GenericArgsRef<'tcx>, location: Location) {
|
||||||
*substs = self.renumber_regions(*substs, || RegionCtxt::Location(location));
|
*args = self.renumber_regions(*args, || RegionCtxt::Location(location));
|
||||||
|
|
||||||
debug!(?substs);
|
debug!(?args);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(self), level = "debug")]
|
#[instrument(skip(self), level = "debug")]
|
||||||
|
|
|
@ -5,7 +5,7 @@ use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelega
|
||||||
use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
|
use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
|
||||||
use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
|
use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
|
||||||
use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
|
use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
|
||||||
use rustc_middle::ty::subst::GenericArgKind;
|
use rustc_middle::ty::GenericArgKind;
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
use rustc_middle::ty::{TypeFoldable, TypeVisitableExt};
|
use rustc_middle::ty::{TypeFoldable, TypeVisitableExt};
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
|
@ -89,20 +89,20 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
|
||||||
|
|
||||||
/// Given an instance of the closure type, this method instantiates the "extra" requirements
|
/// Given an instance of the closure type, this method instantiates the "extra" requirements
|
||||||
/// that we computed for the closure. This has the effect of adding new outlives obligations
|
/// that we computed for the closure. This has the effect of adding new outlives obligations
|
||||||
/// to existing region variables in `closure_substs`.
|
/// to existing region variables in `closure_args`.
|
||||||
#[instrument(skip(self), level = "debug")]
|
#[instrument(skip(self), level = "debug")]
|
||||||
pub fn apply_closure_requirements(
|
pub fn apply_closure_requirements(
|
||||||
&mut self,
|
&mut self,
|
||||||
closure_requirements: &ClosureRegionRequirements<'tcx>,
|
closure_requirements: &ClosureRegionRequirements<'tcx>,
|
||||||
closure_def_id: DefId,
|
closure_def_id: DefId,
|
||||||
closure_substs: ty::SubstsRef<'tcx>,
|
closure_args: ty::GenericArgsRef<'tcx>,
|
||||||
) {
|
) {
|
||||||
// Extract the values of the free regions in `closure_substs`
|
// Extract the values of the free regions in `closure_args`
|
||||||
// into a vector. These are the regions that we will be
|
// into a vector. These are the regions that we will be
|
||||||
// relating to one another.
|
// relating to one another.
|
||||||
let closure_mapping = &UniversalRegions::closure_mapping(
|
let closure_mapping = &UniversalRegions::closure_mapping(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
closure_substs,
|
closure_args,
|
||||||
closure_requirements.num_external_vids,
|
closure_requirements.num_external_vids,
|
||||||
closure_def_id.expect_local(),
|
closure_def_id.expect_local(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::def_use::{self, DefUse};
|
||||||
use crate::location::{LocationIndex, LocationTable};
|
use crate::location::{LocationIndex, LocationTable};
|
||||||
use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
|
use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
|
||||||
use rustc_middle::mir::{Body, Local, Location, Place};
|
use rustc_middle::mir::{Body, Local, Location, Place};
|
||||||
use rustc_middle::ty::subst::GenericArg;
|
use rustc_middle::ty::GenericArg;
|
||||||
use rustc_mir_dataflow::move_paths::{LookupResult, MoveData, MovePathIndex};
|
use rustc_mir_dataflow::move_paths::{LookupResult, MoveData, MovePathIndex};
|
||||||
|
|
||||||
use super::TypeChecker;
|
use super::TypeChecker;
|
||||||
|
|
|
@ -30,12 +30,12 @@ use rustc_middle::traits::query::NoSolution;
|
||||||
use rustc_middle::traits::ObligationCause;
|
use rustc_middle::traits::ObligationCause;
|
||||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||||
use rustc_middle::ty::cast::CastTy;
|
use rustc_middle::ty::cast::CastTy;
|
||||||
use rustc_middle::ty::subst::{SubstsRef, UserSubsts};
|
|
||||||
use rustc_middle::ty::visit::TypeVisitableExt;
|
use rustc_middle::ty::visit::TypeVisitableExt;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, Dynamic,
|
self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, Dynamic,
|
||||||
OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, UserTypeAnnotationIndex,
|
OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, UserTypeAnnotationIndex,
|
||||||
};
|
};
|
||||||
|
use rustc_middle::ty::{GenericArgsRef, UserArgs};
|
||||||
use rustc_span::def_id::CRATE_DEF_ID;
|
use rustc_span::def_id::CRATE_DEF_ID;
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
|
@ -389,15 +389,12 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
||||||
} else {
|
} else {
|
||||||
self.cx.ascribe_user_type(
|
self.cx.ascribe_user_type(
|
||||||
constant.literal.ty(),
|
constant.literal.ty(),
|
||||||
UserType::TypeOf(
|
UserType::TypeOf(uv.def, UserArgs { args: uv.args, user_self_ty: None }),
|
||||||
uv.def,
|
|
||||||
UserSubsts { substs: uv.substs, user_self_ty: None },
|
|
||||||
),
|
|
||||||
locations.span(&self.cx.body),
|
locations.span(&self.cx.body),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if let Some(static_def_id) = constant.check_static_ptr(tcx) {
|
} else if let Some(static_def_id) = constant.check_static_ptr(tcx) {
|
||||||
let unnormalized_ty = tcx.type_of(static_def_id).subst_identity();
|
let unnormalized_ty = tcx.type_of(static_def_id).instantiate_identity();
|
||||||
let normalized_ty = self.cx.normalize(unnormalized_ty, locations);
|
let normalized_ty = self.cx.normalize(unnormalized_ty, locations);
|
||||||
let literal_ty = constant.literal.ty().builtin_deref(true).unwrap().ty;
|
let literal_ty = constant.literal.ty().builtin_deref(true).unwrap().ty;
|
||||||
|
|
||||||
|
@ -411,11 +408,11 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let ty::FnDef(def_id, substs) = *constant.literal.ty().kind() {
|
if let ty::FnDef(def_id, args) = *constant.literal.ty().kind() {
|
||||||
// const_trait_impl: use a non-const param env when checking that a FnDef type is well formed.
|
// const_trait_impl: use a non-const param env when checking that a FnDef type is well formed.
|
||||||
// this is because the well-formedness of the function does not need to be proved to have `const`
|
// this is because the well-formedness of the function does not need to be proved to have `const`
|
||||||
// impls for trait bounds.
|
// impls for trait bounds.
|
||||||
let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs);
|
let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, args);
|
||||||
let prev = self.cx.param_env;
|
let prev = self.cx.param_env;
|
||||||
self.cx.param_env = prev.without_const();
|
self.cx.param_env = prev.without_const();
|
||||||
self.cx.normalize_and_prove_instantiated_predicates(
|
self.cx.normalize_and_prove_instantiated_predicates(
|
||||||
|
@ -666,7 +663,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
ProjectionElem::Downcast(maybe_name, index) => match base_ty.kind() {
|
ProjectionElem::Downcast(maybe_name, index) => match base_ty.kind() {
|
||||||
ty::Adt(adt_def, _substs) if adt_def.is_enum() => {
|
ty::Adt(adt_def, _args) if adt_def.is_enum() => {
|
||||||
if index.as_usize() >= adt_def.variants().len() {
|
if index.as_usize() >= adt_def.variants().len() {
|
||||||
PlaceTy::from_ty(span_mirbug_and_err!(
|
PlaceTy::from_ty(span_mirbug_and_err!(
|
||||||
self,
|
self,
|
||||||
|
@ -776,16 +773,16 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||||
) -> Result<Ty<'tcx>, FieldAccessError> {
|
) -> Result<Ty<'tcx>, FieldAccessError> {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
|
||||||
let (variant, substs) = match base_ty {
|
let (variant, args) = match base_ty {
|
||||||
PlaceTy { ty, variant_index: Some(variant_index) } => match *ty.kind() {
|
PlaceTy { ty, variant_index: Some(variant_index) } => match *ty.kind() {
|
||||||
ty::Adt(adt_def, substs) => (adt_def.variant(variant_index), substs),
|
ty::Adt(adt_def, args) => (adt_def.variant(variant_index), args),
|
||||||
ty::Generator(def_id, substs, _) => {
|
ty::Generator(def_id, args, _) => {
|
||||||
let mut variants = substs.as_generator().state_tys(def_id, tcx);
|
let mut variants = args.as_generator().state_tys(def_id, tcx);
|
||||||
let Some(mut variant) = variants.nth(variant_index.into()) else {
|
let Some(mut variant) = variants.nth(variant_index.into()) else {
|
||||||
bug!(
|
bug!(
|
||||||
"variant_index of generator out of range: {:?}/{:?}",
|
"variant_index of generator out of range: {:?}/{:?}",
|
||||||
variant_index,
|
variant_index,
|
||||||
substs.as_generator().state_tys(def_id, tcx).count()
|
args.as_generator().state_tys(def_id, tcx).count()
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
return match variant.nth(field.index()) {
|
return match variant.nth(field.index()) {
|
||||||
|
@ -796,11 +793,11 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||||
_ => bug!("can't have downcast of non-adt non-generator type"),
|
_ => bug!("can't have downcast of non-adt non-generator type"),
|
||||||
},
|
},
|
||||||
PlaceTy { ty, variant_index: None } => match *ty.kind() {
|
PlaceTy { ty, variant_index: None } => match *ty.kind() {
|
||||||
ty::Adt(adt_def, substs) if !adt_def.is_enum() => {
|
ty::Adt(adt_def, args) if !adt_def.is_enum() => {
|
||||||
(adt_def.variant(FIRST_VARIANT), substs)
|
(adt_def.variant(FIRST_VARIANT), args)
|
||||||
}
|
}
|
||||||
ty::Closure(_, substs) => {
|
ty::Closure(_, args) => {
|
||||||
return match substs
|
return match args
|
||||||
.as_closure()
|
.as_closure()
|
||||||
.tupled_upvars_ty()
|
.tupled_upvars_ty()
|
||||||
.tuple_fields()
|
.tuple_fields()
|
||||||
|
@ -808,17 +805,17 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||||
{
|
{
|
||||||
Some(&ty) => Ok(ty),
|
Some(&ty) => Ok(ty),
|
||||||
None => Err(FieldAccessError::OutOfRange {
|
None => Err(FieldAccessError::OutOfRange {
|
||||||
field_count: substs.as_closure().upvar_tys().count(),
|
field_count: args.as_closure().upvar_tys().count(),
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
ty::Generator(_, substs, _) => {
|
ty::Generator(_, args, _) => {
|
||||||
// Only prefix fields (upvars and current state) are
|
// Only prefix fields (upvars and current state) are
|
||||||
// accessible without a variant index.
|
// accessible without a variant index.
|
||||||
return match substs.as_generator().prefix_tys().nth(field.index()) {
|
return match args.as_generator().prefix_tys().nth(field.index()) {
|
||||||
Some(ty) => Ok(ty),
|
Some(ty) => Ok(ty),
|
||||||
None => Err(FieldAccessError::OutOfRange {
|
None => Err(FieldAccessError::OutOfRange {
|
||||||
field_count: substs.as_generator().prefix_tys().count(),
|
field_count: args.as_generator().prefix_tys().count(),
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -840,7 +837,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(field) = variant.fields.get(field) {
|
if let Some(field) = variant.fields.get(field) {
|
||||||
Ok(self.cx.normalize(field.ty(tcx, substs), location))
|
Ok(self.cx.normalize(field.ty(tcx, args), location))
|
||||||
} else {
|
} else {
|
||||||
Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() })
|
Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() })
|
||||||
}
|
}
|
||||||
|
@ -1065,7 +1062,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
|
|
||||||
ocx.infcx.add_item_bounds_for_hidden_type(
|
ocx.infcx.add_item_bounds_for_hidden_type(
|
||||||
opaque_type_key.def_id.to_def_id(),
|
opaque_type_key.def_id.to_def_id(),
|
||||||
opaque_type_key.substs,
|
opaque_type_key.args,
|
||||||
cause,
|
cause,
|
||||||
param_env,
|
param_env,
|
||||||
hidden_ty.ty,
|
hidden_ty.ty,
|
||||||
|
@ -1770,32 +1767,32 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
|
||||||
match *ak {
|
match *ak {
|
||||||
AggregateKind::Adt(adt_did, variant_index, substs, _, active_field_index) => {
|
AggregateKind::Adt(adt_did, variant_index, args, _, active_field_index) => {
|
||||||
let def = tcx.adt_def(adt_did);
|
let def = tcx.adt_def(adt_did);
|
||||||
let variant = &def.variant(variant_index);
|
let variant = &def.variant(variant_index);
|
||||||
let adj_field_index = active_field_index.unwrap_or(field_index);
|
let adj_field_index = active_field_index.unwrap_or(field_index);
|
||||||
if let Some(field) = variant.fields.get(adj_field_index) {
|
if let Some(field) = variant.fields.get(adj_field_index) {
|
||||||
Ok(self.normalize(field.ty(tcx, substs), location))
|
Ok(self.normalize(field.ty(tcx, args), location))
|
||||||
} else {
|
} else {
|
||||||
Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() })
|
Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AggregateKind::Closure(_, substs) => {
|
AggregateKind::Closure(_, args) => {
|
||||||
match substs.as_closure().upvar_tys().nth(field_index.as_usize()) {
|
match args.as_closure().upvar_tys().nth(field_index.as_usize()) {
|
||||||
Some(ty) => Ok(ty),
|
Some(ty) => Ok(ty),
|
||||||
None => Err(FieldAccessError::OutOfRange {
|
None => Err(FieldAccessError::OutOfRange {
|
||||||
field_count: substs.as_closure().upvar_tys().count(),
|
field_count: args.as_closure().upvar_tys().count(),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AggregateKind::Generator(_, substs, _) => {
|
AggregateKind::Generator(_, args, _) => {
|
||||||
// It doesn't make sense to look at a field beyond the prefix;
|
// It doesn't make sense to look at a field beyond the prefix;
|
||||||
// these require a variant index, and are not initialized in
|
// these require a variant index, and are not initialized in
|
||||||
// aggregate rvalues.
|
// aggregate rvalues.
|
||||||
match substs.as_generator().prefix_tys().nth(field_index.as_usize()) {
|
match args.as_generator().prefix_tys().nth(field_index.as_usize()) {
|
||||||
Some(ty) => Ok(ty),
|
Some(ty) => Ok(ty),
|
||||||
None => Err(FieldAccessError::OutOfRange {
|
None => Err(FieldAccessError::OutOfRange {
|
||||||
field_count: substs.as_generator().prefix_tys().count(),
|
field_count: args.as_generator().prefix_tys().count(),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1821,8 +1818,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
let def_id = uv.def;
|
let def_id = uv.def;
|
||||||
if tcx.def_kind(def_id) == DefKind::InlineConst {
|
if tcx.def_kind(def_id) == DefKind::InlineConst {
|
||||||
let def_id = def_id.expect_local();
|
let def_id = def_id.expect_local();
|
||||||
let predicates =
|
let predicates = self.prove_closure_bounds(tcx, def_id, uv.args, location);
|
||||||
self.prove_closure_bounds(tcx, def_id, uv.substs, location);
|
|
||||||
self.normalize_and_prove_instantiated_predicates(
|
self.normalize_and_prove_instantiated_predicates(
|
||||||
def_id.to_def_id(),
|
def_id.to_def_id(),
|
||||||
predicates,
|
predicates,
|
||||||
|
@ -1939,7 +1935,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
|
|
||||||
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(unsafety)) => {
|
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(unsafety)) => {
|
||||||
let sig = match op.ty(body, tcx).kind() {
|
let sig = match op.ty(body, tcx).kind() {
|
||||||
ty::Closure(_, substs) => substs.as_closure().sig(),
|
ty::Closure(_, args) => args.as_closure().sig(),
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
};
|
};
|
||||||
let ty_fn_ptr_from =
|
let ty_fn_ptr_from =
|
||||||
|
@ -2591,8 +2587,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
|
|
||||||
let (def_id, instantiated_predicates) = match *aggregate_kind {
|
let (def_id, instantiated_predicates) = match *aggregate_kind {
|
||||||
AggregateKind::Adt(adt_did, _, substs, _, _) => {
|
AggregateKind::Adt(adt_did, _, args, _, _) => {
|
||||||
(adt_did, tcx.predicates_of(adt_did).instantiate(tcx, substs))
|
(adt_did, tcx.predicates_of(adt_did).instantiate(tcx, args))
|
||||||
}
|
}
|
||||||
|
|
||||||
// For closures, we have some **extra requirements** we
|
// For closures, we have some **extra requirements** we
|
||||||
|
@ -2614,9 +2610,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
// desugaring. A closure gets desugared to a struct, and
|
// desugaring. A closure gets desugared to a struct, and
|
||||||
// these extra requirements are basically like where
|
// these extra requirements are basically like where
|
||||||
// clauses on the struct.
|
// clauses on the struct.
|
||||||
AggregateKind::Closure(def_id, substs)
|
AggregateKind::Closure(def_id, args) | AggregateKind::Generator(def_id, args, _) => {
|
||||||
| AggregateKind::Generator(def_id, substs, _) => {
|
(def_id, self.prove_closure_bounds(tcx, def_id.expect_local(), args, location))
|
||||||
(def_id, self.prove_closure_bounds(tcx, def_id.expect_local(), substs, location))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AggregateKind::Array(_) | AggregateKind::Tuple => {
|
AggregateKind::Array(_) | AggregateKind::Tuple => {
|
||||||
|
@ -2635,7 +2630,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
def_id: LocalDefId,
|
def_id: LocalDefId,
|
||||||
substs: SubstsRef<'tcx>,
|
args: GenericArgsRef<'tcx>,
|
||||||
location: Location,
|
location: Location,
|
||||||
) -> ty::InstantiatedPredicates<'tcx> {
|
) -> ty::InstantiatedPredicates<'tcx> {
|
||||||
if let Some(closure_requirements) = &tcx.mir_borrowck(def_id).closure_requirements {
|
if let Some(closure_requirements) = &tcx.mir_borrowck(def_id).closure_requirements {
|
||||||
|
@ -2653,26 +2648,26 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
.apply_closure_requirements(
|
.apply_closure_requirements(
|
||||||
&closure_requirements,
|
&closure_requirements,
|
||||||
def_id.to_def_id(),
|
def_id.to_def_id(),
|
||||||
substs,
|
args,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now equate closure substs to regions inherited from `typeck_root_def_id`. Fixes #98589.
|
// Now equate closure args to regions inherited from `typeck_root_def_id`. Fixes #98589.
|
||||||
let typeck_root_def_id = tcx.typeck_root_def_id(self.body.source.def_id());
|
let typeck_root_def_id = tcx.typeck_root_def_id(self.body.source.def_id());
|
||||||
let typeck_root_substs = ty::InternalSubsts::identity_for_item(tcx, typeck_root_def_id);
|
let typeck_root_args = ty::GenericArgs::identity_for_item(tcx, typeck_root_def_id);
|
||||||
|
|
||||||
let parent_substs = match tcx.def_kind(def_id) {
|
let parent_args = match tcx.def_kind(def_id) {
|
||||||
DefKind::Closure => substs.as_closure().parent_substs(),
|
DefKind::Closure => args.as_closure().parent_args(),
|
||||||
DefKind::Generator => substs.as_generator().parent_substs(),
|
DefKind::Generator => args.as_generator().parent_args(),
|
||||||
DefKind::InlineConst => substs.as_inline_const().parent_substs(),
|
DefKind::InlineConst => args.as_inline_const().parent_args(),
|
||||||
other => bug!("unexpected item {:?}", other),
|
other => bug!("unexpected item {:?}", other),
|
||||||
};
|
};
|
||||||
let parent_substs = tcx.mk_substs(parent_substs);
|
let parent_args = tcx.mk_args(parent_args);
|
||||||
|
|
||||||
assert_eq!(typeck_root_substs.len(), parent_substs.len());
|
assert_eq!(typeck_root_args.len(), parent_args.len());
|
||||||
if let Err(_) = self.eq_substs(
|
if let Err(_) = self.eq_args(
|
||||||
typeck_root_substs,
|
typeck_root_args,
|
||||||
parent_substs,
|
parent_args,
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
ConstraintCategory::BoringNoLocation,
|
ConstraintCategory::BoringNoLocation,
|
||||||
) {
|
) {
|
||||||
|
@ -2680,12 +2675,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
self,
|
self,
|
||||||
def_id,
|
def_id,
|
||||||
"could not relate closure to parent {:?} != {:?}",
|
"could not relate closure to parent {:?} != {:?}",
|
||||||
typeck_root_substs,
|
typeck_root_args,
|
||||||
parent_substs
|
parent_args
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
tcx.predicates_of(def_id).instantiate(tcx, substs)
|
tcx.predicates_of(def_id).instantiate(tcx, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(self, body), level = "debug")]
|
#[instrument(skip(self, body), level = "debug")]
|
||||||
|
|
|
@ -42,10 +42,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add sufficient constraints to ensure `a == b`. See also [Self::relate_types].
|
/// Add sufficient constraints to ensure `a == b`. See also [Self::relate_types].
|
||||||
pub(super) fn eq_substs(
|
pub(super) fn eq_args(
|
||||||
&mut self,
|
&mut self,
|
||||||
a: ty::SubstsRef<'tcx>,
|
a: ty::GenericArgsRef<'tcx>,
|
||||||
b: ty::SubstsRef<'tcx>,
|
b: ty::GenericArgsRef<'tcx>,
|
||||||
locations: Locations,
|
locations: Locations,
|
||||||
category: ConstraintCategory<'tcx>,
|
category: ConstraintCategory<'tcx>,
|
||||||
) -> Result<(), NoSolution> {
|
) -> Result<(), NoSolution> {
|
||||||
|
|
|
@ -22,8 +22,8 @@ use rustc_hir::BodyOwnerKind;
|
||||||
use rustc_index::IndexVec;
|
use rustc_index::IndexVec;
|
||||||
use rustc_infer::infer::NllRegionVariableOrigin;
|
use rustc_infer::infer::NllRegionVariableOrigin;
|
||||||
use rustc_middle::ty::fold::TypeFoldable;
|
use rustc_middle::ty::fold::TypeFoldable;
|
||||||
use rustc_middle::ty::{self, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt};
|
use rustc_middle::ty::{self, InlineConstArgs, InlineConstArgsParts, RegionVid, Ty, TyCtxt};
|
||||||
use rustc_middle::ty::{InternalSubsts, SubstsRef};
|
use rustc_middle::ty::{GenericArgs, GenericArgsRef};
|
||||||
use rustc_span::symbol::{kw, sym};
|
use rustc_span::symbol::{kw, sym};
|
||||||
use rustc_span::Symbol;
|
use rustc_span::Symbol;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
@ -88,26 +88,26 @@ pub struct UniversalRegions<'tcx> {
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub enum DefiningTy<'tcx> {
|
pub enum DefiningTy<'tcx> {
|
||||||
/// The MIR is a closure. The signature is found via
|
/// The MIR is a closure. The signature is found via
|
||||||
/// `ClosureSubsts::closure_sig_ty`.
|
/// `ClosureArgs::closure_sig_ty`.
|
||||||
Closure(DefId, SubstsRef<'tcx>),
|
Closure(DefId, GenericArgsRef<'tcx>),
|
||||||
|
|
||||||
/// The MIR is a generator. The signature is that generators take
|
/// The MIR is a generator. The signature is that generators take
|
||||||
/// no parameters and return the result of
|
/// no parameters and return the result of
|
||||||
/// `ClosureSubsts::generator_return_ty`.
|
/// `ClosureArgs::generator_return_ty`.
|
||||||
Generator(DefId, SubstsRef<'tcx>, hir::Movability),
|
Generator(DefId, GenericArgsRef<'tcx>, hir::Movability),
|
||||||
|
|
||||||
/// The MIR is a fn item with the given `DefId` and substs. The signature
|
/// The MIR is a fn item with the given `DefId` and args. The signature
|
||||||
/// of the function can be bound then with the `fn_sig` query.
|
/// of the function can be bound then with the `fn_sig` query.
|
||||||
FnDef(DefId, SubstsRef<'tcx>),
|
FnDef(DefId, GenericArgsRef<'tcx>),
|
||||||
|
|
||||||
/// The MIR represents some form of constant. The signature then
|
/// The MIR represents some form of constant. The signature then
|
||||||
/// is that it has no inputs and a single return value, which is
|
/// is that it has no inputs and a single return value, which is
|
||||||
/// the value of the constant.
|
/// the value of the constant.
|
||||||
Const(DefId, SubstsRef<'tcx>),
|
Const(DefId, GenericArgsRef<'tcx>),
|
||||||
|
|
||||||
/// The MIR represents an inline const. The signature has no inputs and a
|
/// The MIR represents an inline const. The signature has no inputs and a
|
||||||
/// single return value found via `InlineConstSubsts::ty`.
|
/// single return value found via `InlineConstArgs::ty`.
|
||||||
InlineConst(DefId, SubstsRef<'tcx>),
|
InlineConst(DefId, GenericArgsRef<'tcx>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> DefiningTy<'tcx> {
|
impl<'tcx> DefiningTy<'tcx> {
|
||||||
|
@ -117,9 +117,9 @@ impl<'tcx> DefiningTy<'tcx> {
|
||||||
/// match up with the upvar order in the HIR, typesystem, and MIR.
|
/// match up with the upvar order in the HIR, typesystem, and MIR.
|
||||||
pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
|
pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
|
||||||
match self {
|
match self {
|
||||||
DefiningTy::Closure(_, substs) => Either::Left(substs.as_closure().upvar_tys()),
|
DefiningTy::Closure(_, args) => Either::Left(args.as_closure().upvar_tys()),
|
||||||
DefiningTy::Generator(_, substs, _) => {
|
DefiningTy::Generator(_, args, _) => {
|
||||||
Either::Right(Either::Left(substs.as_generator().upvar_tys()))
|
Either::Right(Either::Left(args.as_generator().upvar_tys()))
|
||||||
}
|
}
|
||||||
DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => {
|
DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => {
|
||||||
Either::Right(Either::Right(iter::empty()))
|
Either::Right(Either::Right(iter::empty()))
|
||||||
|
@ -164,9 +164,9 @@ struct UniversalRegionIndices<'tcx> {
|
||||||
/// used because trait matching and type-checking will feed us
|
/// used because trait matching and type-checking will feed us
|
||||||
/// region constraints that reference those regions and we need to
|
/// region constraints that reference those regions and we need to
|
||||||
/// be able to map them to our internal `RegionVid`. This is
|
/// be able to map them to our internal `RegionVid`. This is
|
||||||
/// basically equivalent to an `InternalSubsts`, except that it also
|
/// basically equivalent to an `GenericArgs`, except that it also
|
||||||
/// contains an entry for `ReStatic` -- it might be nice to just
|
/// contains an entry for `ReStatic` -- it might be nice to just
|
||||||
/// use a substs, and then handle `ReStatic` another way.
|
/// use a args, and then handle `ReStatic` another way.
|
||||||
indices: FxHashMap<ty::Region<'tcx>, RegionVid>,
|
indices: FxHashMap<ty::Region<'tcx>, RegionVid>,
|
||||||
|
|
||||||
/// The vid assigned to `'static`. Used only for diagnostics.
|
/// The vid assigned to `'static`. Used only for diagnostics.
|
||||||
|
@ -243,13 +243,13 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||||
/// `V[1]: V[2]`.
|
/// `V[1]: V[2]`.
|
||||||
pub fn closure_mapping(
|
pub fn closure_mapping(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
closure_substs: SubstsRef<'tcx>,
|
closure_args: GenericArgsRef<'tcx>,
|
||||||
expected_num_vars: usize,
|
expected_num_vars: usize,
|
||||||
closure_def_id: LocalDefId,
|
closure_def_id: LocalDefId,
|
||||||
) -> IndexVec<RegionVid, ty::Region<'tcx>> {
|
) -> IndexVec<RegionVid, ty::Region<'tcx>> {
|
||||||
let mut region_mapping = IndexVec::with_capacity(expected_num_vars);
|
let mut region_mapping = IndexVec::with_capacity(expected_num_vars);
|
||||||
region_mapping.push(tcx.lifetimes.re_static);
|
region_mapping.push(tcx.lifetimes.re_static);
|
||||||
tcx.for_each_free_region(&closure_substs, |fr| {
|
tcx.for_each_free_region(&closure_args, |fr| {
|
||||||
region_mapping.push(fr);
|
region_mapping.push(fr);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -334,11 +334,11 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||||
/// state.
|
/// state.
|
||||||
pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) {
|
pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) {
|
||||||
match self.defining_ty {
|
match self.defining_ty {
|
||||||
DefiningTy::Closure(def_id, substs) => {
|
DefiningTy::Closure(def_id, args) => {
|
||||||
err.note(format!(
|
err.note(format!(
|
||||||
"defining type: {} with closure substs {:#?}",
|
"defining type: {} with closure args {:#?}",
|
||||||
tcx.def_path_str_with_substs(def_id, substs),
|
tcx.def_path_str_with_args(def_id, args),
|
||||||
&substs[tcx.generics_of(def_id).parent_count..],
|
&args[tcx.generics_of(def_id).parent_count..],
|
||||||
));
|
));
|
||||||
|
|
||||||
// FIXME: It'd be nice to print the late-bound regions
|
// FIXME: It'd be nice to print the late-bound regions
|
||||||
|
@ -350,11 +350,11 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||||
err.note(format!("late-bound region is {:?}", self.to_region_vid(r)));
|
err.note(format!("late-bound region is {:?}", self.to_region_vid(r)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
DefiningTy::Generator(def_id, substs, _) => {
|
DefiningTy::Generator(def_id, args, _) => {
|
||||||
err.note(format!(
|
err.note(format!(
|
||||||
"defining type: {} with generator substs {:#?}",
|
"defining type: {} with generator args {:#?}",
|
||||||
tcx.def_path_str_with_substs(def_id, substs),
|
tcx.def_path_str_with_args(def_id, args),
|
||||||
&substs[tcx.generics_of(def_id).parent_count..],
|
&args[tcx.generics_of(def_id).parent_count..],
|
||||||
));
|
));
|
||||||
|
|
||||||
// FIXME: As above, we'd like to print out the region
|
// FIXME: As above, we'd like to print out the region
|
||||||
|
@ -364,22 +364,19 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||||
err.note(format!("late-bound region is {:?}", self.to_region_vid(r)));
|
err.note(format!("late-bound region is {:?}", self.to_region_vid(r)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
DefiningTy::FnDef(def_id, substs) => {
|
DefiningTy::FnDef(def_id, args) => {
|
||||||
err.note(format!(
|
err.note(format!("defining type: {}", tcx.def_path_str_with_args(def_id, args),));
|
||||||
"defining type: {}",
|
|
||||||
tcx.def_path_str_with_substs(def_id, substs),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
DefiningTy::Const(def_id, substs) => {
|
DefiningTy::Const(def_id, args) => {
|
||||||
err.note(format!(
|
err.note(format!(
|
||||||
"defining constant type: {}",
|
"defining constant type: {}",
|
||||||
tcx.def_path_str_with_substs(def_id, substs),
|
tcx.def_path_str_with_args(def_id, args),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
DefiningTy::InlineConst(def_id, substs) => {
|
DefiningTy::InlineConst(def_id, args) => {
|
||||||
err.note(format!(
|
err.note(format!(
|
||||||
"defining inline constant type: {}",
|
"defining inline constant type: {}",
|
||||||
tcx.def_path_str_with_substs(def_id, substs),
|
tcx.def_path_str_with_args(def_id, args),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -501,8 +498,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||||
.as_var();
|
.as_var();
|
||||||
|
|
||||||
let region = ty::Region::new_var(self.infcx.tcx, reg_vid);
|
let region = ty::Region::new_var(self.infcx.tcx, reg_vid);
|
||||||
let va_list_ty =
|
let va_list_ty = self
|
||||||
self.infcx.tcx.type_of(va_list_did).subst(self.infcx.tcx, &[region.into()]);
|
.infcx
|
||||||
|
.tcx
|
||||||
|
.type_of(va_list_did)
|
||||||
|
.instantiate(self.infcx.tcx, &[region.into()]);
|
||||||
|
|
||||||
unnormalized_input_tys = self.infcx.tcx.mk_type_list_from_iter(
|
unnormalized_input_tys = self.infcx.tcx.mk_type_list_from_iter(
|
||||||
unnormalized_input_tys.iter().copied().chain(iter::once(va_list_ty)),
|
unnormalized_input_tys.iter().copied().chain(iter::once(va_list_ty)),
|
||||||
|
@ -522,7 +522,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||||
debug!("build: local regions = {}..{}", first_local_index, num_universals);
|
debug!("build: local regions = {}..{}", first_local_index, num_universals);
|
||||||
|
|
||||||
let yield_ty = match defining_ty {
|
let yield_ty = match defining_ty {
|
||||||
DefiningTy::Generator(_, substs, _) => Some(substs.as_generator().yield_ty()),
|
DefiningTy::Generator(_, args, _) => Some(args.as_generator().yield_ty()),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -548,7 +548,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||||
|
|
||||||
match tcx.hir().body_owner_kind(self.mir_def) {
|
match tcx.hir().body_owner_kind(self.mir_def) {
|
||||||
BodyOwnerKind::Closure | BodyOwnerKind::Fn => {
|
BodyOwnerKind::Closure | BodyOwnerKind::Fn => {
|
||||||
let defining_ty = tcx.type_of(self.mir_def).subst_identity();
|
let defining_ty = tcx.type_of(self.mir_def).instantiate_identity();
|
||||||
|
|
||||||
debug!("defining_ty (pre-replacement): {:?}", defining_ty);
|
debug!("defining_ty (pre-replacement): {:?}", defining_ty);
|
||||||
|
|
||||||
|
@ -556,11 +556,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||||
self.infcx.replace_free_regions_with_nll_infer_vars(FR, defining_ty);
|
self.infcx.replace_free_regions_with_nll_infer_vars(FR, defining_ty);
|
||||||
|
|
||||||
match *defining_ty.kind() {
|
match *defining_ty.kind() {
|
||||||
ty::Closure(def_id, substs) => DefiningTy::Closure(def_id, substs),
|
ty::Closure(def_id, args) => DefiningTy::Closure(def_id, args),
|
||||||
ty::Generator(def_id, substs, movability) => {
|
ty::Generator(def_id, args, movability) => {
|
||||||
DefiningTy::Generator(def_id, substs, movability)
|
DefiningTy::Generator(def_id, args, movability)
|
||||||
}
|
}
|
||||||
ty::FnDef(def_id, substs) => DefiningTy::FnDef(def_id, substs),
|
ty::FnDef(def_id, args) => DefiningTy::FnDef(def_id, args),
|
||||||
_ => span_bug!(
|
_ => span_bug!(
|
||||||
tcx.def_span(self.mir_def),
|
tcx.def_span(self.mir_def),
|
||||||
"expected defining type for `{:?}`: `{:?}`",
|
"expected defining type for `{:?}`: `{:?}`",
|
||||||
|
@ -571,11 +571,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
BodyOwnerKind::Const | BodyOwnerKind::Static(..) => {
|
BodyOwnerKind::Const | BodyOwnerKind::Static(..) => {
|
||||||
let identity_substs = InternalSubsts::identity_for_item(tcx, typeck_root_def_id);
|
let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id);
|
||||||
if self.mir_def.to_def_id() == typeck_root_def_id {
|
if self.mir_def.to_def_id() == typeck_root_def_id {
|
||||||
let substs =
|
let args =
|
||||||
self.infcx.replace_free_regions_with_nll_infer_vars(FR, identity_substs);
|
self.infcx.replace_free_regions_with_nll_infer_vars(FR, identity_args);
|
||||||
DefiningTy::Const(self.mir_def.to_def_id(), substs)
|
DefiningTy::Const(self.mir_def.to_def_id(), args)
|
||||||
} else {
|
} else {
|
||||||
// FIXME this line creates a dependency between borrowck and typeck.
|
// FIXME this line creates a dependency between borrowck and typeck.
|
||||||
//
|
//
|
||||||
|
@ -584,18 +584,18 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||||
// into borrowck, which is ICE #78174.
|
// into borrowck, which is ICE #78174.
|
||||||
//
|
//
|
||||||
// As a workaround, inline consts have an additional generic param (`ty`
|
// As a workaround, inline consts have an additional generic param (`ty`
|
||||||
// below), so that `type_of(inline_const_def_id).substs(substs)` uses the
|
// below), so that `type_of(inline_const_def_id).args(args)` uses the
|
||||||
// proper type with NLL infer vars.
|
// proper type with NLL infer vars.
|
||||||
let ty = tcx
|
let ty = tcx
|
||||||
.typeck(self.mir_def)
|
.typeck(self.mir_def)
|
||||||
.node_type(tcx.local_def_id_to_hir_id(self.mir_def));
|
.node_type(tcx.local_def_id_to_hir_id(self.mir_def));
|
||||||
let substs = InlineConstSubsts::new(
|
let args = InlineConstArgs::new(
|
||||||
tcx,
|
tcx,
|
||||||
InlineConstSubstsParts { parent_substs: identity_substs, ty },
|
InlineConstArgsParts { parent_args: identity_args, ty },
|
||||||
)
|
)
|
||||||
.substs;
|
.args;
|
||||||
let substs = self.infcx.replace_free_regions_with_nll_infer_vars(FR, substs);
|
let args = self.infcx.replace_free_regions_with_nll_infer_vars(FR, args);
|
||||||
DefiningTy::InlineConst(self.mir_def.to_def_id(), substs)
|
DefiningTy::InlineConst(self.mir_def.to_def_id(), args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -612,29 +612,29 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||||
) -> UniversalRegionIndices<'tcx> {
|
) -> UniversalRegionIndices<'tcx> {
|
||||||
let tcx = self.infcx.tcx;
|
let tcx = self.infcx.tcx;
|
||||||
let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id());
|
let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id());
|
||||||
let identity_substs = InternalSubsts::identity_for_item(tcx, typeck_root_def_id);
|
let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id);
|
||||||
let fr_substs = match defining_ty {
|
let fr_args = match defining_ty {
|
||||||
DefiningTy::Closure(_, substs)
|
DefiningTy::Closure(_, args)
|
||||||
| DefiningTy::Generator(_, substs, _)
|
| DefiningTy::Generator(_, args, _)
|
||||||
| DefiningTy::InlineConst(_, substs) => {
|
| DefiningTy::InlineConst(_, args) => {
|
||||||
// In the case of closures, we rely on the fact that
|
// In the case of closures, we rely on the fact that
|
||||||
// the first N elements in the ClosureSubsts are
|
// the first N elements in the ClosureArgs are
|
||||||
// inherited from the `typeck_root_def_id`.
|
// inherited from the `typeck_root_def_id`.
|
||||||
// Therefore, when we zip together (below) with
|
// Therefore, when we zip together (below) with
|
||||||
// `identity_substs`, we will get only those regions
|
// `identity_args`, we will get only those regions
|
||||||
// that correspond to early-bound regions declared on
|
// that correspond to early-bound regions declared on
|
||||||
// the `typeck_root_def_id`.
|
// the `typeck_root_def_id`.
|
||||||
assert!(substs.len() >= identity_substs.len());
|
assert!(args.len() >= identity_args.len());
|
||||||
assert_eq!(substs.regions().count(), identity_substs.regions().count());
|
assert_eq!(args.regions().count(), identity_args.regions().count());
|
||||||
substs
|
args
|
||||||
}
|
}
|
||||||
|
|
||||||
DefiningTy::FnDef(_, substs) | DefiningTy::Const(_, substs) => substs,
|
DefiningTy::FnDef(_, args) | DefiningTy::Const(_, args) => args,
|
||||||
};
|
};
|
||||||
|
|
||||||
let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static));
|
let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static));
|
||||||
let subst_mapping =
|
let subst_mapping =
|
||||||
iter::zip(identity_substs.regions(), fr_substs.regions().map(|r| r.as_var()));
|
iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var()));
|
||||||
|
|
||||||
UniversalRegionIndices { indices: global_mapping.chain(subst_mapping).collect(), fr_static }
|
UniversalRegionIndices { indices: global_mapping.chain(subst_mapping).collect(), fr_static }
|
||||||
}
|
}
|
||||||
|
@ -646,9 +646,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||||
) -> ty::Binder<'tcx, &'tcx ty::List<Ty<'tcx>>> {
|
) -> ty::Binder<'tcx, &'tcx ty::List<Ty<'tcx>>> {
|
||||||
let tcx = self.infcx.tcx;
|
let tcx = self.infcx.tcx;
|
||||||
match defining_ty {
|
match defining_ty {
|
||||||
DefiningTy::Closure(def_id, substs) => {
|
DefiningTy::Closure(def_id, args) => {
|
||||||
assert_eq!(self.mir_def.to_def_id(), def_id);
|
assert_eq!(self.mir_def.to_def_id(), def_id);
|
||||||
let closure_sig = substs.as_closure().sig();
|
let closure_sig = args.as_closure().sig();
|
||||||
let inputs_and_output = closure_sig.inputs_and_output();
|
let inputs_and_output = closure_sig.inputs_and_output();
|
||||||
let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
|
let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
|
||||||
inputs_and_output
|
inputs_and_output
|
||||||
|
@ -661,7 +661,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||||
kind: ty::BrEnv,
|
kind: ty::BrEnv,
|
||||||
};
|
};
|
||||||
let env_region = ty::Region::new_late_bound(tcx, ty::INNERMOST, br);
|
let env_region = ty::Region::new_late_bound(tcx, ty::INNERMOST, br);
|
||||||
let closure_ty = tcx.closure_env_ty(def_id, substs, env_region).unwrap();
|
let closure_ty = tcx.closure_env_ty(def_id, args, env_region).unwrap();
|
||||||
|
|
||||||
// The "inputs" of the closure in the
|
// The "inputs" of the closure in the
|
||||||
// signature appear as a tuple. The MIR side
|
// signature appear as a tuple. The MIR side
|
||||||
|
@ -681,18 +681,18 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
DefiningTy::Generator(def_id, substs, movability) => {
|
DefiningTy::Generator(def_id, args, movability) => {
|
||||||
assert_eq!(self.mir_def.to_def_id(), def_id);
|
assert_eq!(self.mir_def.to_def_id(), def_id);
|
||||||
let resume_ty = substs.as_generator().resume_ty();
|
let resume_ty = args.as_generator().resume_ty();
|
||||||
let output = substs.as_generator().return_ty();
|
let output = args.as_generator().return_ty();
|
||||||
let generator_ty = Ty::new_generator(tcx, def_id, substs, movability);
|
let generator_ty = Ty::new_generator(tcx, def_id, args, movability);
|
||||||
let inputs_and_output =
|
let inputs_and_output =
|
||||||
self.infcx.tcx.mk_type_list(&[generator_ty, resume_ty, output]);
|
self.infcx.tcx.mk_type_list(&[generator_ty, resume_ty, output]);
|
||||||
ty::Binder::dummy(inputs_and_output)
|
ty::Binder::dummy(inputs_and_output)
|
||||||
}
|
}
|
||||||
|
|
||||||
DefiningTy::FnDef(def_id, _) => {
|
DefiningTy::FnDef(def_id, _) => {
|
||||||
let sig = tcx.fn_sig(def_id).subst_identity();
|
let sig = tcx.fn_sig(def_id).instantiate_identity();
|
||||||
let sig = indices.fold_to_region_vids(tcx, sig);
|
let sig = indices.fold_to_region_vids(tcx, sig);
|
||||||
sig.inputs_and_output()
|
sig.inputs_and_output()
|
||||||
}
|
}
|
||||||
|
@ -701,14 +701,14 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||||
// For a constant body, there are no inputs, and one
|
// For a constant body, there are no inputs, and one
|
||||||
// "output" (the type of the constant).
|
// "output" (the type of the constant).
|
||||||
assert_eq!(self.mir_def.to_def_id(), def_id);
|
assert_eq!(self.mir_def.to_def_id(), def_id);
|
||||||
let ty = tcx.type_of(self.mir_def).subst_identity();
|
let ty = tcx.type_of(self.mir_def).instantiate_identity();
|
||||||
let ty = indices.fold_to_region_vids(tcx, ty);
|
let ty = indices.fold_to_region_vids(tcx, ty);
|
||||||
ty::Binder::dummy(tcx.mk_type_list(&[ty]))
|
ty::Binder::dummy(tcx.mk_type_list(&[ty]))
|
||||||
}
|
}
|
||||||
|
|
||||||
DefiningTy::InlineConst(def_id, substs) => {
|
DefiningTy::InlineConst(def_id, args) => {
|
||||||
assert_eq!(self.mir_def.to_def_id(), def_id);
|
assert_eq!(self.mir_def.to_def_id(), def_id);
|
||||||
let ty = substs.as_inline_const().ty();
|
let ty = args.as_inline_const().ty();
|
||||||
ty::Binder::dummy(tcx.mk_type_list(&[ty]))
|
ty::Binder::dummy(tcx.mk_type_list(&[ty]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ pub(crate) fn get_function_sig<'tcx>(
|
||||||
default_call_conv: CallConv,
|
default_call_conv: CallConv,
|
||||||
inst: Instance<'tcx>,
|
inst: Instance<'tcx>,
|
||||||
) -> Signature {
|
) -> Signature {
|
||||||
assert!(!inst.substs.has_infer());
|
assert!(!inst.args.has_infer());
|
||||||
clif_sig_from_fn_abi(
|
clif_sig_from_fn_abi(
|
||||||
tcx,
|
tcx,
|
||||||
default_call_conv,
|
default_call_conv,
|
||||||
|
@ -377,16 +377,16 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
||||||
let ret_place = codegen_place(fx, destination);
|
let ret_place = codegen_place(fx, destination);
|
||||||
|
|
||||||
// Handle special calls like intrinsics and empty drop glue.
|
// Handle special calls like intrinsics and empty drop glue.
|
||||||
let instance = if let ty::FnDef(def_id, substs) = *func.layout().ty.kind() {
|
let instance = if let ty::FnDef(def_id, fn_args) = *func.layout().ty.kind() {
|
||||||
let instance =
|
let instance =
|
||||||
ty::Instance::expect_resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, substs)
|
ty::Instance::expect_resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, fn_args)
|
||||||
.polymorphize(fx.tcx);
|
.polymorphize(fx.tcx);
|
||||||
|
|
||||||
if fx.tcx.symbol_name(instance).name.starts_with("llvm.") {
|
if fx.tcx.symbol_name(instance).name.starts_with("llvm.") {
|
||||||
crate::intrinsics::codegen_llvm_intrinsic_call(
|
crate::intrinsics::codegen_llvm_intrinsic_call(
|
||||||
fx,
|
fx,
|
||||||
&fx.tcx.symbol_name(instance).name,
|
&fx.tcx.symbol_name(instance).name,
|
||||||
substs,
|
fn_args,
|
||||||
args,
|
args,
|
||||||
ret_place,
|
ret_place,
|
||||||
target,
|
target,
|
||||||
|
@ -611,7 +611,7 @@ pub(crate) fn codegen_drop<'tcx>(
|
||||||
// `Instance::resolve_drop_in_place`?
|
// `Instance::resolve_drop_in_place`?
|
||||||
let virtual_drop = Instance {
|
let virtual_drop = Instance {
|
||||||
def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0),
|
def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0),
|
||||||
substs: drop_instance.substs,
|
args: drop_instance.args,
|
||||||
};
|
};
|
||||||
let fn_abi =
|
let fn_abi =
|
||||||
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, ty::List::empty());
|
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, ty::List::empty());
|
||||||
|
@ -648,7 +648,7 @@ pub(crate) fn codegen_drop<'tcx>(
|
||||||
|
|
||||||
let virtual_drop = Instance {
|
let virtual_drop = Instance {
|
||||||
def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0),
|
def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0),
|
||||||
substs: drop_instance.substs,
|
args: drop_instance.args,
|
||||||
};
|
};
|
||||||
let fn_abi =
|
let fn_abi =
|
||||||
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, ty::List::empty());
|
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, ty::List::empty());
|
||||||
|
|
|
@ -28,7 +28,7 @@ pub(crate) fn codegen_fn<'tcx>(
|
||||||
module: &mut dyn Module,
|
module: &mut dyn Module,
|
||||||
instance: Instance<'tcx>,
|
instance: Instance<'tcx>,
|
||||||
) -> CodegenedFunction {
|
) -> CodegenedFunction {
|
||||||
debug_assert!(!instance.substs.has_infer());
|
debug_assert!(!instance.args.has_infer());
|
||||||
|
|
||||||
let symbol_name = tcx.symbol_name(instance).name.to_string();
|
let symbol_name = tcx.symbol_name(instance).name.to_string();
|
||||||
let _timer = tcx.prof.generic_activity_with_arg("codegen fn", &*symbol_name);
|
let _timer = tcx.prof.generic_activity_with_arg("codegen fn", &*symbol_name);
|
||||||
|
@ -578,13 +578,13 @@ fn codegen_stmt<'tcx>(
|
||||||
let from_ty = fx.monomorphize(operand.ty(&fx.mir.local_decls, fx.tcx));
|
let from_ty = fx.monomorphize(operand.ty(&fx.mir.local_decls, fx.tcx));
|
||||||
let to_layout = fx.layout_of(fx.monomorphize(to_ty));
|
let to_layout = fx.layout_of(fx.monomorphize(to_ty));
|
||||||
match *from_ty.kind() {
|
match *from_ty.kind() {
|
||||||
ty::FnDef(def_id, substs) => {
|
ty::FnDef(def_id, args) => {
|
||||||
let func_ref = fx.get_function_ref(
|
let func_ref = fx.get_function_ref(
|
||||||
Instance::resolve_for_fn_ptr(
|
Instance::resolve_for_fn_ptr(
|
||||||
fx.tcx,
|
fx.tcx,
|
||||||
ParamEnv::reveal_all(),
|
ParamEnv::reveal_all(),
|
||||||
def_id,
|
def_id,
|
||||||
substs,
|
args,
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.polymorphize(fx.tcx),
|
.polymorphize(fx.tcx),
|
||||||
|
@ -668,11 +668,11 @@ fn codegen_stmt<'tcx>(
|
||||||
) => {
|
) => {
|
||||||
let operand = codegen_operand(fx, operand);
|
let operand = codegen_operand(fx, operand);
|
||||||
match *operand.layout().ty.kind() {
|
match *operand.layout().ty.kind() {
|
||||||
ty::Closure(def_id, substs) => {
|
ty::Closure(def_id, args) => {
|
||||||
let instance = Instance::resolve_closure(
|
let instance = Instance::resolve_closure(
|
||||||
fx.tcx,
|
fx.tcx,
|
||||||
def_id,
|
def_id,
|
||||||
substs,
|
args,
|
||||||
ty::ClosureKind::FnOnce,
|
ty::ClosureKind::FnOnce,
|
||||||
)
|
)
|
||||||
.expect("failed to normalize and resolve closure during codegen")
|
.expect("failed to normalize and resolve closure during codegen")
|
||||||
|
|
|
@ -57,7 +57,7 @@ pub(crate) fn codegen_tls_ref<'tcx>(
|
||||||
let tls_ptr = if !def_id.is_local() && fx.tcx.needs_thread_local_shim(def_id) {
|
let tls_ptr = if !def_id.is_local() && fx.tcx.needs_thread_local_shim(def_id) {
|
||||||
let instance = ty::Instance {
|
let instance = ty::Instance {
|
||||||
def: ty::InstanceDef::ThreadLocalShim(def_id),
|
def: ty::InstanceDef::ThreadLocalShim(def_id),
|
||||||
substs: ty::InternalSubsts::empty(),
|
args: ty::GenericArgs::empty(),
|
||||||
};
|
};
|
||||||
let func_ref = fx.get_function_ref(instance);
|
let func_ref = fx.get_function_ref(instance);
|
||||||
let call = fx.bcx.ins().call(func_ref, &[]);
|
let call = fx.bcx.ins().call(func_ref, &[]);
|
||||||
|
|
|
@ -42,7 +42,7 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
|
||||||
InlineAsmOperand::SymFn { anon_const } => {
|
InlineAsmOperand::SymFn { anon_const } => {
|
||||||
let ty = tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id);
|
let ty = tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id);
|
||||||
let instance = match ty.kind() {
|
let instance = match ty.kind() {
|
||||||
&ty::FnDef(def_id, substs) => Instance::new(def_id, substs),
|
&ty::FnDef(def_id, args) => Instance::new(def_id, args),
|
||||||
_ => span_bug!(op_sp, "asm sym is not a function"),
|
_ => span_bug!(op_sp, "asm sym is not a function"),
|
||||||
};
|
};
|
||||||
let symbol = tcx.symbol_name(instance);
|
let symbol = tcx.symbol_name(instance);
|
||||||
|
|
|
@ -254,12 +254,12 @@ pub(crate) fn codegen_inline_asm<'tcx>(
|
||||||
}
|
}
|
||||||
InlineAsmOperand::SymFn { ref value } => {
|
InlineAsmOperand::SymFn { ref value } => {
|
||||||
let literal = fx.monomorphize(value.literal);
|
let literal = fx.monomorphize(value.literal);
|
||||||
if let ty::FnDef(def_id, substs) = *literal.ty().kind() {
|
if let ty::FnDef(def_id, args) = *literal.ty().kind() {
|
||||||
let instance = ty::Instance::resolve_for_fn_ptr(
|
let instance = ty::Instance::resolve_for_fn_ptr(
|
||||||
fx.tcx,
|
fx.tcx,
|
||||||
ty::ParamEnv::reveal_all(),
|
ty::ParamEnv::reveal_all(),
|
||||||
def_id,
|
def_id,
|
||||||
substs,
|
args,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let symbol = fx.tcx.symbol_name(instance);
|
let symbol = fx.tcx.symbol_name(instance);
|
||||||
|
|
|
@ -3,23 +3,35 @@
|
||||||
use crate::intrinsics::*;
|
use crate::intrinsics::*;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
use rustc_middle::ty::subst::SubstsRef;
|
use rustc_middle::ty::GenericArgsRef;
|
||||||
|
|
||||||
pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
|
pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
|
||||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||||
intrinsic: &str,
|
intrinsic: &str,
|
||||||
substs: SubstsRef<'tcx>,
|
generic_args: GenericArgsRef<'tcx>,
|
||||||
args: &[mir::Operand<'tcx>],
|
args: &[mir::Operand<'tcx>],
|
||||||
ret: CPlace<'tcx>,
|
ret: CPlace<'tcx>,
|
||||||
target: Option<BasicBlock>,
|
target: Option<BasicBlock>,
|
||||||
) {
|
) {
|
||||||
if intrinsic.starts_with("llvm.aarch64") {
|
if intrinsic.starts_with("llvm.aarch64") {
|
||||||
return llvm_aarch64::codegen_aarch64_llvm_intrinsic_call(
|
return llvm_aarch64::codegen_aarch64_llvm_intrinsic_call(
|
||||||
fx, intrinsic, substs, args, ret, target,
|
fx,
|
||||||
|
intrinsic,
|
||||||
|
generic_args,
|
||||||
|
args,
|
||||||
|
ret,
|
||||||
|
target,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if intrinsic.starts_with("llvm.x86") {
|
if intrinsic.starts_with("llvm.x86") {
|
||||||
return llvm_x86::codegen_x86_llvm_intrinsic_call(fx, intrinsic, substs, args, ret, target);
|
return llvm_x86::codegen_x86_llvm_intrinsic_call(
|
||||||
|
fx,
|
||||||
|
intrinsic,
|
||||||
|
generic_args,
|
||||||
|
args,
|
||||||
|
ret,
|
||||||
|
target,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
match intrinsic {
|
match intrinsic {
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
use crate::intrinsics::*;
|
use crate::intrinsics::*;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
use rustc_middle::ty::subst::SubstsRef;
|
use rustc_middle::ty::GenericArgsRef;
|
||||||
|
|
||||||
pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
|
pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
|
||||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||||
intrinsic: &str,
|
intrinsic: &str,
|
||||||
_substs: SubstsRef<'tcx>,
|
_args: GenericArgsRef<'tcx>,
|
||||||
args: &[mir::Operand<'tcx>],
|
args: &[mir::Operand<'tcx>],
|
||||||
ret: CPlace<'tcx>,
|
ret: CPlace<'tcx>,
|
||||||
target: Option<BasicBlock>,
|
target: Option<BasicBlock>,
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
use crate::intrinsics::*;
|
use crate::intrinsics::*;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
use rustc_middle::ty::subst::SubstsRef;
|
use rustc_middle::ty::GenericArgsRef;
|
||||||
|
|
||||||
pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
||||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||||
intrinsic: &str,
|
intrinsic: &str,
|
||||||
_substs: SubstsRef<'tcx>,
|
_args: GenericArgsRef<'tcx>,
|
||||||
args: &[mir::Operand<'tcx>],
|
args: &[mir::Operand<'tcx>],
|
||||||
ret: CPlace<'tcx>,
|
ret: CPlace<'tcx>,
|
||||||
target: Option<BasicBlock>,
|
target: Option<BasicBlock>,
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub(crate) use llvm::codegen_llvm_intrinsic_call;
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_middle::ty::layout::{HasParamEnv, ValidityRequirement};
|
use rustc_middle::ty::layout::{HasParamEnv, ValidityRequirement};
|
||||||
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
|
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
|
||||||
use rustc_middle::ty::subst::SubstsRef;
|
use rustc_middle::ty::GenericArgsRef;
|
||||||
use rustc_span::symbol::{kw, sym, Symbol};
|
use rustc_span::symbol::{kw, sym, Symbol};
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
@ -213,13 +213,13 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
|
||||||
source_info: mir::SourceInfo,
|
source_info: mir::SourceInfo,
|
||||||
) {
|
) {
|
||||||
let intrinsic = fx.tcx.item_name(instance.def_id());
|
let intrinsic = fx.tcx.item_name(instance.def_id());
|
||||||
let substs = instance.substs;
|
let instance_args = instance.args;
|
||||||
|
|
||||||
if intrinsic.as_str().starts_with("simd_") {
|
if intrinsic.as_str().starts_with("simd_") {
|
||||||
self::simd::codegen_simd_intrinsic_call(
|
self::simd::codegen_simd_intrinsic_call(
|
||||||
fx,
|
fx,
|
||||||
intrinsic,
|
intrinsic,
|
||||||
substs,
|
instance_args,
|
||||||
args,
|
args,
|
||||||
destination,
|
destination,
|
||||||
target.expect("target for simd intrinsic"),
|
target.expect("target for simd intrinsic"),
|
||||||
|
@ -233,7 +233,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
|
||||||
fx,
|
fx,
|
||||||
instance,
|
instance,
|
||||||
intrinsic,
|
intrinsic,
|
||||||
substs,
|
instance_args,
|
||||||
args,
|
args,
|
||||||
destination,
|
destination,
|
||||||
target,
|
target,
|
||||||
|
@ -365,7 +365,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||||
instance: Instance<'tcx>,
|
instance: Instance<'tcx>,
|
||||||
intrinsic: Symbol,
|
intrinsic: Symbol,
|
||||||
substs: SubstsRef<'tcx>,
|
generic_args: GenericArgsRef<'tcx>,
|
||||||
args: &[mir::Operand<'tcx>],
|
args: &[mir::Operand<'tcx>],
|
||||||
ret: CPlace<'tcx>,
|
ret: CPlace<'tcx>,
|
||||||
destination: Option<BasicBlock>,
|
destination: Option<BasicBlock>,
|
||||||
|
@ -394,7 +394,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||||
let dst = dst.load_scalar(fx);
|
let dst = dst.load_scalar(fx);
|
||||||
let count = count.load_scalar(fx);
|
let count = count.load_scalar(fx);
|
||||||
|
|
||||||
let elem_ty = substs.type_at(0);
|
let elem_ty = generic_args.type_at(0);
|
||||||
let elem_size: u64 = fx.layout_of(elem_ty).size.bytes();
|
let elem_size: u64 = fx.layout_of(elem_ty).size.bytes();
|
||||||
assert_eq!(args.len(), 3);
|
assert_eq!(args.len(), 3);
|
||||||
let byte_amount =
|
let byte_amount =
|
||||||
|
@ -410,7 +410,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||||
let src = src.load_scalar(fx);
|
let src = src.load_scalar(fx);
|
||||||
let count = count.load_scalar(fx);
|
let count = count.load_scalar(fx);
|
||||||
|
|
||||||
let elem_ty = substs.type_at(0);
|
let elem_ty = generic_args.type_at(0);
|
||||||
let elem_size: u64 = fx.layout_of(elem_ty).size.bytes();
|
let elem_size: u64 = fx.layout_of(elem_ty).size.bytes();
|
||||||
assert_eq!(args.len(), 3);
|
assert_eq!(args.len(), 3);
|
||||||
let byte_amount =
|
let byte_amount =
|
||||||
|
@ -428,7 +428,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||||
sym::size_of_val => {
|
sym::size_of_val => {
|
||||||
intrinsic_args!(fx, args => (ptr); intrinsic);
|
intrinsic_args!(fx, args => (ptr); intrinsic);
|
||||||
|
|
||||||
let layout = fx.layout_of(substs.type_at(0));
|
let layout = fx.layout_of(generic_args.type_at(0));
|
||||||
// Note: Can't use is_unsized here as truly unsized types need to take the fixed size
|
// Note: Can't use is_unsized here as truly unsized types need to take the fixed size
|
||||||
// branch
|
// branch
|
||||||
let size = if let Abi::ScalarPair(_, _) = ptr.layout().abi {
|
let size = if let Abi::ScalarPair(_, _) = ptr.layout().abi {
|
||||||
|
@ -443,7 +443,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||||
sym::min_align_of_val => {
|
sym::min_align_of_val => {
|
||||||
intrinsic_args!(fx, args => (ptr); intrinsic);
|
intrinsic_args!(fx, args => (ptr); intrinsic);
|
||||||
|
|
||||||
let layout = fx.layout_of(substs.type_at(0));
|
let layout = fx.layout_of(generic_args.type_at(0));
|
||||||
// Note: Can't use is_unsized here as truly unsized types need to take the fixed size
|
// Note: Can't use is_unsized here as truly unsized types need to take the fixed size
|
||||||
// branch
|
// branch
|
||||||
let align = if let Abi::ScalarPair(_, _) = ptr.layout().abi {
|
let align = if let Abi::ScalarPair(_, _) = ptr.layout().abi {
|
||||||
|
@ -602,7 +602,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||||
sym::assert_inhabited | sym::assert_zero_valid | sym::assert_mem_uninitialized_valid => {
|
sym::assert_inhabited | sym::assert_zero_valid | sym::assert_mem_uninitialized_valid => {
|
||||||
intrinsic_args!(fx, args => (); intrinsic);
|
intrinsic_args!(fx, args => (); intrinsic);
|
||||||
|
|
||||||
let ty = substs.type_at(0);
|
let ty = generic_args.type_at(0);
|
||||||
|
|
||||||
let requirement = ValidityRequirement::from_intrinsic(intrinsic);
|
let requirement = ValidityRequirement::from_intrinsic(intrinsic);
|
||||||
|
|
||||||
|
@ -674,7 +674,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||||
intrinsic_args!(fx, args => (ptr, base); intrinsic);
|
intrinsic_args!(fx, args => (ptr, base); intrinsic);
|
||||||
let ptr = ptr.load_scalar(fx);
|
let ptr = ptr.load_scalar(fx);
|
||||||
let base = base.load_scalar(fx);
|
let base = base.load_scalar(fx);
|
||||||
let ty = substs.type_at(0);
|
let ty = generic_args.type_at(0);
|
||||||
|
|
||||||
let pointee_size: u64 = fx.layout_of(ty).size.bytes();
|
let pointee_size: u64 = fx.layout_of(ty).size.bytes();
|
||||||
let diff_bytes = fx.bcx.ins().isub(ptr, base);
|
let diff_bytes = fx.bcx.ins().isub(ptr, base);
|
||||||
|
@ -720,7 +720,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||||
intrinsic_args!(fx, args => (ptr); intrinsic);
|
intrinsic_args!(fx, args => (ptr); intrinsic);
|
||||||
let ptr = ptr.load_scalar(fx);
|
let ptr = ptr.load_scalar(fx);
|
||||||
|
|
||||||
let ty = substs.type_at(0);
|
let ty = generic_args.type_at(0);
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => {
|
ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => {
|
||||||
// FIXME implement 128bit atomics
|
// FIXME implement 128bit atomics
|
||||||
|
@ -751,7 +751,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||||
intrinsic_args!(fx, args => (ptr, val); intrinsic);
|
intrinsic_args!(fx, args => (ptr, val); intrinsic);
|
||||||
let ptr = ptr.load_scalar(fx);
|
let ptr = ptr.load_scalar(fx);
|
||||||
|
|
||||||
let ty = substs.type_at(0);
|
let ty = generic_args.type_at(0);
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => {
|
ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => {
|
||||||
// FIXME implement 128bit atomics
|
// FIXME implement 128bit atomics
|
||||||
|
@ -1128,7 +1128,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||||
let lhs_ref = lhs_ref.load_scalar(fx);
|
let lhs_ref = lhs_ref.load_scalar(fx);
|
||||||
let rhs_ref = rhs_ref.load_scalar(fx);
|
let rhs_ref = rhs_ref.load_scalar(fx);
|
||||||
|
|
||||||
let size = fx.layout_of(substs.type_at(0)).layout.size();
|
let size = fx.layout_of(generic_args.type_at(0)).layout.size();
|
||||||
// FIXME add and use emit_small_memcmp
|
// FIXME add and use emit_small_memcmp
|
||||||
let is_eq_value = if size == Size::ZERO {
|
let is_eq_value = if size == Size::ZERO {
|
||||||
// No bytes means they're trivially equal
|
// No bytes means they're trivially equal
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! Codegen `extern "platform-intrinsic"` intrinsics.
|
//! Codegen `extern "platform-intrinsic"` intrinsics.
|
||||||
|
|
||||||
use rustc_middle::ty::subst::SubstsRef;
|
use rustc_middle::ty::GenericArgsRef;
|
||||||
use rustc_span::Symbol;
|
use rustc_span::Symbol;
|
||||||
use rustc_target::abi::Endian;
|
use rustc_target::abi::Endian;
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ fn report_simd_type_validation_error(
|
||||||
pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
||||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||||
intrinsic: Symbol,
|
intrinsic: Symbol,
|
||||||
_substs: SubstsRef<'tcx>,
|
_args: GenericArgsRef<'tcx>,
|
||||||
args: &[mir::Operand<'tcx>],
|
args: &[mir::Operand<'tcx>],
|
||||||
ret: CPlace<'tcx>,
|
ret: CPlace<'tcx>,
|
||||||
target: BasicBlock,
|
target: BasicBlock,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use rustc_hir::LangItem;
|
use rustc_hir::LangItem;
|
||||||
use rustc_middle::ty::subst::GenericArg;
|
|
||||||
use rustc_middle::ty::AssocKind;
|
use rustc_middle::ty::AssocKind;
|
||||||
|
use rustc_middle::ty::GenericArg;
|
||||||
use rustc_session::config::{sigpipe, EntryFnType};
|
use rustc_session::config::{sigpipe, EntryFnType};
|
||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::Ident;
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ pub(crate) fn maybe_create_entry_wrapper(
|
||||||
tcx,
|
tcx,
|
||||||
ParamEnv::reveal_all(),
|
ParamEnv::reveal_all(),
|
||||||
report.def_id,
|
report.def_id,
|
||||||
tcx.mk_substs(&[GenericArg::from(main_ret_ty)]),
|
tcx.mk_args(&[GenericArg::from(main_ret_ty)]),
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -146,7 +146,7 @@ pub(crate) fn maybe_create_entry_wrapper(
|
||||||
tcx,
|
tcx,
|
||||||
ParamEnv::reveal_all(),
|
ParamEnv::reveal_all(),
|
||||||
start_def_id,
|
start_def_id,
|
||||||
tcx.mk_substs(&[main_ret_ty.into()]),
|
tcx.mk_args(&[main_ret_ty.into()]),
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
//!
|
//!
|
||||||
//! function u0:22(i64) -> i8, i8 system_v {
|
//! function u0:22(i64) -> i8, i8 system_v {
|
||||||
//! ; symbol _ZN97_$LT$example..IsNotEmpty$u20$as$u20$mini_core..FnOnce$LT$$LP$$RF$$RF$$u5b$u16$u5d$$C$$RP$$GT$$GT$9call_once17hd517c453d67c0915E
|
//! ; symbol _ZN97_$LT$example..IsNotEmpty$u20$as$u20$mini_core..FnOnce$LT$$LP$$RF$$RF$$u5b$u16$u5d$$C$$RP$$GT$$GT$9call_once17hd517c453d67c0915E
|
||||||
//! ; instance Instance { def: Item(WithOptConstParam { did: DefId(0:42 ~ example[4e51]::{impl#0}::call_once), const_param_did: None }), substs: [ReErased, ReErased] }
|
//! ; instance Instance { def: Item(WithOptConstParam { did: DefId(0:42 ~ example[4e51]::{impl#0}::call_once), const_param_did: None }), args: [ReErased, ReErased] }
|
||||||
//! ; abi FnAbi { args: [ArgAbi { layout: TyAndLayout { ty: IsNotEmpty, layout: Layout { size: Size(0 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, abi: Aggregate { sized: true }, fields: Arbitrary { offsets: [], memory_index: [] }, largest_niche: None, variants: Single { index: 0 } } }, mode: Ignore }, ArgAbi { layout: TyAndLayout { ty: &&[u16], layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), variants: Single { index: 0 } } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(8 bytes)) }) }], ret: ArgAbi { layout: TyAndLayout { ty: (u8, u8), layout: Layout { size: Size(2 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, abi: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=255 }, Initialized { value: Int(I8, false), valid_range: 0..=255 }), fields: Arbitrary { offsets: [Size(0 bytes), Size(1 bytes)], memory_index: [0, 1] }, largest_niche: None, variants: Single { index: 0 } } }, mode: Pair(ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }, ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }) }, c_variadic: false, fixed_count: 1, conv: Rust, can_unwind: false }
|
//! ; abi FnAbi { args: [ArgAbi { layout: TyAndLayout { ty: IsNotEmpty, layout: Layout { size: Size(0 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, abi: Aggregate { sized: true }, fields: Arbitrary { offsets: [], memory_index: [] }, largest_niche: None, variants: Single { index: 0 } } }, mode: Ignore }, ArgAbi { layout: TyAndLayout { ty: &&[u16], layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), variants: Single { index: 0 } } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(8 bytes)) }) }], ret: ArgAbi { layout: TyAndLayout { ty: (u8, u8), layout: Layout { size: Size(2 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, abi: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=255 }, Initialized { value: Int(I8, false), valid_range: 0..=255 }), fields: Arbitrary { offsets: [Size(0 bytes), Size(1 bytes)], memory_index: [0, 1] }, largest_niche: None, variants: Single { index: 0 } } }, mode: Pair(ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }, ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }) }, c_variadic: false, fixed_count: 1, conv: Rust, can_unwind: false }
|
||||||
//!
|
//!
|
||||||
//! ; kind loc.idx param pass mode ty
|
//! ; kind loc.idx param pass mode ty
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
//!
|
//!
|
||||||
//! ss0 = explicit_slot 16
|
//! ss0 = explicit_slot 16
|
||||||
//! sig0 = (i64, i64) -> i8, i8 system_v
|
//! sig0 = (i64, i64) -> i8, i8 system_v
|
||||||
//! fn0 = colocated u0:23 sig0 ; Instance { def: Item(WithOptConstParam { did: DefId(0:46 ~ example[4e51]::{impl#1}::call_mut), const_param_did: None }), substs: [ReErased, ReErased] }
|
//! fn0 = colocated u0:23 sig0 ; Instance { def: Item(WithOptConstParam { did: DefId(0:46 ~ example[4e51]::{impl#1}::call_mut), const_param_did: None }), args: [ReErased, ReErased] }
|
||||||
//!
|
//!
|
||||||
//! block0(v0: i64):
|
//! block0(v0: i64):
|
||||||
//! nop
|
//! nop
|
||||||
|
@ -261,7 +261,7 @@ pub(crate) fn write_clif_file(
|
||||||
|
|
||||||
impl fmt::Debug for FunctionCx<'_, '_, '_> {
|
impl fmt::Debug for FunctionCx<'_, '_, '_> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
writeln!(f, "{:?}", self.instance.substs)?;
|
writeln!(f, "{:?}", self.instance.args)?;
|
||||||
writeln!(f, "{:?}", self.local_map)?;
|
writeln!(f, "{:?}", self.local_map)?;
|
||||||
|
|
||||||
let mut clif = String::new();
|
let mut clif = String::new();
|
||||||
|
|
|
@ -850,11 +850,11 @@ pub(crate) fn assert_assignable<'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(&ty::Adt(adt_def_a, substs_a), &ty::Adt(adt_def_b, substs_b))
|
(&ty::Adt(adt_def_a, args_a), &ty::Adt(adt_def_b, args_b))
|
||||||
if adt_def_a.did() == adt_def_b.did() =>
|
if adt_def_a.did() == adt_def_b.did() =>
|
||||||
{
|
{
|
||||||
let mut types_a = substs_a.types();
|
let mut types_a = args_a.types();
|
||||||
let mut types_b = substs_b.types();
|
let mut types_b = args_b.types();
|
||||||
loop {
|
loop {
|
||||||
match (types_a.next(), types_b.next()) {
|
match (types_a.next(), types_b.next()) {
|
||||||
(Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),
|
(Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),
|
||||||
|
@ -864,11 +864,11 @@ pub(crate) fn assert_assignable<'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(ty::Array(a, _), ty::Array(b, _)) => assert_assignable(fx, *a, *b, limit - 1),
|
(ty::Array(a, _), ty::Array(b, _)) => assert_assignable(fx, *a, *b, limit - 1),
|
||||||
(&ty::Closure(def_id_a, substs_a), &ty::Closure(def_id_b, substs_b))
|
(&ty::Closure(def_id_a, args_a), &ty::Closure(def_id_b, args_b))
|
||||||
if def_id_a == def_id_b =>
|
if def_id_a == def_id_b =>
|
||||||
{
|
{
|
||||||
let mut types_a = substs_a.types();
|
let mut types_a = args_a.types();
|
||||||
let mut types_b = substs_b.types();
|
let mut types_b = args_b.types();
|
||||||
loop {
|
loop {
|
||||||
match (types_a.next(), types_b.next()) {
|
match (types_a.next(), types_b.next()) {
|
||||||
(Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),
|
(Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),
|
||||||
|
|
|
@ -17,8 +17,8 @@ use crate::context::CodegenCx;
|
||||||
pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>) -> Function<'gcc> {
|
pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>) -> Function<'gcc> {
|
||||||
let tcx = cx.tcx();
|
let tcx = cx.tcx();
|
||||||
|
|
||||||
assert!(!instance.substs.has_infer());
|
assert!(!instance.args.has_infer());
|
||||||
assert!(!instance.substs.has_escaping_bound_vars());
|
assert!(!instance.args.has_escaping_bound_vars());
|
||||||
|
|
||||||
let sym = tcx.symbol_name(instance).name;
|
let sym = tcx.symbol_name(instance).name;
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>)
|
||||||
// whether we are sharing generics or not. The important thing here is
|
// whether we are sharing generics or not. The important thing here is
|
||||||
// that the visibility we apply to the declaration is the same one that
|
// that the visibility we apply to the declaration is the same one that
|
||||||
// has been applied to the definition (wherever that definition may be).
|
// has been applied to the definition (wherever that definition may be).
|
||||||
let is_generic = instance.substs.non_erasable_generics().next().is_some();
|
let is_generic = instance.args.non_erasable_generics().next().is_some();
|
||||||
|
|
||||||
if is_generic {
|
if is_generic {
|
||||||
// This is a monomorphization. Its expected visibility depends
|
// This is a monomorphization. Its expected visibility depends
|
||||||
|
|
|
@ -92,8 +92,8 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
|
let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
|
||||||
|
|
||||||
let (def_id, substs) = match *callee_ty.kind() {
|
let (def_id, fn_args) = match *callee_ty.kind() {
|
||||||
ty::FnDef(def_id, substs) => (def_id, substs),
|
ty::FnDef(def_id, fn_args) => (def_id, fn_args),
|
||||||
_ => bug!("expected fn item type, found {}", callee_ty),
|
_ => bug!("expected fn item type, found {}", callee_ty),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
sym::volatile_load | sym::unaligned_volatile_load => {
|
sym::volatile_load | sym::unaligned_volatile_load => {
|
||||||
let tp_ty = substs.type_at(0);
|
let tp_ty = fn_args.type_at(0);
|
||||||
let mut ptr = args[0].immediate();
|
let mut ptr = args[0].immediate();
|
||||||
if let PassMode::Cast(ty, _) = &fn_abi.ret.mode {
|
if let PassMode::Cast(ty, _) = &fn_abi.ret.mode {
|
||||||
ptr = self.pointercast(ptr, self.type_ptr_to(ty.gcc_type(self)));
|
ptr = self.pointercast(ptr, self.type_ptr_to(ty.gcc_type(self)));
|
||||||
|
@ -264,7 +264,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||||
|
|
||||||
sym::raw_eq => {
|
sym::raw_eq => {
|
||||||
use rustc_target::abi::Abi::*;
|
use rustc_target::abi::Abi::*;
|
||||||
let tp_ty = substs.type_at(0);
|
let tp_ty = fn_args.type_at(0);
|
||||||
let layout = self.layout_of(tp_ty).layout;
|
let layout = self.layout_of(tp_ty).layout;
|
||||||
let _use_integer_compare = match layout.abi() {
|
let _use_integer_compare = match layout.abi() {
|
||||||
Scalar(_) | ScalarPair(_, _) => true,
|
Scalar(_) | ScalarPair(_, _) => true,
|
||||||
|
|
|
@ -31,7 +31,7 @@ impl<'gcc, 'tcx> PreDefineMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
|
||||||
|
|
||||||
#[cfg_attr(not(feature="master"), allow(unused_variables))]
|
#[cfg_attr(not(feature="master"), allow(unused_variables))]
|
||||||
fn predefine_fn(&self, instance: Instance<'tcx>, linkage: Linkage, visibility: Visibility, symbol_name: &str) {
|
fn predefine_fn(&self, instance: Instance<'tcx>, linkage: Linkage, visibility: Visibility, symbol_name: &str) {
|
||||||
assert!(!instance.substs.has_infer());
|
assert!(!instance.args.has_infer());
|
||||||
|
|
||||||
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
|
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
|
||||||
self.linkage.set(base::linkage_to_gcc(linkage));
|
self.linkage.set(base::linkage_to_gcc(linkage));
|
||||||
|
|
|
@ -101,7 +101,7 @@ fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout
|
||||||
if let (&ty::Generator(_, _, _), &Variants::Single { index }) =
|
if let (&ty::Generator(_, _, _), &Variants::Single { index }) =
|
||||||
(layout.ty.kind(), &layout.variants)
|
(layout.ty.kind(), &layout.variants)
|
||||||
{
|
{
|
||||||
write!(&mut name, "::{}", ty::GeneratorSubsts::variant_name(index)).unwrap();
|
write!(&mut name, "::{}", ty::GeneratorArgs::variant_name(index)).unwrap();
|
||||||
}
|
}
|
||||||
Some(name)
|
Some(name)
|
||||||
}
|
}
|
||||||
|
@ -282,7 +282,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
|
||||||
}
|
}
|
||||||
// only wide pointer boxes are handled as pointers
|
// only wide pointer boxes are handled as pointers
|
||||||
// thin pointer boxes with scalar allocators are handled by the general logic below
|
// thin pointer boxes with scalar allocators are handled by the general logic below
|
||||||
ty::Adt(def, substs) if def.is_box() && cx.layout_of(substs.type_at(1)).is_zst() => {
|
ty::Adt(def, args) if def.is_box() && cx.layout_of(args.type_at(1)).is_zst() => {
|
||||||
let ptr_ty = Ty::new_mut_ptr(cx.tcx,self.ty.boxed_ty());
|
let ptr_ty = Ty::new_mut_ptr(cx.tcx,self.ty.boxed_ty());
|
||||||
return cx.layout_of(ptr_ty).scalar_pair_element_gcc_type(cx, index, immediate);
|
return cx.layout_of(ptr_ty).scalar_pair_element_gcc_type(cx, index, immediate);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,8 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) ->
|
||||||
|
|
||||||
debug!("get_fn(instance={:?})", instance);
|
debug!("get_fn(instance={:?})", instance);
|
||||||
|
|
||||||
assert!(!instance.substs.has_infer());
|
assert!(!instance.args.has_infer());
|
||||||
assert!(!instance.substs.has_escaping_bound_vars());
|
assert!(!instance.args.has_escaping_bound_vars());
|
||||||
|
|
||||||
if let Some(&llfn) = cx.instances.borrow().get(&instance) {
|
if let Some(&llfn) = cx.instances.borrow().get(&instance) {
|
||||||
return llfn;
|
return llfn;
|
||||||
|
@ -129,7 +129,7 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) ->
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
|
llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
|
||||||
|
|
||||||
let is_generic = instance.substs.non_erasable_generics().next().is_some();
|
let is_generic = instance.args.non_erasable_generics().next().is_some();
|
||||||
|
|
||||||
if is_generic {
|
if is_generic {
|
||||||
// This is a monomorphization. Its expected visibility depends
|
// This is a monomorphization. Its expected visibility depends
|
||||||
|
|
|
@ -22,7 +22,7 @@ use rustc_middle::mir::coverage::{
|
||||||
use rustc_middle::mir::Coverage;
|
use rustc_middle::mir::Coverage;
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
|
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
|
||||||
use rustc_middle::ty::subst::InternalSubsts;
|
use rustc_middle::ty::GenericArgs;
|
||||||
use rustc_middle::ty::Instance;
|
use rustc_middle::ty::Instance;
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::Ty;
|
||||||
|
|
||||||
|
@ -250,7 +250,7 @@ fn declare_unused_fn<'tcx>(cx: &CodegenCx<'_, 'tcx>, def_id: DefId) -> Instance<
|
||||||
|
|
||||||
let instance = Instance::new(
|
let instance = Instance::new(
|
||||||
def_id,
|
def_id,
|
||||||
InternalSubsts::for_item(tcx, def_id, |param, _| {
|
GenericArgs::for_item(tcx, def_id, |param, _| {
|
||||||
if let ty::GenericParamDefKind::Lifetime = param.kind {
|
if let ty::GenericParamDefKind::Lifetime = param.kind {
|
||||||
tcx.lifetimes.re_erased.into()
|
tcx.lifetimes.re_erased.into()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -91,7 +91,7 @@ fn make_mir_scope<'ll, 'tcx>(
|
||||||
// FIXME(eddyb) this would be `self.monomorphize(&callee)`
|
// FIXME(eddyb) this would be `self.monomorphize(&callee)`
|
||||||
// if this is moved to `rustc_codegen_ssa::mir::debuginfo`.
|
// if this is moved to `rustc_codegen_ssa::mir::debuginfo`.
|
||||||
let callee = cx.tcx.subst_and_normalize_erasing_regions(
|
let callee = cx.tcx.subst_and_normalize_erasing_regions(
|
||||||
instance.substs,
|
instance.args,
|
||||||
ty::ParamEnv::reveal_all(),
|
ty::ParamEnv::reveal_all(),
|
||||||
ty::EarlyBinder::bind(callee),
|
ty::EarlyBinder::bind(callee),
|
||||||
);
|
);
|
||||||
|
|
|
@ -449,7 +449,7 @@ pub fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll D
|
||||||
}
|
}
|
||||||
// Box<T, A> may have a non-ZST allocator A. In that case, we
|
// Box<T, A> may have a non-ZST allocator A. In that case, we
|
||||||
// cannot treat Box<T, A> as just an owned alias of `*mut T`.
|
// cannot treat Box<T, A> as just an owned alias of `*mut T`.
|
||||||
ty::Adt(def, substs) if def.is_box() && cx.layout_of(substs.type_at(1)).is_zst() => {
|
ty::Adt(def, args) if def.is_box() && cx.layout_of(args.type_at(1)).is_zst() => {
|
||||||
build_pointer_or_reference_di_node(cx, t, t.boxed_ty(), unique_type_id)
|
build_pointer_or_reference_di_node(cx, t, t.boxed_ty(), unique_type_id)
|
||||||
}
|
}
|
||||||
ty::FnDef(..) | ty::FnPtr(_) => build_subroutine_type_di_node(cx, unique_type_id),
|
ty::FnDef(..) | ty::FnPtr(_) => build_subroutine_type_di_node(cx, unique_type_id),
|
||||||
|
@ -1007,12 +1007,12 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>(
|
||||||
closure_or_generator_di_node: &'ll DIType,
|
closure_or_generator_di_node: &'ll DIType,
|
||||||
) -> SmallVec<&'ll DIType> {
|
) -> SmallVec<&'ll DIType> {
|
||||||
let (&def_id, up_var_tys) = match closure_or_generator_ty.kind() {
|
let (&def_id, up_var_tys) = match closure_or_generator_ty.kind() {
|
||||||
ty::Generator(def_id, substs, _) => {
|
ty::Generator(def_id, args, _) => {
|
||||||
let upvar_tys: SmallVec<_> = substs.as_generator().prefix_tys().collect();
|
let upvar_tys: SmallVec<_> = args.as_generator().prefix_tys().collect();
|
||||||
(def_id, upvar_tys)
|
(def_id, upvar_tys)
|
||||||
}
|
}
|
||||||
ty::Closure(def_id, substs) => {
|
ty::Closure(def_id, args) => {
|
||||||
let upvar_tys: SmallVec<_> = substs.as_closure().upvar_tys().collect();
|
let upvar_tys: SmallVec<_> = args.as_closure().upvar_tys().collect();
|
||||||
(def_id, upvar_tys)
|
(def_id, upvar_tys)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -1102,7 +1102,7 @@ fn build_closure_env_di_node<'ll, 'tcx>(
|
||||||
unique_type_id: UniqueTypeId<'tcx>,
|
unique_type_id: UniqueTypeId<'tcx>,
|
||||||
) -> DINodeCreationResult<'ll> {
|
) -> DINodeCreationResult<'ll> {
|
||||||
let closure_env_type = unique_type_id.expect_ty();
|
let closure_env_type = unique_type_id.expect_ty();
|
||||||
let &ty::Closure(def_id, _substs) = closure_env_type.kind() else {
|
let &ty::Closure(def_id, _args) = closure_env_type.kind() else {
|
||||||
bug!("build_closure_env_di_node() called with non-closure-type: {:?}", closure_env_type)
|
bug!("build_closure_env_di_node() called with non-closure-type: {:?}", closure_env_type)
|
||||||
};
|
};
|
||||||
let containing_scope = get_namespace_for_item(cx, def_id);
|
let containing_scope = get_namespace_for_item(cx, def_id);
|
||||||
|
@ -1180,11 +1180,11 @@ fn build_generic_type_param_di_nodes<'ll, 'tcx>(
|
||||||
cx: &CodegenCx<'ll, 'tcx>,
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
) -> SmallVec<&'ll DIType> {
|
) -> SmallVec<&'ll DIType> {
|
||||||
if let ty::Adt(def, substs) = *ty.kind() {
|
if let ty::Adt(def, args) = *ty.kind() {
|
||||||
if substs.types().next().is_some() {
|
if args.types().next().is_some() {
|
||||||
let generics = cx.tcx.generics_of(def.did());
|
let generics = cx.tcx.generics_of(def.did());
|
||||||
let names = get_parameter_names(cx, generics);
|
let names = get_parameter_names(cx, generics);
|
||||||
let template_params: SmallVec<_> = iter::zip(substs, names)
|
let template_params: SmallVec<_> = iter::zip(args, names)
|
||||||
.filter_map(|(kind, name)| {
|
.filter_map(|(kind, name)| {
|
||||||
kind.as_type().map(|ty| {
|
kind.as_type().map(|ty| {
|
||||||
let actual_type =
|
let actual_type =
|
||||||
|
|
|
@ -12,7 +12,7 @@ use rustc_middle::{
|
||||||
ty::{
|
ty::{
|
||||||
self,
|
self,
|
||||||
layout::{LayoutOf, TyAndLayout},
|
layout::{LayoutOf, TyAndLayout},
|
||||||
AdtDef, GeneratorSubsts, Ty,
|
AdtDef, GeneratorArgs, Ty,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use rustc_target::abi::{Align, Endian, Size, TagEncoding, VariantIdx, Variants};
|
use rustc_target::abi::{Align, Endian, Size, TagEncoding, VariantIdx, Variants};
|
||||||
|
@ -673,15 +673,15 @@ fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>(
|
||||||
bug!("This function only supports layouts with directly encoded tags.")
|
bug!("This function only supports layouts with directly encoded tags.")
|
||||||
};
|
};
|
||||||
|
|
||||||
let (generator_def_id, generator_substs) = match generator_type_and_layout.ty.kind() {
|
let (generator_def_id, generator_args) = match generator_type_and_layout.ty.kind() {
|
||||||
&ty::Generator(def_id, substs, _) => (def_id, substs.as_generator()),
|
&ty::Generator(def_id, args, _) => (def_id, args.as_generator()),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let generator_layout = cx.tcx.optimized_mir(generator_def_id).generator_layout().unwrap();
|
let generator_layout = cx.tcx.optimized_mir(generator_def_id).generator_layout().unwrap();
|
||||||
|
|
||||||
let common_upvar_names = cx.tcx.closure_saved_names_of_captured_variables(generator_def_id);
|
let common_upvar_names = cx.tcx.closure_saved_names_of_captured_variables(generator_def_id);
|
||||||
let variant_range = generator_substs.variant_range(generator_def_id, cx.tcx);
|
let variant_range = generator_args.variant_range(generator_def_id, cx.tcx);
|
||||||
let variant_count = (variant_range.start.as_u32()..variant_range.end.as_u32()).len();
|
let variant_count = (variant_range.start.as_u32()..variant_range.end.as_u32()).len();
|
||||||
|
|
||||||
let tag_base_type = tag_base_type(cx, generator_type_and_layout);
|
let tag_base_type = tag_base_type(cx, generator_type_and_layout);
|
||||||
|
@ -691,11 +691,11 @@ fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>(
|
||||||
generator_type_di_node,
|
generator_type_di_node,
|
||||||
variant_range
|
variant_range
|
||||||
.clone()
|
.clone()
|
||||||
.map(|variant_index| (variant_index, GeneratorSubsts::variant_name(variant_index))),
|
.map(|variant_index| (variant_index, GeneratorArgs::variant_name(variant_index))),
|
||||||
);
|
);
|
||||||
|
|
||||||
let discriminants: IndexVec<VariantIdx, DiscrResult> = {
|
let discriminants: IndexVec<VariantIdx, DiscrResult> = {
|
||||||
let discriminants_iter = generator_substs.discriminants(generator_def_id, cx.tcx);
|
let discriminants_iter = generator_args.discriminants(generator_def_id, cx.tcx);
|
||||||
let mut discriminants: IndexVec<VariantIdx, DiscrResult> =
|
let mut discriminants: IndexVec<VariantIdx, DiscrResult> =
|
||||||
IndexVec::with_capacity(variant_count);
|
IndexVec::with_capacity(variant_count);
|
||||||
for (variant_index, discr) in discriminants_iter {
|
for (variant_index, discr) in discriminants_iter {
|
||||||
|
|
|
@ -10,7 +10,7 @@ use rustc_middle::{
|
||||||
ty::{
|
ty::{
|
||||||
self,
|
self,
|
||||||
layout::{IntegerExt, LayoutOf, PrimitiveExt, TyAndLayout},
|
layout::{IntegerExt, LayoutOf, PrimitiveExt, TyAndLayout},
|
||||||
AdtDef, GeneratorSubsts, Ty, VariantDef,
|
AdtDef, GeneratorArgs, Ty, VariantDef,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use rustc_span::Symbol;
|
use rustc_span::Symbol;
|
||||||
|
@ -325,7 +325,7 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>(
|
||||||
generator_layout: &GeneratorLayout<'tcx>,
|
generator_layout: &GeneratorLayout<'tcx>,
|
||||||
common_upvar_names: &IndexSlice<FieldIdx, Symbol>,
|
common_upvar_names: &IndexSlice<FieldIdx, Symbol>,
|
||||||
) -> &'ll DIType {
|
) -> &'ll DIType {
|
||||||
let variant_name = GeneratorSubsts::variant_name(variant_index);
|
let variant_name = GeneratorArgs::variant_name(variant_index);
|
||||||
let unique_type_id = UniqueTypeId::for_enum_variant_struct_type(
|
let unique_type_id = UniqueTypeId::for_enum_variant_struct_type(
|
||||||
cx.tcx,
|
cx.tcx,
|
||||||
generator_type_and_layout.ty,
|
generator_type_and_layout.ty,
|
||||||
|
@ -334,8 +334,8 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>(
|
||||||
|
|
||||||
let variant_layout = generator_type_and_layout.for_variant(cx, variant_index);
|
let variant_layout = generator_type_and_layout.for_variant(cx, variant_index);
|
||||||
|
|
||||||
let generator_substs = match generator_type_and_layout.ty.kind() {
|
let generator_args = match generator_type_and_layout.ty.kind() {
|
||||||
ty::Generator(_, substs, _) => substs.as_generator(),
|
ty::Generator(_, args, _) => args.as_generator(),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -377,7 +377,7 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>(
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// Fields that are common to all states
|
// Fields that are common to all states
|
||||||
let common_fields: SmallVec<_> = generator_substs
|
let common_fields: SmallVec<_> = generator_args
|
||||||
.prefix_tys()
|
.prefix_tys()
|
||||||
.zip(common_upvar_names)
|
.zip(common_upvar_names)
|
||||||
.enumerate()
|
.enumerate()
|
||||||
|
|
|
@ -175,7 +175,7 @@ pub(super) fn build_generator_di_node<'ll, 'tcx>(
|
||||||
.indices()
|
.indices()
|
||||||
.map(|variant_index| {
|
.map(|variant_index| {
|
||||||
// FIXME: This is problematic because just a number is not a valid identifier.
|
// FIXME: This is problematic because just a number is not a valid identifier.
|
||||||
// GeneratorSubsts::variant_name(variant_index), would be consistent
|
// GeneratorArgs::variant_name(variant_index), would be consistent
|
||||||
// with enums?
|
// with enums?
|
||||||
let variant_name = format!("{}", variant_index.as_usize()).into();
|
let variant_name = format!("{}", variant_index.as_usize()).into();
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ use rustc_hir::def_id::{DefId, DefIdMap};
|
||||||
use rustc_index::IndexVec;
|
use rustc_index::IndexVec;
|
||||||
use rustc_middle::mir;
|
use rustc_middle::mir;
|
||||||
use rustc_middle::ty::layout::LayoutOf;
|
use rustc_middle::ty::layout::LayoutOf;
|
||||||
use rustc_middle::ty::subst::SubstsRef;
|
use rustc_middle::ty::GenericArgsRef;
|
||||||
use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TypeVisitableExt};
|
use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TypeVisitableExt};
|
||||||
use rustc_session::config::{self, DebugInfo};
|
use rustc_session::config::{self, DebugInfo};
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
|
@ -338,19 +338,19 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||||
// Find the enclosing function, in case this is a closure.
|
// Find the enclosing function, in case this is a closure.
|
||||||
let enclosing_fn_def_id = tcx.typeck_root_def_id(def_id);
|
let enclosing_fn_def_id = tcx.typeck_root_def_id(def_id);
|
||||||
|
|
||||||
// We look up the generics of the enclosing function and truncate the substs
|
// We look up the generics of the enclosing function and truncate the args
|
||||||
// to their length in order to cut off extra stuff that might be in there for
|
// to their length in order to cut off extra stuff that might be in there for
|
||||||
// closures or generators.
|
// closures or generators.
|
||||||
let generics = tcx.generics_of(enclosing_fn_def_id);
|
let generics = tcx.generics_of(enclosing_fn_def_id);
|
||||||
let substs = instance.substs.truncate_to(tcx, generics);
|
let args = instance.args.truncate_to(tcx, generics);
|
||||||
|
|
||||||
type_names::push_generic_params(
|
type_names::push_generic_params(
|
||||||
tcx,
|
tcx,
|
||||||
tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substs),
|
tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args),
|
||||||
&mut name,
|
&mut name,
|
||||||
);
|
);
|
||||||
|
|
||||||
let template_parameters = get_template_parameters(self, generics, substs);
|
let template_parameters = get_template_parameters(self, generics, args);
|
||||||
|
|
||||||
let linkage_name = &mangled_name_of_instance(self, instance).name;
|
let linkage_name = &mangled_name_of_instance(self, instance).name;
|
||||||
// Omit the linkage_name if it is the same as subprogram name.
|
// Omit the linkage_name if it is the same as subprogram name.
|
||||||
|
@ -471,16 +471,16 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||||
fn get_template_parameters<'ll, 'tcx>(
|
fn get_template_parameters<'ll, 'tcx>(
|
||||||
cx: &CodegenCx<'ll, 'tcx>,
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
generics: &ty::Generics,
|
generics: &ty::Generics,
|
||||||
substs: SubstsRef<'tcx>,
|
args: GenericArgsRef<'tcx>,
|
||||||
) -> &'ll DIArray {
|
) -> &'ll DIArray {
|
||||||
if substs.types().next().is_none() {
|
if args.types().next().is_none() {
|
||||||
return create_DIArray(DIB(cx), &[]);
|
return create_DIArray(DIB(cx), &[]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Again, only create type information if full debuginfo is enabled
|
// Again, only create type information if full debuginfo is enabled
|
||||||
let template_params: Vec<_> = if cx.sess().opts.debuginfo == DebugInfo::Full {
|
let template_params: Vec<_> = if cx.sess().opts.debuginfo == DebugInfo::Full {
|
||||||
let names = get_parameter_names(cx, generics);
|
let names = get_parameter_names(cx, generics);
|
||||||
iter::zip(substs, names)
|
iter::zip(args, names)
|
||||||
.filter_map(|(kind, name)| {
|
.filter_map(|(kind, name)| {
|
||||||
kind.as_type().map(|ty| {
|
kind.as_type().map(|ty| {
|
||||||
let actual_type =
|
let actual_type =
|
||||||
|
@ -527,7 +527,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||||
// If the method does *not* belong to a trait, proceed
|
// If the method does *not* belong to a trait, proceed
|
||||||
if cx.tcx.trait_id_of_impl(impl_def_id).is_none() {
|
if cx.tcx.trait_id_of_impl(impl_def_id).is_none() {
|
||||||
let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions(
|
let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions(
|
||||||
instance.substs,
|
instance.args,
|
||||||
ty::ParamEnv::reveal_all(),
|
ty::ParamEnv::reveal_all(),
|
||||||
cx.tcx.type_of(impl_def_id),
|
cx.tcx.type_of(impl_def_id),
|
||||||
);
|
);
|
||||||
|
|
|
@ -90,7 +90,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
|
let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
|
||||||
|
|
||||||
let ty::FnDef(def_id, substs) = *callee_ty.kind() else {
|
let ty::FnDef(def_id, fn_args) = *callee_ty.kind() else {
|
||||||
bug!("expected fn item type, found {}", callee_ty);
|
bug!("expected fn item type, found {}", callee_ty);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
sym::volatile_load | sym::unaligned_volatile_load => {
|
sym::volatile_load | sym::unaligned_volatile_load => {
|
||||||
let tp_ty = substs.type_at(0);
|
let tp_ty = fn_args.type_at(0);
|
||||||
let ptr = args[0].immediate();
|
let ptr = args[0].immediate();
|
||||||
let load = if let PassMode::Cast(ty, _) = &fn_abi.ret.mode {
|
let load = if let PassMode::Cast(ty, _) = &fn_abi.ret.mode {
|
||||||
let llty = ty.llvm_type(self);
|
let llty = ty.llvm_type(self);
|
||||||
|
@ -298,7 +298,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
||||||
|
|
||||||
sym::raw_eq => {
|
sym::raw_eq => {
|
||||||
use abi::Abi::*;
|
use abi::Abi::*;
|
||||||
let tp_ty = substs.type_at(0);
|
let tp_ty = fn_args.type_at(0);
|
||||||
let layout = self.layout_of(tp_ty).layout;
|
let layout = self.layout_of(tp_ty).layout;
|
||||||
let use_integer_compare = match layout.abi() {
|
let use_integer_compare = match layout.abi() {
|
||||||
Scalar(_) | ScalarPair(_, _) => true,
|
Scalar(_) | ScalarPair(_, _) => true,
|
||||||
|
|
|
@ -48,7 +48,7 @@ impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'_, 'tcx> {
|
||||||
visibility: Visibility,
|
visibility: Visibility,
|
||||||
symbol_name: &str,
|
symbol_name: &str,
|
||||||
) {
|
) {
|
||||||
assert!(!instance.substs.has_infer());
|
assert!(!instance.args.has_infer());
|
||||||
|
|
||||||
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
|
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
|
||||||
let lldecl = self.declare_fn(symbol_name, fn_abi, Some(instance));
|
let lldecl = self.declare_fn(symbol_name, fn_abi, Some(instance));
|
||||||
|
|
|
@ -57,7 +57,7 @@ fn uncached_llvm_type<'a, 'tcx>(
|
||||||
if let (&ty::Generator(_, _, _), &Variants::Single { index }) =
|
if let (&ty::Generator(_, _, _), &Variants::Single { index }) =
|
||||||
(layout.ty.kind(), &layout.variants)
|
(layout.ty.kind(), &layout.variants)
|
||||||
{
|
{
|
||||||
write!(&mut name, "::{}", ty::GeneratorSubsts::variant_name(index)).unwrap();
|
write!(&mut name, "::{}", ty::GeneratorArgs::variant_name(index)).unwrap();
|
||||||
}
|
}
|
||||||
Some(name)
|
Some(name)
|
||||||
}
|
}
|
||||||
|
@ -336,7 +336,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
|
||||||
}
|
}
|
||||||
// only wide pointer boxes are handled as pointers
|
// only wide pointer boxes are handled as pointers
|
||||||
// thin pointer boxes with scalar allocators are handled by the general logic below
|
// thin pointer boxes with scalar allocators are handled by the general logic below
|
||||||
ty::Adt(def, substs) if def.is_box() && cx.layout_of(substs.type_at(1)).is_zst() => {
|
ty::Adt(def, args) if def.is_box() && cx.layout_of(args.type_at(1)).is_zst() => {
|
||||||
let ptr_ty = Ty::new_mut_ptr(cx.tcx, self.ty.boxed_ty());
|
let ptr_ty = Ty::new_mut_ptr(cx.tcx, self.ty.boxed_ty());
|
||||||
return cx.layout_of(ptr_ty).scalar_pair_element_llvm_type(cx, index, immediate);
|
return cx.layout_of(ptr_ty).scalar_pair_element_llvm_type(cx, index, immediate);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,9 @@ use rustc_middle::middle::exported_symbols::{
|
||||||
};
|
};
|
||||||
use rustc_middle::query::LocalCrate;
|
use rustc_middle::query::LocalCrate;
|
||||||
use rustc_middle::query::{ExternProviders, Providers};
|
use rustc_middle::query::{ExternProviders, Providers};
|
||||||
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
|
|
||||||
use rustc_middle::ty::Instance;
|
use rustc_middle::ty::Instance;
|
||||||
use rustc_middle::ty::{self, SymbolName, TyCtxt};
|
use rustc_middle::ty::{self, SymbolName, TyCtxt};
|
||||||
|
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
|
||||||
use rustc_session::config::{CrateType, OomStrategy};
|
use rustc_session::config::{CrateType, OomStrategy};
|
||||||
use rustc_target::spec::SanitizerSet;
|
use rustc_target::spec::SanitizerSet;
|
||||||
|
|
||||||
|
@ -342,9 +342,9 @@ fn exported_symbols_provider_local(
|
||||||
}
|
}
|
||||||
|
|
||||||
match *mono_item {
|
match *mono_item {
|
||||||
MonoItem::Fn(Instance { def: InstanceDef::Item(def), substs }) => {
|
MonoItem::Fn(Instance { def: InstanceDef::Item(def), args }) => {
|
||||||
if substs.non_erasable_generics().next().is_some() {
|
if args.non_erasable_generics().next().is_some() {
|
||||||
let symbol = ExportedSymbol::Generic(def, substs);
|
let symbol = ExportedSymbol::Generic(def, args);
|
||||||
symbols.push((
|
symbols.push((
|
||||||
symbol,
|
symbol,
|
||||||
SymbolExportInfo {
|
SymbolExportInfo {
|
||||||
|
@ -355,10 +355,10 @@ fn exported_symbols_provider_local(
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MonoItem::Fn(Instance { def: InstanceDef::DropGlue(_, Some(ty)), substs }) => {
|
MonoItem::Fn(Instance { def: InstanceDef::DropGlue(_, Some(ty)), args }) => {
|
||||||
// A little sanity-check
|
// A little sanity-check
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
substs.non_erasable_generics().next(),
|
args.non_erasable_generics().next(),
|
||||||
Some(GenericArgKind::Type(ty))
|
Some(GenericArgKind::Type(ty))
|
||||||
);
|
);
|
||||||
symbols.push((
|
symbols.push((
|
||||||
|
@ -386,7 +386,7 @@ fn exported_symbols_provider_local(
|
||||||
fn upstream_monomorphizations_provider(
|
fn upstream_monomorphizations_provider(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
(): (),
|
(): (),
|
||||||
) -> DefIdMap<FxHashMap<SubstsRef<'_>, CrateNum>> {
|
) -> DefIdMap<FxHashMap<GenericArgsRef<'_>, CrateNum>> {
|
||||||
let cnums = tcx.crates(());
|
let cnums = tcx.crates(());
|
||||||
|
|
||||||
let mut instances: DefIdMap<FxHashMap<_, _>> = Default::default();
|
let mut instances: DefIdMap<FxHashMap<_, _>> = Default::default();
|
||||||
|
@ -395,11 +395,11 @@ fn upstream_monomorphizations_provider(
|
||||||
|
|
||||||
for &cnum in cnums.iter() {
|
for &cnum in cnums.iter() {
|
||||||
for (exported_symbol, _) in tcx.exported_symbols(cnum).iter() {
|
for (exported_symbol, _) in tcx.exported_symbols(cnum).iter() {
|
||||||
let (def_id, substs) = match *exported_symbol {
|
let (def_id, args) = match *exported_symbol {
|
||||||
ExportedSymbol::Generic(def_id, substs) => (def_id, substs),
|
ExportedSymbol::Generic(def_id, args) => (def_id, args),
|
||||||
ExportedSymbol::DropGlue(ty) => {
|
ExportedSymbol::DropGlue(ty) => {
|
||||||
if let Some(drop_in_place_fn_def_id) = drop_in_place_fn_def_id {
|
if let Some(drop_in_place_fn_def_id) = drop_in_place_fn_def_id {
|
||||||
(drop_in_place_fn_def_id, tcx.mk_substs(&[ty.into()]))
|
(drop_in_place_fn_def_id, tcx.mk_args(&[ty.into()]))
|
||||||
} else {
|
} else {
|
||||||
// `drop_in_place` in place does not exist, don't try
|
// `drop_in_place` in place does not exist, don't try
|
||||||
// to use it.
|
// to use it.
|
||||||
|
@ -414,9 +414,9 @@ fn upstream_monomorphizations_provider(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let substs_map = instances.entry(def_id).or_default();
|
let args_map = instances.entry(def_id).or_default();
|
||||||
|
|
||||||
match substs_map.entry(substs) {
|
match args_map.entry(args) {
|
||||||
Occupied(mut e) => {
|
Occupied(mut e) => {
|
||||||
// If there are multiple monomorphizations available,
|
// If there are multiple monomorphizations available,
|
||||||
// we select one deterministically.
|
// we select one deterministically.
|
||||||
|
@ -438,17 +438,17 @@ fn upstream_monomorphizations_provider(
|
||||||
fn upstream_monomorphizations_for_provider(
|
fn upstream_monomorphizations_for_provider(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
) -> Option<&FxHashMap<SubstsRef<'_>, CrateNum>> {
|
) -> Option<&FxHashMap<GenericArgsRef<'_>, CrateNum>> {
|
||||||
debug_assert!(!def_id.is_local());
|
debug_assert!(!def_id.is_local());
|
||||||
tcx.upstream_monomorphizations(()).get(&def_id)
|
tcx.upstream_monomorphizations(()).get(&def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn upstream_drop_glue_for_provider<'tcx>(
|
fn upstream_drop_glue_for_provider<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
substs: SubstsRef<'tcx>,
|
args: GenericArgsRef<'tcx>,
|
||||||
) -> Option<CrateNum> {
|
) -> Option<CrateNum> {
|
||||||
if let Some(def_id) = tcx.lang_items().drop_in_place_fn() {
|
if let Some(def_id) = tcx.lang_items().drop_in_place_fn() {
|
||||||
tcx.upstream_monomorphizations_for(def_id).and_then(|monos| monos.get(&substs).cloned())
|
tcx.upstream_monomorphizations_for(def_id).and_then(|monos| monos.get(&args).cloned())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -521,10 +521,10 @@ pub fn symbol_name_for_instance_in_crate<'tcx>(
|
||||||
instantiating_crate,
|
instantiating_crate,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ExportedSymbol::Generic(def_id, substs) => {
|
ExportedSymbol::Generic(def_id, args) => {
|
||||||
rustc_symbol_mangling::symbol_name_for_instance_in_crate(
|
rustc_symbol_mangling::symbol_name_for_instance_in_crate(
|
||||||
tcx,
|
tcx,
|
||||||
Instance::new(def_id, substs),
|
Instance::new(def_id, args),
|
||||||
instantiating_crate,
|
instantiating_crate,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -533,7 +533,7 @@ pub fn symbol_name_for_instance_in_crate<'tcx>(
|
||||||
tcx,
|
tcx,
|
||||||
ty::Instance {
|
ty::Instance {
|
||||||
def: ty::InstanceDef::ThreadLocalShim(def_id),
|
def: ty::InstanceDef::ThreadLocalShim(def_id),
|
||||||
substs: ty::InternalSubsts::empty(),
|
args: ty::GenericArgs::empty(),
|
||||||
},
|
},
|
||||||
instantiating_crate,
|
instantiating_crate,
|
||||||
)
|
)
|
||||||
|
@ -580,7 +580,7 @@ pub fn linking_symbol_name_for_instance_in_crate<'tcx>(
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
ExportedSymbol::NonGeneric(def_id) => Some(Instance::mono(tcx, def_id)),
|
ExportedSymbol::NonGeneric(def_id) => Some(Instance::mono(tcx, def_id)),
|
||||||
ExportedSymbol::Generic(def_id, substs) => Some(Instance::new(def_id, substs)),
|
ExportedSymbol::Generic(def_id, args) => Some(Instance::new(def_id, args)),
|
||||||
// DropGlue always use the Rust calling convention and thus follow the target's default
|
// DropGlue always use the Rust calling convention and thus follow the target's default
|
||||||
// symbol decoration scheme.
|
// symbol decoration scheme.
|
||||||
ExportedSymbol::DropGlue(..) => None,
|
ExportedSymbol::DropGlue(..) => None,
|
||||||
|
|
|
@ -499,7 +499,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||||
cx.tcx(),
|
cx.tcx(),
|
||||||
ty::ParamEnv::reveal_all(),
|
ty::ParamEnv::reveal_all(),
|
||||||
start_def_id,
|
start_def_id,
|
||||||
cx.tcx().mk_substs(&[main_ret_ty.into()]),
|
cx.tcx().mk_args(&[main_ret_ty.into()]),
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
|
|
|
@ -17,8 +17,8 @@ use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData};
|
use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData};
|
||||||
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Mutability};
|
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Mutability};
|
||||||
use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
|
use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
|
||||||
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
|
|
||||||
use rustc_middle::ty::{self, ExistentialProjection, ParamEnv, Ty, TyCtxt};
|
use rustc_middle::ty::{self, ExistentialProjection, ParamEnv, Ty, TyCtxt};
|
||||||
|
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
|
||||||
use rustc_target::abi::Integer;
|
use rustc_target::abi::Integer;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ fn push_debuginfo_type_name<'tcx>(
|
||||||
ty::Uint(uint_ty) => output.push_str(uint_ty.name_str()),
|
ty::Uint(uint_ty) => output.push_str(uint_ty.name_str()),
|
||||||
ty::Float(float_ty) => output.push_str(float_ty.name_str()),
|
ty::Float(float_ty) => output.push_str(float_ty.name_str()),
|
||||||
ty::Foreign(def_id) => push_item_name(tcx, def_id, qualified, output),
|
ty::Foreign(def_id) => push_item_name(tcx, def_id, qualified, output),
|
||||||
ty::Adt(def, substs) => {
|
ty::Adt(def, args) => {
|
||||||
// `layout_for_cpp_like_fallback` will be `Some` if we want to use the fallback encoding.
|
// `layout_for_cpp_like_fallback` will be `Some` if we want to use the fallback encoding.
|
||||||
let layout_for_cpp_like_fallback = if cpp_like_debuginfo && def.is_enum() {
|
let layout_for_cpp_like_fallback = if cpp_like_debuginfo && def.is_enum() {
|
||||||
match tcx.layout_of(ParamEnv::reveal_all().and(t)) {
|
match tcx.layout_of(ParamEnv::reveal_all().and(t)) {
|
||||||
|
@ -106,14 +106,14 @@ fn push_debuginfo_type_name<'tcx>(
|
||||||
ty_and_layout,
|
ty_and_layout,
|
||||||
&|output, visited| {
|
&|output, visited| {
|
||||||
push_item_name(tcx, def.did(), true, output);
|
push_item_name(tcx, def.did(), true, output);
|
||||||
push_generic_params_internal(tcx, substs, output, visited);
|
push_generic_params_internal(tcx, args, output, visited);
|
||||||
},
|
},
|
||||||
output,
|
output,
|
||||||
visited,
|
visited,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
push_item_name(tcx, def.did(), qualified, output);
|
push_item_name(tcx, def.did(), qualified, output);
|
||||||
push_generic_params_internal(tcx, substs, output, visited);
|
push_generic_params_internal(tcx, args, output, visited);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::Tuple(component_types) => {
|
ty::Tuple(component_types) => {
|
||||||
|
@ -238,7 +238,7 @@ fn push_debuginfo_type_name<'tcx>(
|
||||||
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), principal);
|
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), principal);
|
||||||
push_item_name(tcx, principal.def_id, qualified, output);
|
push_item_name(tcx, principal.def_id, qualified, output);
|
||||||
let principal_has_generic_params =
|
let principal_has_generic_params =
|
||||||
push_generic_params_internal(tcx, principal.substs, output, visited);
|
push_generic_params_internal(tcx, principal.args, output, visited);
|
||||||
|
|
||||||
let projection_bounds: SmallVec<[_; 4]> = trait_data
|
let projection_bounds: SmallVec<[_; 4]> = trait_data
|
||||||
.projection_bounds()
|
.projection_bounds()
|
||||||
|
@ -393,7 +393,7 @@ fn push_debuginfo_type_name<'tcx>(
|
||||||
// processing
|
// processing
|
||||||
visited.remove(&t);
|
visited.remove(&t);
|
||||||
}
|
}
|
||||||
ty::Closure(def_id, substs) | ty::Generator(def_id, substs, ..) => {
|
ty::Closure(def_id, args) | ty::Generator(def_id, args, ..) => {
|
||||||
// Name will be "{closure_env#0}<T1, T2, ...>", "{generator_env#0}<T1, T2, ...>", or
|
// Name will be "{closure_env#0}<T1, T2, ...>", "{generator_env#0}<T1, T2, ...>", or
|
||||||
// "{async_fn_env#0}<T1, T2, ...>", etc.
|
// "{async_fn_env#0}<T1, T2, ...>", etc.
|
||||||
// In the case of cpp-like debuginfo, the name additionally gets wrapped inside of
|
// In the case of cpp-like debuginfo, the name additionally gets wrapped inside of
|
||||||
|
@ -403,13 +403,13 @@ fn push_debuginfo_type_name<'tcx>(
|
||||||
msvc_enum_fallback(
|
msvc_enum_fallback(
|
||||||
ty_and_layout,
|
ty_and_layout,
|
||||||
&|output, visited| {
|
&|output, visited| {
|
||||||
push_closure_or_generator_name(tcx, def_id, substs, true, output, visited);
|
push_closure_or_generator_name(tcx, def_id, args, true, output, visited);
|
||||||
},
|
},
|
||||||
output,
|
output,
|
||||||
visited,
|
visited,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
push_closure_or_generator_name(tcx, def_id, substs, qualified, output, visited);
|
push_closure_or_generator_name(tcx, def_id, args, qualified, output, visited);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Type parameters from polymorphized functions.
|
// Type parameters from polymorphized functions.
|
||||||
|
@ -516,7 +516,7 @@ pub fn compute_debuginfo_vtable_name<'tcx>(
|
||||||
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), trait_ref);
|
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), trait_ref);
|
||||||
push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name);
|
push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name);
|
||||||
visited.clear();
|
visited.clear();
|
||||||
push_generic_params_internal(tcx, trait_ref.substs, &mut vtable_name, &mut visited);
|
push_generic_params_internal(tcx, trait_ref.args, &mut vtable_name, &mut visited);
|
||||||
} else {
|
} else {
|
||||||
vtable_name.push('_');
|
vtable_name.push('_');
|
||||||
}
|
}
|
||||||
|
@ -609,21 +609,21 @@ fn push_unqualified_item_name(
|
||||||
|
|
||||||
fn push_generic_params_internal<'tcx>(
|
fn push_generic_params_internal<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
substs: SubstsRef<'tcx>,
|
args: GenericArgsRef<'tcx>,
|
||||||
output: &mut String,
|
output: &mut String,
|
||||||
visited: &mut FxHashSet<Ty<'tcx>>,
|
visited: &mut FxHashSet<Ty<'tcx>>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if substs.non_erasable_generics().next().is_none() {
|
if args.non_erasable_generics().next().is_none() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_assert_eq!(substs, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substs));
|
debug_assert_eq!(args, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args));
|
||||||
|
|
||||||
let cpp_like_debuginfo = cpp_like_debuginfo(tcx);
|
let cpp_like_debuginfo = cpp_like_debuginfo(tcx);
|
||||||
|
|
||||||
output.push('<');
|
output.push('<');
|
||||||
|
|
||||||
for type_parameter in substs.non_erasable_generics() {
|
for type_parameter in args.non_erasable_generics() {
|
||||||
match type_parameter {
|
match type_parameter {
|
||||||
GenericArgKind::Type(type_parameter) => {
|
GenericArgKind::Type(type_parameter) => {
|
||||||
push_debuginfo_type_name(tcx, type_parameter, true, output, visited);
|
push_debuginfo_type_name(tcx, type_parameter, true, output, visited);
|
||||||
|
@ -688,16 +688,20 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_generic_params<'tcx>(tcx: TyCtxt<'tcx>, substs: SubstsRef<'tcx>, output: &mut String) {
|
pub fn push_generic_params<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
args: GenericArgsRef<'tcx>,
|
||||||
|
output: &mut String,
|
||||||
|
) {
|
||||||
let _prof = tcx.prof.generic_activity("compute_debuginfo_type_name");
|
let _prof = tcx.prof.generic_activity("compute_debuginfo_type_name");
|
||||||
let mut visited = FxHashSet::default();
|
let mut visited = FxHashSet::default();
|
||||||
push_generic_params_internal(tcx, substs, output, &mut visited);
|
push_generic_params_internal(tcx, args, output, &mut visited);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_closure_or_generator_name<'tcx>(
|
fn push_closure_or_generator_name<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
substs: SubstsRef<'tcx>,
|
args: GenericArgsRef<'tcx>,
|
||||||
qualified: bool,
|
qualified: bool,
|
||||||
output: &mut String,
|
output: &mut String,
|
||||||
visited: &mut FxHashSet<Ty<'tcx>>,
|
visited: &mut FxHashSet<Ty<'tcx>>,
|
||||||
|
@ -731,10 +735,10 @@ fn push_closure_or_generator_name<'tcx>(
|
||||||
let enclosing_fn_def_id = tcx.typeck_root_def_id(def_id);
|
let enclosing_fn_def_id = tcx.typeck_root_def_id(def_id);
|
||||||
let generics = tcx.generics_of(enclosing_fn_def_id);
|
let generics = tcx.generics_of(enclosing_fn_def_id);
|
||||||
|
|
||||||
// Truncate the substs to the length of the above generics. This will cut off
|
// Truncate the args to the length of the above generics. This will cut off
|
||||||
// anything closure- or generator-specific.
|
// anything closure- or generator-specific.
|
||||||
let substs = substs.truncate_to(tcx, generics);
|
let args = args.truncate_to(tcx, generics);
|
||||||
push_generic_params_internal(tcx, substs, output, visited);
|
push_generic_params_internal(tcx, args, output, visited);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_close_angle_bracket(cpp_like_debuginfo: bool, output: &mut String) {
|
fn push_close_angle_bracket(cpp_like_debuginfo: bool, output: &mut String) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::traits::*;
|
use crate::traits::*;
|
||||||
|
|
||||||
use rustc_middle::ty::{self, subst::GenericArgKind, Ty};
|
use rustc_middle::ty::{self, GenericArgKind, Ty};
|
||||||
use rustc_session::config::Lto;
|
use rustc_session::config::Lto;
|
||||||
use rustc_symbol_mangling::typeid_for_trait_ref;
|
use rustc_symbol_mangling::typeid_for_trait_ref;
|
||||||
use rustc_target::abi::call::FnAbi;
|
use rustc_target::abi::call::FnAbi;
|
||||||
|
|
|
@ -491,7 +491,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
//
|
//
|
||||||
let virtual_drop = Instance {
|
let virtual_drop = Instance {
|
||||||
def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
|
def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
|
||||||
substs: drop_fn.substs,
|
args: drop_fn.args,
|
||||||
};
|
};
|
||||||
debug!("ty = {:?}", ty);
|
debug!("ty = {:?}", ty);
|
||||||
debug!("drop_fn = {:?}", drop_fn);
|
debug!("drop_fn = {:?}", drop_fn);
|
||||||
|
@ -531,7 +531,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
// SO THEN WE CAN USE THE ABOVE CODE.
|
// SO THEN WE CAN USE THE ABOVE CODE.
|
||||||
let virtual_drop = Instance {
|
let virtual_drop = Instance {
|
||||||
def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
|
def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
|
||||||
substs: drop_fn.substs,
|
args: drop_fn.args,
|
||||||
};
|
};
|
||||||
debug!("ty = {:?}", ty);
|
debug!("ty = {:?}", ty);
|
||||||
debug!("drop_fn = {:?}", drop_fn);
|
debug!("drop_fn = {:?}", drop_fn);
|
||||||
|
@ -687,7 +687,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
// which mentions the offending type, even from a const context.
|
// which mentions the offending type, even from a const context.
|
||||||
let panic_intrinsic = intrinsic.and_then(|s| ValidityRequirement::from_intrinsic(s));
|
let panic_intrinsic = intrinsic.and_then(|s| ValidityRequirement::from_intrinsic(s));
|
||||||
if let Some(requirement) = panic_intrinsic {
|
if let Some(requirement) = panic_intrinsic {
|
||||||
let ty = instance.unwrap().substs.type_at(0);
|
let ty = instance.unwrap().args.type_at(0);
|
||||||
|
|
||||||
let do_panic = !bx
|
let do_panic = !bx
|
||||||
.tcx()
|
.tcx()
|
||||||
|
@ -760,13 +760,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
let callee = self.codegen_operand(bx, func);
|
let callee = self.codegen_operand(bx, func);
|
||||||
|
|
||||||
let (instance, mut llfn) = match *callee.layout.ty.kind() {
|
let (instance, mut llfn) = match *callee.layout.ty.kind() {
|
||||||
ty::FnDef(def_id, substs) => (
|
ty::FnDef(def_id, args) => (
|
||||||
Some(
|
Some(
|
||||||
ty::Instance::expect_resolve(
|
ty::Instance::expect_resolve(
|
||||||
bx.tcx(),
|
bx.tcx(),
|
||||||
ty::ParamEnv::reveal_all(),
|
ty::ParamEnv::reveal_all(),
|
||||||
def_id,
|
def_id,
|
||||||
substs,
|
args,
|
||||||
)
|
)
|
||||||
.polymorphize(bx.tcx()),
|
.polymorphize(bx.tcx()),
|
||||||
),
|
),
|
||||||
|
@ -1125,12 +1125,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
}
|
}
|
||||||
mir::InlineAsmOperand::SymFn { ref value } => {
|
mir::InlineAsmOperand::SymFn { ref value } => {
|
||||||
let literal = self.monomorphize(value.literal);
|
let literal = self.monomorphize(value.literal);
|
||||||
if let ty::FnDef(def_id, substs) = *literal.ty().kind() {
|
if let ty::FnDef(def_id, args) = *literal.ty().kind() {
|
||||||
let instance = ty::Instance::resolve_for_fn_ptr(
|
let instance = ty::Instance::resolve_for_fn_ptr(
|
||||||
bx.tcx(),
|
bx.tcx(),
|
||||||
ty::ParamEnv::reveal_all(),
|
ty::ParamEnv::reveal_all(),
|
||||||
def_id,
|
def_id,
|
||||||
substs,
|
args,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
InlineAsmOperandRef::SymFn { instance }
|
InlineAsmOperandRef::SymFn { instance }
|
||||||
|
|
|
@ -64,7 +64,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
) {
|
) {
|
||||||
let callee_ty = instance.ty(bx.tcx(), ty::ParamEnv::reveal_all());
|
let callee_ty = instance.ty(bx.tcx(), ty::ParamEnv::reveal_all());
|
||||||
|
|
||||||
let ty::FnDef(def_id, substs) = *callee_ty.kind() else {
|
let ty::FnDef(def_id, fn_args) = *callee_ty.kind() else {
|
||||||
bug!("expected fn item type, found {}", callee_ty);
|
bug!("expected fn item type, found {}", callee_ty);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
sym::va_start => bx.va_start(args[0].immediate()),
|
sym::va_start => bx.va_start(args[0].immediate()),
|
||||||
sym::va_end => bx.va_end(args[0].immediate()),
|
sym::va_end => bx.va_end(args[0].immediate()),
|
||||||
sym::size_of_val => {
|
sym::size_of_val => {
|
||||||
let tp_ty = substs.type_at(0);
|
let tp_ty = fn_args.type_at(0);
|
||||||
if let OperandValue::Pair(_, meta) = args[0].val {
|
if let OperandValue::Pair(_, meta) = args[0].val {
|
||||||
let (llsize, _) = glue::size_and_align_of_dst(bx, tp_ty, Some(meta));
|
let (llsize, _) = glue::size_and_align_of_dst(bx, tp_ty, Some(meta));
|
||||||
llsize
|
llsize
|
||||||
|
@ -96,7 +96,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sym::min_align_of_val => {
|
sym::min_align_of_val => {
|
||||||
let tp_ty = substs.type_at(0);
|
let tp_ty = fn_args.type_at(0);
|
||||||
if let OperandValue::Pair(_, meta) = args[0].val {
|
if let OperandValue::Pair(_, meta) = args[0].val {
|
||||||
let (_, llalign) = glue::size_and_align_of_dst(bx, tp_ty, Some(meta));
|
let (_, llalign) = glue::size_and_align_of_dst(bx, tp_ty, Some(meta));
|
||||||
llalign
|
llalign
|
||||||
|
@ -136,7 +136,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
OperandRef::from_const(bx, value, ret_ty).immediate_or_packed_pair(bx)
|
OperandRef::from_const(bx, value, ret_ty).immediate_or_packed_pair(bx)
|
||||||
}
|
}
|
||||||
sym::arith_offset => {
|
sym::arith_offset => {
|
||||||
let ty = substs.type_at(0);
|
let ty = fn_args.type_at(0);
|
||||||
let layout = bx.layout_of(ty);
|
let layout = bx.layout_of(ty);
|
||||||
let ptr = args[0].immediate();
|
let ptr = args[0].immediate();
|
||||||
let offset = args[1].immediate();
|
let offset = args[1].immediate();
|
||||||
|
@ -147,7 +147,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
bx,
|
bx,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
substs.type_at(0),
|
fn_args.type_at(0),
|
||||||
args[1].immediate(),
|
args[1].immediate(),
|
||||||
args[0].immediate(),
|
args[0].immediate(),
|
||||||
args[2].immediate(),
|
args[2].immediate(),
|
||||||
|
@ -158,7 +158,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
memset_intrinsic(
|
memset_intrinsic(
|
||||||
bx,
|
bx,
|
||||||
false,
|
false,
|
||||||
substs.type_at(0),
|
fn_args.type_at(0),
|
||||||
args[0].immediate(),
|
args[0].immediate(),
|
||||||
args[1].immediate(),
|
args[1].immediate(),
|
||||||
args[2].immediate(),
|
args[2].immediate(),
|
||||||
|
@ -171,7 +171,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
bx,
|
bx,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
substs.type_at(0),
|
fn_args.type_at(0),
|
||||||
args[0].immediate(),
|
args[0].immediate(),
|
||||||
args[1].immediate(),
|
args[1].immediate(),
|
||||||
args[2].immediate(),
|
args[2].immediate(),
|
||||||
|
@ -183,7 +183,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
bx,
|
bx,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
substs.type_at(0),
|
fn_args.type_at(0),
|
||||||
args[0].immediate(),
|
args[0].immediate(),
|
||||||
args[1].immediate(),
|
args[1].immediate(),
|
||||||
args[2].immediate(),
|
args[2].immediate(),
|
||||||
|
@ -194,7 +194,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
memset_intrinsic(
|
memset_intrinsic(
|
||||||
bx,
|
bx,
|
||||||
true,
|
true,
|
||||||
substs.type_at(0),
|
fn_args.type_at(0),
|
||||||
args[0].immediate(),
|
args[0].immediate(),
|
||||||
args[1].immediate(),
|
args[1].immediate(),
|
||||||
args[2].immediate(),
|
args[2].immediate(),
|
||||||
|
@ -307,7 +307,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
let Some((success, failure)) = ordering.split_once('_') else {
|
let Some((success, failure)) = ordering.split_once('_') else {
|
||||||
bx.sess().emit_fatal(errors::AtomicCompareExchange);
|
bx.sess().emit_fatal(errors::AtomicCompareExchange);
|
||||||
};
|
};
|
||||||
let ty = substs.type_at(0);
|
let ty = fn_args.type_at(0);
|
||||||
if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
|
if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
|
||||||
let weak = instruction == "cxchgweak";
|
let weak = instruction == "cxchgweak";
|
||||||
let mut dst = args[0].immediate();
|
let mut dst = args[0].immediate();
|
||||||
|
@ -338,7 +338,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
"load" => {
|
"load" => {
|
||||||
let ty = substs.type_at(0);
|
let ty = fn_args.type_at(0);
|
||||||
if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
|
if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
|
||||||
let layout = bx.layout_of(ty);
|
let layout = bx.layout_of(ty);
|
||||||
let size = layout.size;
|
let size = layout.size;
|
||||||
|
@ -361,7 +361,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
"store" => {
|
"store" => {
|
||||||
let ty = substs.type_at(0);
|
let ty = fn_args.type_at(0);
|
||||||
if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
|
if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
|
||||||
let size = bx.layout_of(ty).size;
|
let size = bx.layout_of(ty).size;
|
||||||
let mut val = args[1].immediate();
|
let mut val = args[1].immediate();
|
||||||
|
@ -407,7 +407,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
_ => bx.sess().emit_fatal(errors::UnknownAtomicOperation),
|
_ => bx.sess().emit_fatal(errors::UnknownAtomicOperation),
|
||||||
};
|
};
|
||||||
|
|
||||||
let ty = substs.type_at(0);
|
let ty = fn_args.type_at(0);
|
||||||
if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
|
if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
|
||||||
let mut ptr = args[0].immediate();
|
let mut ptr = args[0].immediate();
|
||||||
let mut val = args[1].immediate();
|
let mut val = args[1].immediate();
|
||||||
|
@ -439,7 +439,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
sym::ptr_offset_from | sym::ptr_offset_from_unsigned => {
|
sym::ptr_offset_from | sym::ptr_offset_from_unsigned => {
|
||||||
let ty = substs.type_at(0);
|
let ty = fn_args.type_at(0);
|
||||||
let pointee_size = bx.layout_of(ty).size;
|
let pointee_size = bx.layout_of(ty).size;
|
||||||
|
|
||||||
let a = args[0].immediate();
|
let a = args[0].immediate();
|
||||||
|
|
|
@ -159,7 +159,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||||
cx: &'a Bx::CodegenCx,
|
cx: &'a Bx::CodegenCx,
|
||||||
instance: Instance<'tcx>,
|
instance: Instance<'tcx>,
|
||||||
) {
|
) {
|
||||||
assert!(!instance.substs.has_infer());
|
assert!(!instance.args.has_infer());
|
||||||
|
|
||||||
let llfn = cx.get_fn(instance);
|
let llfn = cx.get_fn(instance);
|
||||||
|
|
||||||
|
|
|
@ -417,12 +417,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
}
|
}
|
||||||
mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
|
mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
|
||||||
match *operand.layout.ty.kind() {
|
match *operand.layout.ty.kind() {
|
||||||
ty::FnDef(def_id, substs) => {
|
ty::FnDef(def_id, args) => {
|
||||||
let instance = ty::Instance::resolve_for_fn_ptr(
|
let instance = ty::Instance::resolve_for_fn_ptr(
|
||||||
bx.tcx(),
|
bx.tcx(),
|
||||||
ty::ParamEnv::reveal_all(),
|
ty::ParamEnv::reveal_all(),
|
||||||
def_id,
|
def_id,
|
||||||
substs,
|
args,
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.polymorphize(bx.cx().tcx());
|
.polymorphize(bx.cx().tcx());
|
||||||
|
@ -433,11 +433,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
}
|
}
|
||||||
mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)) => {
|
mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)) => {
|
||||||
match *operand.layout.ty.kind() {
|
match *operand.layout.ty.kind() {
|
||||||
ty::Closure(def_id, substs) => {
|
ty::Closure(def_id, args) => {
|
||||||
let instance = Instance::resolve_closure(
|
let instance = Instance::resolve_closure(
|
||||||
bx.cx().tcx(),
|
bx.cx().tcx(),
|
||||||
def_id,
|
def_id,
|
||||||
substs,
|
args,
|
||||||
ty::ClosureKind::FnOnce,
|
ty::ClosureKind::FnOnce,
|
||||||
)
|
)
|
||||||
.expect("failed to normalize and resolve closure during codegen")
|
.expect("failed to normalize and resolve closure during codegen")
|
||||||
|
@ -711,7 +711,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
{
|
{
|
||||||
let instance = ty::Instance {
|
let instance = ty::Instance {
|
||||||
def: ty::InstanceDef::ThreadLocalShim(def_id),
|
def: ty::InstanceDef::ThreadLocalShim(def_id),
|
||||||
substs: ty::InternalSubsts::empty(),
|
args: ty::GenericArgs::empty(),
|
||||||
};
|
};
|
||||||
let fn_ptr = bx.get_fn_addr(instance);
|
let fn_ptr = bx.get_fn_addr(instance);
|
||||||
let fn_abi = bx.fn_abi_of_instance(instance, ty::List::empty());
|
let fn_abi = bx.fn_abi_of_instance(instance, ty::List::empty());
|
||||||
|
|
|
@ -64,7 +64,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
|
||||||
.typeck_body(anon_const.body)
|
.typeck_body(anon_const.body)
|
||||||
.node_type(anon_const.hir_id);
|
.node_type(anon_const.hir_id);
|
||||||
let instance = match ty.kind() {
|
let instance = match ty.kind() {
|
||||||
&ty::FnDef(def_id, substs) => Instance::new(def_id, substs),
|
&ty::FnDef(def_id, args) => Instance::new(def_id, args),
|
||||||
_ => span_bug!(*op_sp, "asm sym is not a function"),
|
_ => span_bug!(*op_sp, "asm sym is not a function"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
|
||||||
fn to_raw_string(&self) -> String {
|
fn to_raw_string(&self) -> String {
|
||||||
match *self {
|
match *self {
|
||||||
MonoItem::Fn(instance) => {
|
MonoItem::Fn(instance) => {
|
||||||
format!("Fn({:?}, {})", instance.def, instance.substs.as_ptr().addr())
|
format!("Fn({:?}, {})", instance.def, instance.args.as_ptr().addr())
|
||||||
}
|
}
|
||||||
MonoItem::Static(id) => format!("Static({:?})", id),
|
MonoItem::Static(id) => format!("Static({:?})", id),
|
||||||
MonoItem::GlobalAsm(id) => format!("GlobalAsm({:?})", id),
|
MonoItem::GlobalAsm(id) => format!("GlobalAsm({:?})", id),
|
||||||
|
|
|
@ -45,7 +45,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
|
||||||
"Unexpected DefKind: {:?}",
|
"Unexpected DefKind: {:?}",
|
||||||
ecx.tcx.def_kind(cid.instance.def_id())
|
ecx.tcx.def_kind(cid.instance.def_id())
|
||||||
);
|
);
|
||||||
let layout = ecx.layout_of(body.bound_return_ty().subst(tcx, cid.instance.substs))?;
|
let layout = ecx.layout_of(body.bound_return_ty().instantiate(tcx, cid.instance.args))?;
|
||||||
assert!(layout.is_sized());
|
assert!(layout.is_sized());
|
||||||
let ret = ecx.allocate(layout, MemoryKind::Stack)?;
|
let ret = ecx.allocate(layout, MemoryKind::Stack)?;
|
||||||
|
|
||||||
|
@ -245,10 +245,10 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
|
||||||
// Catch such calls and evaluate them instead of trying to load a constant's MIR.
|
// Catch such calls and evaluate them instead of trying to load a constant's MIR.
|
||||||
if let ty::InstanceDef::Intrinsic(def_id) = key.value.instance.def {
|
if let ty::InstanceDef::Intrinsic(def_id) = key.value.instance.def {
|
||||||
let ty = key.value.instance.ty(tcx, key.param_env);
|
let ty = key.value.instance.ty(tcx, key.param_env);
|
||||||
let ty::FnDef(_, substs) = ty.kind() else {
|
let ty::FnDef(_, args) = ty.kind() else {
|
||||||
bug!("intrinsic with type {:?}", ty);
|
bug!("intrinsic with type {:?}", ty);
|
||||||
};
|
};
|
||||||
return eval_nullary_intrinsic(tcx, key.param_env, def_id, substs).map_err(|error| {
|
return eval_nullary_intrinsic(tcx, key.param_env, def_id, args).map_err(|error| {
|
||||||
let span = tcx.def_span(def_id);
|
let span = tcx.def_span(def_id);
|
||||||
|
|
||||||
super::report(
|
super::report(
|
||||||
|
@ -328,10 +328,10 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
|
||||||
("static", String::new())
|
("static", String::new())
|
||||||
} else {
|
} else {
|
||||||
// If the current item has generics, we'd like to enrich the message with the
|
// If the current item has generics, we'd like to enrich the message with the
|
||||||
// instance and its substs: to show the actual compile-time values, in addition to
|
// instance and its args: to show the actual compile-time values, in addition to
|
||||||
// the expression, leading to the const eval error.
|
// the expression, leading to the const eval error.
|
||||||
let instance = &key.value.instance;
|
let instance = &key.value.instance;
|
||||||
if !instance.substs.is_empty() {
|
if !instance.args.is_empty() {
|
||||||
let instance = with_no_trimmed_paths!(instance.to_string());
|
let instance = with_no_trimmed_paths!(instance.to_string());
|
||||||
("const_with_path", instance)
|
("const_with_path", instance)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -230,7 +230,7 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> {
|
||||||
*self.tcx,
|
*self.tcx,
|
||||||
ty::ParamEnv::reveal_all(),
|
ty::ParamEnv::reveal_all(),
|
||||||
const_def_id,
|
const_def_id,
|
||||||
instance.substs,
|
instance.args,
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -105,7 +105,7 @@ pub(crate) fn try_destructure_mir_constant_for_diagnostics<'tcx>(
|
||||||
let down = ecx.operand_downcast(&op, variant).ok()?;
|
let down = ecx.operand_downcast(&op, variant).ok()?;
|
||||||
(def.variants()[variant].fields.len(), Some(variant), down)
|
(def.variants()[variant].fields.len(), Some(variant), down)
|
||||||
}
|
}
|
||||||
ty::Tuple(substs) => (substs.len(), None, op),
|
ty::Tuple(args) => (args.len(), None, op),
|
||||||
_ => bug!("cannot destructure mir constant {:?}", val),
|
_ => bug!("cannot destructure mir constant {:?}", val),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -416,9 +416,9 @@ fn valtree_into_mplace<'tcx>(
|
||||||
debug!(?unsized_inner_ty);
|
debug!(?unsized_inner_ty);
|
||||||
|
|
||||||
let inner_ty = match ty.kind() {
|
let inner_ty = match ty.kind() {
|
||||||
ty::Adt(def, substs) => {
|
ty::Adt(def, args) => {
|
||||||
let i = FieldIdx::from_usize(i);
|
let i = FieldIdx::from_usize(i);
|
||||||
def.variant(FIRST_VARIANT).fields[i].ty(tcx, substs)
|
def.variant(FIRST_VARIANT).fields[i].ty(tcx, args)
|
||||||
}
|
}
|
||||||
ty::Tuple(inner_tys) => inner_tys[i],
|
ty::Tuple(inner_tys) => inner_tys[i],
|
||||||
_ => bug!("unexpected unsized type {:?}", ty),
|
_ => bug!("unexpected unsized type {:?}", ty),
|
||||||
|
|
|
@ -75,12 +75,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
|
|
||||||
// The src operand does not matter, just its type
|
// The src operand does not matter, just its type
|
||||||
match *src.layout.ty.kind() {
|
match *src.layout.ty.kind() {
|
||||||
ty::FnDef(def_id, substs) => {
|
ty::FnDef(def_id, args) => {
|
||||||
let instance = ty::Instance::resolve_for_fn_ptr(
|
let instance = ty::Instance::resolve_for_fn_ptr(
|
||||||
*self.tcx,
|
*self.tcx,
|
||||||
self.param_env,
|
self.param_env,
|
||||||
def_id,
|
def_id,
|
||||||
substs,
|
args,
|
||||||
)
|
)
|
||||||
.ok_or_else(|| err_inval!(TooGeneric))?;
|
.ok_or_else(|| err_inval!(TooGeneric))?;
|
||||||
|
|
||||||
|
@ -108,11 +108,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
|
|
||||||
// The src operand does not matter, just its type
|
// The src operand does not matter, just its type
|
||||||
match *src.layout.ty.kind() {
|
match *src.layout.ty.kind() {
|
||||||
ty::Closure(def_id, substs) => {
|
ty::Closure(def_id, args) => {
|
||||||
let instance = ty::Instance::resolve_closure(
|
let instance = ty::Instance::resolve_closure(
|
||||||
*self.tcx,
|
*self.tcx,
|
||||||
def_id,
|
def_id,
|
||||||
substs,
|
args,
|
||||||
ty::ClosureKind::FnOnce,
|
ty::ClosureKind::FnOnce,
|
||||||
)
|
)
|
||||||
.ok_or_else(|| err_inval!(TooGeneric))?;
|
.ok_or_else(|| err_inval!(TooGeneric))?;
|
||||||
|
|
|
@ -164,11 +164,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
ty::Adt(adt, _) => {
|
ty::Adt(adt, _) => {
|
||||||
adt.discriminants(*self.tcx).find(|(_, var)| var.val == discr_bits)
|
adt.discriminants(*self.tcx).find(|(_, var)| var.val == discr_bits)
|
||||||
}
|
}
|
||||||
ty::Generator(def_id, substs, _) => {
|
ty::Generator(def_id, args, _) => {
|
||||||
let substs = substs.as_generator();
|
let args = args.as_generator();
|
||||||
substs
|
args.discriminants(def_id, *self.tcx).find(|(_, var)| var.val == discr_bits)
|
||||||
.discriminants(def_id, *self.tcx)
|
|
||||||
.find(|(_, var)| var.val == discr_bits)
|
|
||||||
}
|
}
|
||||||
_ => span_bug!(self.cur_span(), "tagged layout for non-adt non-generator"),
|
_ => span_bug!(self.cur_span(), "tagged layout for non-adt non-generator"),
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ use rustc_middle::ty::layout::{
|
||||||
self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers,
|
self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers,
|
||||||
TyAndLayout,
|
TyAndLayout,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::{self, subst::SubstsRef, ParamEnv, Ty, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt, TypeFoldable};
|
||||||
use rustc_mir_dataflow::storage::always_storage_live_locals;
|
use rustc_mir_dataflow::storage::always_storage_live_locals;
|
||||||
use rustc_session::Limit;
|
use rustc_session::Limit;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -91,7 +91,7 @@ pub struct Frame<'mir, 'tcx, Prov: Provenance = AllocId, Extra = ()> {
|
||||||
/// The MIR for the function called on this frame.
|
/// The MIR for the function called on this frame.
|
||||||
pub body: &'mir mir::Body<'tcx>,
|
pub body: &'mir mir::Body<'tcx>,
|
||||||
|
|
||||||
/// The def_id and substs of the current function.
|
/// The def_id and args of the current function.
|
||||||
pub instance: ty::Instance<'tcx>,
|
pub instance: ty::Instance<'tcx>,
|
||||||
|
|
||||||
/// Extra data for the machine.
|
/// Extra data for the machine.
|
||||||
|
@ -529,16 +529,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
.map_err(|_| err_inval!(TooGeneric))
|
.map_err(|_| err_inval!(TooGeneric))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The `substs` are assumed to already be in our interpreter "universe" (param_env).
|
/// The `args` are assumed to already be in our interpreter "universe" (param_env).
|
||||||
pub(super) fn resolve(
|
pub(super) fn resolve(
|
||||||
&self,
|
&self,
|
||||||
def: DefId,
|
def: DefId,
|
||||||
substs: SubstsRef<'tcx>,
|
args: GenericArgsRef<'tcx>,
|
||||||
) -> InterpResult<'tcx, ty::Instance<'tcx>> {
|
) -> InterpResult<'tcx, ty::Instance<'tcx>> {
|
||||||
trace!("resolve: {:?}, {:#?}", def, substs);
|
trace!("resolve: {:?}, {:#?}", def, args);
|
||||||
trace!("param_env: {:#?}", self.param_env);
|
trace!("param_env: {:#?}", self.param_env);
|
||||||
trace!("substs: {:#?}", substs);
|
trace!("args: {:#?}", args);
|
||||||
match ty::Instance::resolve(*self.tcx, self.param_env, def, substs) {
|
match ty::Instance::resolve(*self.tcx, self.param_env, def, args) {
|
||||||
Ok(Some(instance)) => Ok(instance),
|
Ok(Some(instance)) => Ok(instance),
|
||||||
Ok(None) => throw_inval!(TooGeneric),
|
Ok(None) => throw_inval!(TooGeneric),
|
||||||
|
|
||||||
|
@ -684,7 +684,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
return_to_block: StackPopCleanup,
|
return_to_block: StackPopCleanup,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
trace!("body: {:#?}", body);
|
trace!("body: {:#?}", body);
|
||||||
// First push a stack frame so we have access to the local substs
|
// First push a stack frame so we have access to the local args
|
||||||
let pre_frame = Frame {
|
let pre_frame = Frame {
|
||||||
body,
|
body,
|
||||||
loc: Right(body.span), // Span used for errors caused during preamble.
|
loc: Right(body.span), // Span used for errors caused during preamble.
|
||||||
|
|
|
@ -12,7 +12,7 @@ use rustc_middle::mir::{
|
||||||
};
|
};
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_middle::ty::layout::{LayoutOf as _, ValidityRequirement};
|
use rustc_middle::ty::layout::{LayoutOf as _, ValidityRequirement};
|
||||||
use rustc_middle::ty::subst::SubstsRef;
|
use rustc_middle::ty::GenericArgsRef;
|
||||||
use rustc_middle::ty::{Ty, TyCtxt};
|
use rustc_middle::ty::{Ty, TyCtxt};
|
||||||
use rustc_span::symbol::{sym, Symbol};
|
use rustc_span::symbol::{sym, Symbol};
|
||||||
use rustc_target::abi::{Abi, Align, Primitive, Size};
|
use rustc_target::abi::{Abi, Align, Primitive, Size};
|
||||||
|
@ -56,9 +56,9 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
substs: SubstsRef<'tcx>,
|
args: GenericArgsRef<'tcx>,
|
||||||
) -> InterpResult<'tcx, ConstValue<'tcx>> {
|
) -> InterpResult<'tcx, ConstValue<'tcx>> {
|
||||||
let tp_ty = substs.type_at(0);
|
let tp_ty = args.type_at(0);
|
||||||
let name = tcx.item_name(def_id);
|
let name = tcx.item_name(def_id);
|
||||||
Ok(match name {
|
Ok(match name {
|
||||||
sym::type_name => {
|
sym::type_name => {
|
||||||
|
@ -123,7 +123,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
dest: &PlaceTy<'tcx, M::Provenance>,
|
dest: &PlaceTy<'tcx, M::Provenance>,
|
||||||
ret: Option<mir::BasicBlock>,
|
ret: Option<mir::BasicBlock>,
|
||||||
) -> InterpResult<'tcx, bool> {
|
) -> InterpResult<'tcx, bool> {
|
||||||
let substs = instance.substs;
|
let instance_args = instance.args;
|
||||||
let intrinsic_name = self.tcx.item_name(instance.def_id());
|
let intrinsic_name = self.tcx.item_name(instance.def_id());
|
||||||
|
|
||||||
// First handle intrinsics without return place.
|
// First handle intrinsics without return place.
|
||||||
|
@ -187,7 +187,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
| sym::ctlz_nonzero
|
| sym::ctlz_nonzero
|
||||||
| sym::bswap
|
| sym::bswap
|
||||||
| sym::bitreverse => {
|
| sym::bitreverse => {
|
||||||
let ty = substs.type_at(0);
|
let ty = instance_args.type_at(0);
|
||||||
let layout_of = self.layout_of(ty)?;
|
let layout_of = self.layout_of(ty)?;
|
||||||
let val = self.read_scalar(&args[0])?;
|
let val = self.read_scalar(&args[0])?;
|
||||||
let bits = val.to_bits(layout_of.size)?;
|
let bits = val.to_bits(layout_of.size)?;
|
||||||
|
@ -237,7 +237,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
sym::rotate_left | sym::rotate_right => {
|
sym::rotate_left | sym::rotate_right => {
|
||||||
// rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW))
|
// rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW))
|
||||||
// rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
|
// rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
|
||||||
let layout = self.layout_of(substs.type_at(0))?;
|
let layout = self.layout_of(instance_args.type_at(0))?;
|
||||||
let val = self.read_scalar(&args[0])?;
|
let val = self.read_scalar(&args[0])?;
|
||||||
let val_bits = val.to_bits(layout.size)?;
|
let val_bits = val.to_bits(layout.size)?;
|
||||||
let raw_shift = self.read_scalar(&args[1])?;
|
let raw_shift = self.read_scalar(&args[1])?;
|
||||||
|
@ -263,7 +263,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
sym::arith_offset => {
|
sym::arith_offset => {
|
||||||
let ptr = self.read_pointer(&args[0])?;
|
let ptr = self.read_pointer(&args[0])?;
|
||||||
let offset_count = self.read_target_isize(&args[1])?;
|
let offset_count = self.read_target_isize(&args[1])?;
|
||||||
let pointee_ty = substs.type_at(0);
|
let pointee_ty = instance_args.type_at(0);
|
||||||
|
|
||||||
let pointee_size = i64::try_from(self.layout_of(pointee_ty)?.size.bytes()).unwrap();
|
let pointee_size = i64::try_from(self.layout_of(pointee_ty)?.size.bytes()).unwrap();
|
||||||
let offset_bytes = offset_count.wrapping_mul(pointee_size);
|
let offset_bytes = offset_count.wrapping_mul(pointee_size);
|
||||||
|
@ -368,7 +368,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
assert!(self.target_isize_min() <= dist && dist <= self.target_isize_max());
|
assert!(self.target_isize_min() <= dist && dist <= self.target_isize_max());
|
||||||
isize_layout
|
isize_layout
|
||||||
};
|
};
|
||||||
let pointee_layout = self.layout_of(substs.type_at(0))?;
|
let pointee_layout = self.layout_of(instance_args.type_at(0))?;
|
||||||
// If ret_layout is unsigned, we checked that so is the distance, so we are good.
|
// If ret_layout is unsigned, we checked that so is the distance, so we are good.
|
||||||
let val = ImmTy::from_int(dist, ret_layout);
|
let val = ImmTy::from_int(dist, ret_layout);
|
||||||
let size = ImmTy::from_int(pointee_layout.size.bytes(), ret_layout);
|
let size = ImmTy::from_int(pointee_layout.size.bytes(), ret_layout);
|
||||||
|
@ -378,7 +378,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
sym::assert_inhabited
|
sym::assert_inhabited
|
||||||
| sym::assert_zero_valid
|
| sym::assert_zero_valid
|
||||||
| sym::assert_mem_uninitialized_valid => {
|
| sym::assert_mem_uninitialized_valid => {
|
||||||
let ty = instance.substs.type_at(0);
|
let ty = instance.args.type_at(0);
|
||||||
let requirement = ValidityRequirement::from_intrinsic(intrinsic_name).unwrap();
|
let requirement = ValidityRequirement::from_intrinsic(intrinsic_name).unwrap();
|
||||||
|
|
||||||
let should_panic = !self
|
let should_panic = !self
|
||||||
|
|
|
@ -96,7 +96,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
let loc_ty = self
|
let loc_ty = self
|
||||||
.tcx
|
.tcx
|
||||||
.type_of(self.tcx.require_lang_item(LangItem::PanicLocation, None))
|
.type_of(self.tcx.require_lang_item(LangItem::PanicLocation, None))
|
||||||
.subst(*self.tcx, self.tcx.mk_substs(&[self.tcx.lifetimes.re_erased.into()]));
|
.instantiate(*self.tcx, self.tcx.mk_args(&[self.tcx.lifetimes.re_erased.into()]));
|
||||||
let loc_layout = self.layout_of(loc_ty).unwrap();
|
let loc_layout = self.layout_of(loc_ty).unwrap();
|
||||||
let location = self.allocate(loc_layout, MemoryKind::CallerLocation).unwrap();
|
let location = self.allocate(loc_layout, MemoryKind::CallerLocation).unwrap();
|
||||||
|
|
||||||
|
|
|
@ -590,7 +590,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
throw_inval!(AlreadyReported(reported.into()))
|
throw_inval!(AlreadyReported(reported.into()))
|
||||||
}
|
}
|
||||||
ty::ConstKind::Unevaluated(uv) => {
|
ty::ConstKind::Unevaluated(uv) => {
|
||||||
let instance = self.resolve(uv.def, uv.substs)?;
|
let instance = self.resolve(uv.def, uv.args)?;
|
||||||
let cid = GlobalId { instance, promoted: None };
|
let cid = GlobalId { instance, promoted: None };
|
||||||
self.ctfe_query(span, |tcx| {
|
self.ctfe_query(span, |tcx| {
|
||||||
tcx.eval_to_valtree(self.param_env.with_const().and(cid))
|
tcx.eval_to_valtree(self.param_env.with_const().and(cid))
|
||||||
|
@ -619,7 +619,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
}
|
}
|
||||||
mir::ConstantKind::Val(val, ty) => self.const_val_to_op(val, ty, layout),
|
mir::ConstantKind::Val(val, ty) => self.const_val_to_op(val, ty, layout),
|
||||||
mir::ConstantKind::Unevaluated(uv, _) => {
|
mir::ConstantKind::Unevaluated(uv, _) => {
|
||||||
let instance = self.resolve(uv.def, uv.substs)?;
|
let instance = self.resolve(uv.def, uv.args)?;
|
||||||
Ok(self.eval_global(GlobalId { instance, promoted: uv.promoted }, span)?.into())
|
Ok(self.eval_global(GlobalId { instance, promoted: uv.promoted }, span)?.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,8 +135,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
let fn_val = self.get_ptr_fn(fn_ptr)?;
|
let fn_val = self.get_ptr_fn(fn_ptr)?;
|
||||||
(fn_val, self.fn_abi_of_fn_ptr(fn_sig_binder, extra_args)?, false)
|
(fn_val, self.fn_abi_of_fn_ptr(fn_sig_binder, extra_args)?, false)
|
||||||
}
|
}
|
||||||
ty::FnDef(def_id, substs) => {
|
ty::FnDef(def_id, args) => {
|
||||||
let instance = self.resolve(def_id, substs)?;
|
let instance = self.resolve(def_id, args)?;
|
||||||
(
|
(
|
||||||
FnVal::Instance(instance),
|
FnVal::Instance(instance),
|
||||||
self.fn_abi_of_instance(instance, extra_args)?,
|
self.fn_abi_of_instance(instance, extra_args)?,
|
||||||
|
@ -748,7 +748,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
|
|
||||||
let trait_def_id = tcx.trait_of_item(def_id).unwrap();
|
let trait_def_id = tcx.trait_of_item(def_id).unwrap();
|
||||||
let virtual_trait_ref =
|
let virtual_trait_ref =
|
||||||
ty::TraitRef::from_method(tcx, trait_def_id, instance.substs);
|
ty::TraitRef::from_method(tcx, trait_def_id, instance.args);
|
||||||
let existential_trait_ref =
|
let existential_trait_ref =
|
||||||
ty::ExistentialTraitRef::erase_self_ty(tcx, virtual_trait_ref);
|
ty::ExistentialTraitRef::erase_self_ty(tcx, virtual_trait_ref);
|
||||||
let concrete_trait_ref = existential_trait_ref.with_self_ty(tcx, dyn_ty);
|
let concrete_trait_ref = existential_trait_ref.with_self_ty(tcx, dyn_ty);
|
||||||
|
@ -757,7 +757,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
tcx,
|
tcx,
|
||||||
self.param_env,
|
self.param_env,
|
||||||
def_id,
|
def_id,
|
||||||
instance.substs.rebase_onto(tcx, trait_def_id, concrete_trait_ref.substs),
|
instance.args.rebase_onto(tcx, trait_def_id, concrete_trait_ref.args),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(fn_inst, concrete_method);
|
assert_eq!(fn_inst, concrete_method);
|
||||||
|
|
|
@ -33,12 +33,12 @@ where
|
||||||
|
|
||||||
match *ty.kind() {
|
match *ty.kind() {
|
||||||
ty::Param(_) => ControlFlow::Break(FoundParam),
|
ty::Param(_) => ControlFlow::Break(FoundParam),
|
||||||
ty::Closure(def_id, substs)
|
ty::Closure(def_id, args)
|
||||||
| ty::Generator(def_id, substs, ..)
|
| ty::Generator(def_id, args, ..)
|
||||||
| ty::FnDef(def_id, substs) => {
|
| ty::FnDef(def_id, args) => {
|
||||||
let instance = ty::InstanceDef::Item(def_id);
|
let instance = ty::InstanceDef::Item(def_id);
|
||||||
let unused_params = self.tcx.unused_generic_params(instance);
|
let unused_params = self.tcx.unused_generic_params(instance);
|
||||||
for (index, subst) in substs.into_iter().enumerate() {
|
for (index, subst) in args.into_iter().enumerate() {
|
||||||
let index = index
|
let index = index
|
||||||
.try_into()
|
.try_into()
|
||||||
.expect("more generic parameters than can fit into a `u32`");
|
.expect("more generic parameters than can fit into a `u32`");
|
||||||
|
|
|
@ -8,8 +8,8 @@ use rustc_infer::infer::TyCtxtInferExt;
|
||||||
use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
|
use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
|
||||||
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
|
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
|
|
||||||
use rustc_middle::ty::{self, adjustment::PointerCoercion, Instance, InstanceDef, Ty, TyCtxt};
|
use rustc_middle::ty::{self, adjustment::PointerCoercion, Instance, InstanceDef, Ty, TyCtxt};
|
||||||
|
use rustc_middle::ty::{GenericArgKind, GenericArgs};
|
||||||
use rustc_middle::ty::{TraitRef, TypeVisitableExt};
|
use rustc_middle::ty::{TraitRef, TypeVisitableExt};
|
||||||
use rustc_mir_dataflow::{self, Analysis};
|
use rustc_mir_dataflow::{self, Analysis};
|
||||||
use rustc_span::{sym, Span, Symbol};
|
use rustc_span::{sym, Span, Symbol};
|
||||||
|
@ -701,8 +701,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
|
|
||||||
let fn_ty = func.ty(body, tcx);
|
let fn_ty = func.ty(body, tcx);
|
||||||
|
|
||||||
let (mut callee, mut substs) = match *fn_ty.kind() {
|
let (mut callee, mut fn_args) = match *fn_ty.kind() {
|
||||||
ty::FnDef(def_id, substs) => (def_id, substs),
|
ty::FnDef(def_id, fn_args) => (def_id, fn_args),
|
||||||
|
|
||||||
ty::FnPtr(_) => {
|
ty::FnPtr(_) => {
|
||||||
self.check_op(ops::FnCallIndirect);
|
self.check_op(ops::FnCallIndirect);
|
||||||
|
@ -721,7 +721,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
let infcx = tcx.infer_ctxt().build();
|
let infcx = tcx.infer_ctxt().build();
|
||||||
let ocx = ObligationCtxt::new(&infcx);
|
let ocx = ObligationCtxt::new(&infcx);
|
||||||
|
|
||||||
let predicates = tcx.predicates_of(callee).instantiate(tcx, substs);
|
let predicates = tcx.predicates_of(callee).instantiate(tcx, fn_args);
|
||||||
let cause = ObligationCause::new(
|
let cause = ObligationCause::new(
|
||||||
terminator.source_info.span,
|
terminator.source_info.span,
|
||||||
self.body.source.def_id().expect_local(),
|
self.body.source.def_id().expect_local(),
|
||||||
|
@ -746,7 +746,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
self.check_op(ops::FnCallNonConst {
|
self.check_op(ops::FnCallNonConst {
|
||||||
caller,
|
caller,
|
||||||
callee,
|
callee,
|
||||||
substs,
|
args: fn_args,
|
||||||
span: *fn_span,
|
span: *fn_span,
|
||||||
call_source: *call_source,
|
call_source: *call_source,
|
||||||
feature: Some(sym::const_trait_impl),
|
feature: Some(sym::const_trait_impl),
|
||||||
|
@ -754,7 +754,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let trait_ref = TraitRef::from_method(tcx, trait_id, substs);
|
let trait_ref = TraitRef::from_method(tcx, trait_id, fn_args);
|
||||||
let trait_ref = trait_ref.with_constness(ty::BoundConstness::ConstIfConst);
|
let trait_ref = trait_ref.with_constness(ty::BoundConstness::ConstIfConst);
|
||||||
let obligation =
|
let obligation =
|
||||||
Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref);
|
Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref);
|
||||||
|
@ -778,7 +778,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
if trait_ref.self_ty().is_closure()
|
if trait_ref.self_ty().is_closure()
|
||||||
&& tcx.fn_trait_kind_from_def_id(trait_id).is_some() =>
|
&& tcx.fn_trait_kind_from_def_id(trait_id).is_some() =>
|
||||||
{
|
{
|
||||||
let ty::Closure(closure_def_id, substs) = *trait_ref.self_ty().kind()
|
let ty::Closure(closure_def_id, fn_args) = *trait_ref.self_ty().kind()
|
||||||
else {
|
else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
|
@ -786,7 +786,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
self.check_op(ops::FnCallNonConst {
|
self.check_op(ops::FnCallNonConst {
|
||||||
caller,
|
caller,
|
||||||
callee,
|
callee,
|
||||||
substs,
|
args: fn_args,
|
||||||
span: *fn_span,
|
span: *fn_span,
|
||||||
call_source: *call_source,
|
call_source: *call_source,
|
||||||
feature: None,
|
feature: None,
|
||||||
|
@ -802,9 +802,9 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
.iter()
|
.iter()
|
||||||
.find(|did| tcx.item_name(**did) == callee_name)
|
.find(|did| tcx.item_name(**did) == callee_name)
|
||||||
{
|
{
|
||||||
// using internal substs is ok here, since this is only
|
// using internal args is ok here, since this is only
|
||||||
// used for the `resolve` call below
|
// used for the `resolve` call below
|
||||||
substs = InternalSubsts::identity_for_item(tcx, did);
|
fn_args = GenericArgs::identity_for_item(tcx, did);
|
||||||
callee = did;
|
callee = did;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -812,7 +812,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
self.check_op(ops::FnCallNonConst {
|
self.check_op(ops::FnCallNonConst {
|
||||||
caller,
|
caller,
|
||||||
callee,
|
callee,
|
||||||
substs,
|
args: fn_args,
|
||||||
span: *fn_span,
|
span: *fn_span,
|
||||||
call_source: *call_source,
|
call_source: *call_source,
|
||||||
feature: None,
|
feature: None,
|
||||||
|
@ -828,7 +828,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
&& tcx.has_attr(callee_trait, sym::const_trait)
|
&& tcx.has_attr(callee_trait, sym::const_trait)
|
||||||
&& Some(callee_trait) == tcx.trait_of_item(caller.to_def_id())
|
&& Some(callee_trait) == tcx.trait_of_item(caller.to_def_id())
|
||||||
// Can only call methods when it's `<Self as TheTrait>::f`.
|
// Can only call methods when it's `<Self as TheTrait>::f`.
|
||||||
&& tcx.types.self_param == substs.type_at(0)
|
&& tcx.types.self_param == fn_args.type_at(0)
|
||||||
{
|
{
|
||||||
nonconst_call_permission = true;
|
nonconst_call_permission = true;
|
||||||
}
|
}
|
||||||
|
@ -855,7 +855,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
self.check_op(ops::FnCallNonConst {
|
self.check_op(ops::FnCallNonConst {
|
||||||
caller,
|
caller,
|
||||||
callee,
|
callee,
|
||||||
substs,
|
args: fn_args,
|
||||||
span: *fn_span,
|
span: *fn_span,
|
||||||
call_source: *call_source,
|
call_source: *call_source,
|
||||||
feature: None,
|
feature: None,
|
||||||
|
@ -868,7 +868,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
|
|
||||||
// Resolve a trait method call to its concrete implementation, which may be in a
|
// Resolve a trait method call to its concrete implementation, which may be in a
|
||||||
// `const` trait impl.
|
// `const` trait impl.
|
||||||
let instance = Instance::resolve(tcx, param_env, callee, substs);
|
let instance = Instance::resolve(tcx, param_env, callee, fn_args);
|
||||||
debug!("Resolving ({:?}) -> {:?}", callee, instance);
|
debug!("Resolving ({:?}) -> {:?}", callee, instance);
|
||||||
if let Ok(Some(func)) = instance {
|
if let Ok(Some(func)) = instance {
|
||||||
if let InstanceDef::Item(def) = func.def {
|
if let InstanceDef::Item(def) = func.def {
|
||||||
|
@ -915,7 +915,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
self.check_op(ops::FnCallNonConst {
|
self.check_op(ops::FnCallNonConst {
|
||||||
caller,
|
caller,
|
||||||
callee,
|
callee,
|
||||||
substs,
|
args: fn_args,
|
||||||
span: *fn_span,
|
span: *fn_span,
|
||||||
call_source: *call_source,
|
call_source: *call_source,
|
||||||
feature: None,
|
feature: None,
|
||||||
|
|
|
@ -68,11 +68,11 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> {
|
||||||
pub fn fn_sig(&self) -> PolyFnSig<'tcx> {
|
pub fn fn_sig(&self) -> PolyFnSig<'tcx> {
|
||||||
let did = self.def_id().to_def_id();
|
let did = self.def_id().to_def_id();
|
||||||
if self.tcx.is_closure(did) {
|
if self.tcx.is_closure(did) {
|
||||||
let ty = self.tcx.type_of(did).subst_identity();
|
let ty = self.tcx.type_of(did).instantiate_identity();
|
||||||
let ty::Closure(_, substs) = ty.kind() else { bug!("type_of closure not ty::Closure") };
|
let ty::Closure(_, args) = ty.kind() else { bug!("type_of closure not ty::Closure") };
|
||||||
substs.as_closure().sig()
|
args.as_closure().sig()
|
||||||
} else {
|
} else {
|
||||||
self.tcx.fn_sig(did).subst_identity()
|
self.tcx.fn_sig(did).instantiate_identity()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,9 @@ use rustc_infer::infer::TyCtxtInferExt;
|
||||||
use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
|
use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
|
||||||
use rustc_middle::mir::{self, CallSource};
|
use rustc_middle::mir::{self, CallSource};
|
||||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||||
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
|
|
||||||
use rustc_middle::ty::TraitRef;
|
use rustc_middle::ty::TraitRef;
|
||||||
use rustc_middle::ty::{suggest_constraining_type_param, Adt, Closure, FnDef, FnPtr, Param, Ty};
|
use rustc_middle::ty::{suggest_constraining_type_param, Adt, Closure, FnDef, FnPtr, Param, Ty};
|
||||||
|
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
|
||||||
use rustc_middle::util::{call_kind, CallDesugaringKind, CallKind};
|
use rustc_middle::util::{call_kind, CallDesugaringKind, CallKind};
|
||||||
use rustc_session::parse::feature_err;
|
use rustc_session::parse::feature_err;
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
|
@ -98,7 +98,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallIndirect {
|
||||||
pub struct FnCallNonConst<'tcx> {
|
pub struct FnCallNonConst<'tcx> {
|
||||||
pub caller: LocalDefId,
|
pub caller: LocalDefId,
|
||||||
pub callee: DefId,
|
pub callee: DefId,
|
||||||
pub substs: SubstsRef<'tcx>,
|
pub args: GenericArgsRef<'tcx>,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub call_source: CallSource,
|
pub call_source: CallSource,
|
||||||
pub feature: Option<Symbol>,
|
pub feature: Option<Symbol>,
|
||||||
|
@ -110,11 +110,11 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||||
ccx: &ConstCx<'_, 'tcx>,
|
ccx: &ConstCx<'_, 'tcx>,
|
||||||
_: Span,
|
_: Span,
|
||||||
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
||||||
let FnCallNonConst { caller, callee, substs, span, call_source, feature } = *self;
|
let FnCallNonConst { caller, callee, args, span, call_source, feature } = *self;
|
||||||
let ConstCx { tcx, param_env, .. } = *ccx;
|
let ConstCx { tcx, param_env, .. } = *ccx;
|
||||||
|
|
||||||
let diag_trait = |err, self_ty: Ty<'_>, trait_id| {
|
let diag_trait = |err, self_ty: Ty<'_>, trait_id| {
|
||||||
let trait_ref = TraitRef::from_method(tcx, trait_id, substs);
|
let trait_ref = TraitRef::from_method(tcx, trait_id, args);
|
||||||
|
|
||||||
match self_ty.kind() {
|
match self_ty.kind() {
|
||||||
Param(param_ty) => {
|
Param(param_ty) => {
|
||||||
|
@ -154,7 +154,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let call_kind =
|
let call_kind =
|
||||||
call_kind(tcx, ccx.param_env, callee, substs, span, call_source.from_hir_call(), None);
|
call_kind(tcx, ccx.param_env, callee, args, span, call_source.from_hir_call(), None);
|
||||||
|
|
||||||
debug!(?call_kind);
|
debug!(?call_kind);
|
||||||
|
|
||||||
|
@ -226,7 +226,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||||
let mut sugg = None;
|
let mut sugg = None;
|
||||||
|
|
||||||
if Some(trait_id) == ccx.tcx.lang_items().eq_trait() {
|
if Some(trait_id) == ccx.tcx.lang_items().eq_trait() {
|
||||||
match (substs[0].unpack(), substs[1].unpack()) {
|
match (args[0].unpack(), args[1].unpack()) {
|
||||||
(GenericArgKind::Type(self_ty), GenericArgKind::Type(rhs_ty))
|
(GenericArgKind::Type(self_ty), GenericArgKind::Type(rhs_ty))
|
||||||
if self_ty == rhs_ty
|
if self_ty == rhs_ty
|
||||||
&& self_ty.is_ref()
|
&& self_ty.is_ref()
|
||||||
|
@ -297,7 +297,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||||
.create_err(errors::NonConstFmtMacroCall { span, kind: ccx.const_kind() }),
|
.create_err(errors::NonConstFmtMacroCall { span, kind: ccx.const_kind() }),
|
||||||
_ => ccx.tcx.sess.create_err(errors::NonConstFnCall {
|
_ => ccx.tcx.sess.create_err(errors::NonConstFnCall {
|
||||||
span,
|
span,
|
||||||
def_path_str: ccx.tcx.def_path_str_with_substs(callee, substs),
|
def_path_str: ccx.tcx.def_path_str_with_args(callee, args),
|
||||||
kind: ccx.const_kind(),
|
kind: ccx.const_kind(),
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,7 +7,7 @@ use rustc_hir::LangItem;
|
||||||
use rustc_infer::infer::TyCtxtInferExt;
|
use rustc_infer::infer::TyCtxtInferExt;
|
||||||
use rustc_middle::mir;
|
use rustc_middle::mir;
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
use rustc_middle::ty::{self, subst::SubstsRef, AdtDef, Ty};
|
use rustc_middle::ty::{self, AdtDef, GenericArgsRef, Ty};
|
||||||
use rustc_trait_selection::traits::{
|
use rustc_trait_selection::traits::{
|
||||||
self, ImplSource, Obligation, ObligationCause, ObligationCtxt, SelectionContext,
|
self, ImplSource, Obligation, ObligationCause, ObligationCtxt, SelectionContext,
|
||||||
};
|
};
|
||||||
|
@ -72,7 +72,7 @@ pub trait Qualif {
|
||||||
fn in_adt_inherently<'tcx>(
|
fn in_adt_inherently<'tcx>(
|
||||||
cx: &ConstCx<'_, 'tcx>,
|
cx: &ConstCx<'_, 'tcx>,
|
||||||
adt: AdtDef<'tcx>,
|
adt: AdtDef<'tcx>,
|
||||||
substs: SubstsRef<'tcx>,
|
args: GenericArgsRef<'tcx>,
|
||||||
) -> bool;
|
) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ impl Qualif for HasMutInterior {
|
||||||
fn in_adt_inherently<'tcx>(
|
fn in_adt_inherently<'tcx>(
|
||||||
_cx: &ConstCx<'_, 'tcx>,
|
_cx: &ConstCx<'_, 'tcx>,
|
||||||
adt: AdtDef<'tcx>,
|
adt: AdtDef<'tcx>,
|
||||||
_: SubstsRef<'tcx>,
|
_: GenericArgsRef<'tcx>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
// Exactly one type, `UnsafeCell`, has the `HasMutInterior` qualif inherently.
|
// Exactly one type, `UnsafeCell`, has the `HasMutInterior` qualif inherently.
|
||||||
// It arises structurally for all other types.
|
// It arises structurally for all other types.
|
||||||
|
@ -127,7 +127,7 @@ impl Qualif for NeedsDrop {
|
||||||
fn in_adt_inherently<'tcx>(
|
fn in_adt_inherently<'tcx>(
|
||||||
cx: &ConstCx<'_, 'tcx>,
|
cx: &ConstCx<'_, 'tcx>,
|
||||||
adt: AdtDef<'tcx>,
|
adt: AdtDef<'tcx>,
|
||||||
_: SubstsRef<'tcx>,
|
_: GenericArgsRef<'tcx>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
adt.has_dtor(cx.tcx)
|
adt.has_dtor(cx.tcx)
|
||||||
}
|
}
|
||||||
|
@ -193,7 +193,7 @@ impl Qualif for NeedsNonConstDrop {
|
||||||
fn in_adt_inherently<'tcx>(
|
fn in_adt_inherently<'tcx>(
|
||||||
cx: &ConstCx<'_, 'tcx>,
|
cx: &ConstCx<'_, 'tcx>,
|
||||||
adt: AdtDef<'tcx>,
|
adt: AdtDef<'tcx>,
|
||||||
_: SubstsRef<'tcx>,
|
_: GenericArgsRef<'tcx>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
adt.has_non_const_dtor(cx.tcx)
|
adt.has_non_const_dtor(cx.tcx)
|
||||||
}
|
}
|
||||||
|
@ -221,9 +221,9 @@ impl Qualif for CustomEq {
|
||||||
fn in_adt_inherently<'tcx>(
|
fn in_adt_inherently<'tcx>(
|
||||||
cx: &ConstCx<'_, 'tcx>,
|
cx: &ConstCx<'_, 'tcx>,
|
||||||
def: AdtDef<'tcx>,
|
def: AdtDef<'tcx>,
|
||||||
substs: SubstsRef<'tcx>,
|
args: GenericArgsRef<'tcx>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let ty = Ty::new_adt(cx.tcx, def, substs);
|
let ty = Ty::new_adt(cx.tcx, def, args);
|
||||||
!ty.is_structural_eq_shallow(cx.tcx)
|
!ty.is_structural_eq_shallow(cx.tcx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -276,9 +276,9 @@ where
|
||||||
Rvalue::Aggregate(kind, operands) => {
|
Rvalue::Aggregate(kind, operands) => {
|
||||||
// Return early if we know that the struct or enum being constructed is always
|
// Return early if we know that the struct or enum being constructed is always
|
||||||
// qualified.
|
// qualified.
|
||||||
if let AggregateKind::Adt(adt_did, _, substs, ..) = **kind {
|
if let AggregateKind::Adt(adt_did, _, args, ..) = **kind {
|
||||||
let def = cx.tcx.adt_def(adt_did);
|
let def = cx.tcx.adt_def(adt_did);
|
||||||
if Q::in_adt_inherently(cx, def, substs) {
|
if Q::in_adt_inherently(cx, def, args) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if def.is_union() && Q::in_any_value_of_ty(cx, rvalue.ty(cx.body, cx.tcx)) {
|
if def.is_union() && Q::in_any_value_of_ty(cx, rvalue.ty(cx.body, cx.tcx)) {
|
||||||
|
@ -360,7 +360,7 @@ where
|
||||||
ConstantKind::Val(..) => None,
|
ConstantKind::Val(..) => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(mir::UnevaluatedConst { def, substs: _, promoted }) = uneval {
|
if let Some(mir::UnevaluatedConst { def, args: _, promoted }) = uneval {
|
||||||
// Use qualifs of the type for the promoted. Promoteds in MIR body should be possible
|
// Use qualifs of the type for the promoted. Promoteds in MIR body should be possible
|
||||||
// only for `NeedsNonConstDrop` with precise drop checking. This is the only const
|
// only for `NeedsNonConstDrop` with precise drop checking. This is the only const
|
||||||
// check performed after the promotion. Verify that with an assertion.
|
// check performed after the promotion. Verify that with an assertion.
|
||||||
|
|
|
@ -16,7 +16,7 @@ use rustc_hir as hir;
|
||||||
use rustc_middle::mir;
|
use rustc_middle::mir;
|
||||||
use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
|
use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
use rustc_middle::ty::subst::InternalSubsts;
|
use rustc_middle::ty::GenericArgs;
|
||||||
use rustc_middle::ty::{self, List, Ty, TyCtxt, TypeVisitableExt};
|
use rustc_middle::ty::{self, List, Ty, TyCtxt, TypeVisitableExt};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
|
@ -841,8 +841,8 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
||||||
let mut promoted_operand = |ty, span| {
|
let mut promoted_operand = |ty, span| {
|
||||||
promoted.span = span;
|
promoted.span = span;
|
||||||
promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span);
|
promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span);
|
||||||
let substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def));
|
let args = tcx.erase_regions(GenericArgs::identity_for_item(tcx, def));
|
||||||
let uneval = mir::UnevaluatedConst { def, substs, promoted: Some(promoted_id) };
|
let uneval = mir::UnevaluatedConst { def, args, promoted: Some(promoted_id) };
|
||||||
|
|
||||||
Operand::Constant(Box::new(Constant {
|
Operand::Constant(Box::new(Constant {
|
||||||
span,
|
span,
|
||||||
|
|
|
@ -358,8 +358,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let kind = match parent_ty.ty.kind() {
|
let kind = match parent_ty.ty.kind() {
|
||||||
&ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
|
&ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
|
||||||
self.tcx.type_of(def_id).subst(self.tcx, substs).kind()
|
self.tcx.type_of(def_id).instantiate(self.tcx, args).kind()
|
||||||
}
|
}
|
||||||
kind => kind,
|
kind => kind,
|
||||||
};
|
};
|
||||||
|
@ -372,23 +372,23 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||||
};
|
};
|
||||||
check_equal(self, location, *f_ty);
|
check_equal(self, location, *f_ty);
|
||||||
}
|
}
|
||||||
ty::Adt(adt_def, substs) => {
|
ty::Adt(adt_def, args) => {
|
||||||
let var = parent_ty.variant_index.unwrap_or(FIRST_VARIANT);
|
let var = parent_ty.variant_index.unwrap_or(FIRST_VARIANT);
|
||||||
let Some(field) = adt_def.variant(var).fields.get(f) else {
|
let Some(field) = adt_def.variant(var).fields.get(f) else {
|
||||||
fail_out_of_bounds(self, location);
|
fail_out_of_bounds(self, location);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
check_equal(self, location, field.ty(self.tcx, substs));
|
check_equal(self, location, field.ty(self.tcx, args));
|
||||||
}
|
}
|
||||||
ty::Closure(_, substs) => {
|
ty::Closure(_, args) => {
|
||||||
let substs = substs.as_closure();
|
let args = args.as_closure();
|
||||||
let Some(f_ty) = substs.upvar_tys().nth(f.as_usize()) else {
|
let Some(f_ty) = args.upvar_tys().nth(f.as_usize()) else {
|
||||||
fail_out_of_bounds(self, location);
|
fail_out_of_bounds(self, location);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
check_equal(self, location, f_ty);
|
check_equal(self, location, f_ty);
|
||||||
}
|
}
|
||||||
&ty::Generator(def_id, substs, _) => {
|
&ty::Generator(def_id, args, _) => {
|
||||||
let f_ty = if let Some(var) = parent_ty.variant_index {
|
let f_ty = if let Some(var) = parent_ty.variant_index {
|
||||||
let gen_body = if def_id == self.body.source.def_id() {
|
let gen_body = if def_id == self.body.source.def_id() {
|
||||||
self.body
|
self.body
|
||||||
|
@ -419,8 +419,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||||
|
|
||||||
f_ty.ty
|
f_ty.ty
|
||||||
} else {
|
} else {
|
||||||
let Some(f_ty) = substs.as_generator().prefix_tys().nth(f.index())
|
let Some(f_ty) = args.as_generator().prefix_tys().nth(f.index()) else {
|
||||||
else {
|
|
||||||
fail_out_of_bounds(self, location);
|
fail_out_of_bounds(self, location);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -735,7 +734,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||||
|
|
||||||
current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty);
|
current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty);
|
||||||
}
|
}
|
||||||
ty::Adt(adt_def, substs) => {
|
ty::Adt(adt_def, args) => {
|
||||||
if adt_def.is_enum() {
|
if adt_def.is_enum() {
|
||||||
self.fail(
|
self.fail(
|
||||||
location,
|
location,
|
||||||
|
@ -749,7 +748,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let f_ty = field.ty(self.tcx, substs);
|
let f_ty = field.ty(self.tcx, args);
|
||||||
current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty);
|
current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|
|
@ -4,8 +4,7 @@ use rustc_hir::definitions::DisambiguatedDefPathData;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self,
|
self,
|
||||||
print::{PrettyPrinter, Print, Printer},
|
print::{PrettyPrinter, Print, Printer},
|
||||||
subst::{GenericArg, GenericArgKind},
|
GenericArg, GenericArgKind, Ty, TyCtxt,
|
||||||
Ty, TyCtxt,
|
|
||||||
};
|
};
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
|
||||||
|
@ -56,11 +55,11 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Types with identity (print the module path).
|
// Types with identity (print the module path).
|
||||||
ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), substs)
|
ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), args)
|
||||||
| ty::FnDef(def_id, substs)
|
| ty::FnDef(def_id, args)
|
||||||
| ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, substs, .. })
|
| ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. })
|
||||||
| ty::Closure(def_id, substs)
|
| ty::Closure(def_id, args)
|
||||||
| ty::Generator(def_id, substs, _) => self.print_def_path(def_id, substs),
|
| ty::Generator(def_id, args, _) => self.print_def_path(def_id, args),
|
||||||
ty::Foreign(def_id) => self.print_def_path(def_id, &[]),
|
ty::Foreign(def_id) => self.print_def_path(def_id, &[]),
|
||||||
|
|
||||||
ty::Alias(ty::Weak, _) => bug!("type_name: unexpected weak projection"),
|
ty::Alias(ty::Weak, _) => bug!("type_name: unexpected weak projection"),
|
||||||
|
|
|
@ -812,7 +812,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
||||||
TEST, rustc_error, Normal,
|
TEST, rustc_error, Normal,
|
||||||
template!(Word, List: "delay_span_bug_from_inside_query"), WarnFollowingWordOnly
|
template!(Word, List: "delay_span_bug_from_inside_query"), WarnFollowingWordOnly
|
||||||
),
|
),
|
||||||
rustc_attr!(TEST, rustc_dump_user_substs, Normal, template!(Word), WarnFollowing),
|
rustc_attr!(TEST, rustc_dump_user_args, Normal, template!(Word), WarnFollowing),
|
||||||
rustc_attr!(TEST, rustc_evaluate_where_clauses, Normal, template!(Word), WarnFollowing),
|
rustc_attr!(TEST, rustc_evaluate_where_clauses, Normal, template!(Word), WarnFollowing),
|
||||||
rustc_attr!(
|
rustc_attr!(
|
||||||
TEST, rustc_if_this_changed, Normal, template!(Word, List: "DepNode"), DuplicatesOk
|
TEST, rustc_if_this_changed, Normal, template!(Word, List: "DepNode"), DuplicatesOk
|
||||||
|
|
|
@ -341,8 +341,8 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
||||||
// If we have an method return type bound, then we need to substitute
|
// If we have an method return type bound, then we need to substitute
|
||||||
// the method's early bound params with suitable late-bound params.
|
// the method's early bound params with suitable late-bound params.
|
||||||
let mut num_bound_vars = candidate.bound_vars().len();
|
let mut num_bound_vars = candidate.bound_vars().len();
|
||||||
let substs =
|
let args =
|
||||||
candidate.skip_binder().substs.extend_to(tcx, assoc_item.def_id, |param, _| {
|
candidate.skip_binder().args.extend_to(tcx, assoc_item.def_id, |param, _| {
|
||||||
let subst = match param.kind {
|
let subst = match param.kind {
|
||||||
ty::GenericParamDefKind::Lifetime => ty::Region::new_late_bound(
|
ty::GenericParamDefKind::Lifetime => ty::Region::new_late_bound(
|
||||||
tcx,
|
tcx,
|
||||||
|
@ -422,7 +422,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
||||||
// params (and trait ref's late bound params). This logic is very similar to
|
// params (and trait ref's late bound params). This logic is very similar to
|
||||||
// `Predicate::subst_supertrait`, and it's no coincidence why.
|
// `Predicate::subst_supertrait`, and it's no coincidence why.
|
||||||
let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output);
|
let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output);
|
||||||
let subst_output = ty::EarlyBinder::bind(shifted_output).subst(tcx, substs);
|
let subst_output = ty::EarlyBinder::bind(shifted_output).instantiate(tcx, args);
|
||||||
|
|
||||||
let bound_vars = tcx.late_bound_vars(binding.hir_id);
|
let bound_vars = tcx.late_bound_vars(binding.hir_id);
|
||||||
ty::Binder::bind_with_vars(subst_output, bound_vars)
|
ty::Binder::bind_with_vars(subst_output, bound_vars)
|
||||||
|
@ -438,16 +438,16 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
||||||
infer_args: false,
|
infer_args: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let substs_trait_ref_and_assoc_item = self.create_substs_for_associated_item(
|
let args_trait_ref_and_assoc_item = self.create_args_for_associated_item(
|
||||||
path_span,
|
path_span,
|
||||||
assoc_item.def_id,
|
assoc_item.def_id,
|
||||||
&item_segment,
|
&item_segment,
|
||||||
trait_ref.substs,
|
trait_ref.args,
|
||||||
);
|
);
|
||||||
|
|
||||||
debug!(?substs_trait_ref_and_assoc_item);
|
debug!(?args_trait_ref_and_assoc_item);
|
||||||
|
|
||||||
tcx.mk_alias_ty(assoc_item.def_id, substs_trait_ref_and_assoc_item)
|
tcx.mk_alias_ty(assoc_item.def_id, args_trait_ref_and_assoc_item)
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -533,7 +533,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
||||||
tcx,
|
tcx,
|
||||||
reported,
|
reported,
|
||||||
tcx.type_of(assoc_item_def_id)
|
tcx.type_of(assoc_item_def_id)
|
||||||
.subst(tcx, projection_ty.skip_binder().substs),
|
.instantiate(tcx, projection_ty.skip_binder().args),
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
|
|
@ -247,7 +247,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
"the candidate".into()
|
"the candidate".into()
|
||||||
};
|
};
|
||||||
|
|
||||||
let impl_ty = tcx.at(span).type_of(impl_).subst_identity();
|
let impl_ty = tcx.at(span).type_of(impl_).instantiate_identity();
|
||||||
let note = format!("{title} is defined in an impl for the type `{impl_ty}`");
|
let note = format!("{title} is defined in an impl for the type `{impl_ty}`");
|
||||||
|
|
||||||
if let Some(span) = note_span {
|
if let Some(span) = note_span {
|
||||||
|
@ -295,7 +295,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
let type_candidates = candidates
|
let type_candidates = candidates
|
||||||
.iter()
|
.iter()
|
||||||
.take(limit)
|
.take(limit)
|
||||||
.map(|&(impl_, _)| format!("- `{}`", tcx.at(span).type_of(impl_).subst_identity()))
|
.map(|&(impl_, _)| {
|
||||||
|
format!("- `{}`", tcx.at(span).type_of(impl_).instantiate_identity())
|
||||||
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join("\n");
|
.join("\n");
|
||||||
let additional_types = if candidates.len() > limit {
|
let additional_types = if candidates.len() > limit {
|
||||||
|
@ -356,13 +358,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
// `<Foo as Iterator>::Item = String`.
|
// `<Foo as Iterator>::Item = String`.
|
||||||
let projection_ty = pred.skip_binder().projection_ty;
|
let projection_ty = pred.skip_binder().projection_ty;
|
||||||
|
|
||||||
let substs_with_infer_self = tcx.mk_substs_from_iter(
|
let args_with_infer_self = tcx.mk_args_from_iter(
|
||||||
std::iter::once(Ty::new_var(tcx, ty::TyVid::from_u32(0)).into())
|
std::iter::once(Ty::new_var(tcx, ty::TyVid::from_u32(0)).into())
|
||||||
.chain(projection_ty.substs.iter().skip(1)),
|
.chain(projection_ty.args.iter().skip(1)),
|
||||||
);
|
);
|
||||||
|
|
||||||
let quiet_projection_ty =
|
let quiet_projection_ty =
|
||||||
tcx.mk_alias_ty(projection_ty.def_id, substs_with_infer_self);
|
tcx.mk_alias_ty(projection_ty.def_id, args_with_infer_self);
|
||||||
|
|
||||||
let term = pred.skip_binder().term;
|
let term = pred.skip_binder().term;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::GenericArg;
|
use rustc_hir::GenericArg;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, subst, subst::SubstsRef, GenericParamDef, GenericParamDefKind, IsSuggestable, Ty, TyCtxt,
|
self, GenericArgsRef, GenericParamDef, GenericParamDefKind, IsSuggestable, Ty, TyCtxt,
|
||||||
};
|
};
|
||||||
use rustc_session::lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS;
|
use rustc_session::lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS;
|
||||||
use rustc_span::{symbol::kw, Span};
|
use rustc_span::{symbol::kw, Span};
|
||||||
|
@ -76,7 +76,7 @@ fn generic_arg_mismatch_err(
|
||||||
Res::Def(DefKind::TyParam, src_def_id) => {
|
Res::Def(DefKind::TyParam, src_def_id) => {
|
||||||
if let Some(param_local_id) = param.def_id.as_local() {
|
if let Some(param_local_id) = param.def_id.as_local() {
|
||||||
let param_name = tcx.hir().ty_param_name(param_local_id);
|
let param_name = tcx.hir().ty_param_name(param_local_id);
|
||||||
let param_type = tcx.type_of(param.def_id).subst_identity();
|
let param_type = tcx.type_of(param.def_id).instantiate_identity();
|
||||||
if param_type.is_suggestable(tcx, false) {
|
if param_type.is_suggestable(tcx, false) {
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
tcx.def_span(src_def_id),
|
tcx.def_span(src_def_id),
|
||||||
|
@ -146,14 +146,14 @@ fn generic_arg_mismatch_err(
|
||||||
///
|
///
|
||||||
/// To start, we are given the `def_id` of the thing we are
|
/// To start, we are given the `def_id` of the thing we are
|
||||||
/// creating the substitutions for, and a partial set of
|
/// creating the substitutions for, and a partial set of
|
||||||
/// substitutions `parent_substs`. In general, the substitutions
|
/// substitutions `parent_args`. In general, the substitutions
|
||||||
/// for an item begin with substitutions for all the "parents" of
|
/// for an item begin with substitutions for all the "parents" of
|
||||||
/// that item -- e.g., for a method it might include the
|
/// that item -- e.g., for a method it might include the
|
||||||
/// parameters from the impl.
|
/// parameters from the impl.
|
||||||
///
|
///
|
||||||
/// Therefore, the method begins by walking down these parents,
|
/// Therefore, the method begins by walking down these parents,
|
||||||
/// starting with the outermost parent and proceed inwards until
|
/// starting with the outermost parent and proceed inwards until
|
||||||
/// it reaches `def_id`. For each parent `P`, it will check `parent_substs`
|
/// it reaches `def_id`. For each parent `P`, it will check `parent_args`
|
||||||
/// first to see if the parent's substitutions are listed in there. If so,
|
/// first to see if the parent's substitutions are listed in there. If so,
|
||||||
/// we can append those and move on. Otherwise, it invokes the
|
/// we can append those and move on. Otherwise, it invokes the
|
||||||
/// three callback functions:
|
/// three callback functions:
|
||||||
|
@ -168,15 +168,15 @@ fn generic_arg_mismatch_err(
|
||||||
/// instantiate a `GenericArg`.
|
/// instantiate a `GenericArg`.
|
||||||
/// - `inferred_kind`: if no parameter was provided, and inference is enabled, then
|
/// - `inferred_kind`: if no parameter was provided, and inference is enabled, then
|
||||||
/// creates a suitable inference variable.
|
/// creates a suitable inference variable.
|
||||||
pub fn create_substs_for_generic_args<'tcx, 'a>(
|
pub fn create_args_for_parent_generic_args<'tcx, 'a>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
parent_substs: &[subst::GenericArg<'tcx>],
|
parent_args: &[ty::GenericArg<'tcx>],
|
||||||
has_self: bool,
|
has_self: bool,
|
||||||
self_ty: Option<Ty<'tcx>>,
|
self_ty: Option<Ty<'tcx>>,
|
||||||
arg_count: &GenericArgCountResult,
|
arg_count: &GenericArgCountResult,
|
||||||
ctx: &mut impl CreateSubstsForGenericArgsCtxt<'a, 'tcx>,
|
ctx: &mut impl CreateSubstsForGenericArgsCtxt<'a, 'tcx>,
|
||||||
) -> SubstsRef<'tcx> {
|
) -> GenericArgsRef<'tcx> {
|
||||||
// Collect the segments of the path; we need to substitute arguments
|
// Collect the segments of the path; we need to substitute arguments
|
||||||
// for parameters throughout the entire path (wherever there are
|
// for parameters throughout the entire path (wherever there are
|
||||||
// generic parameters).
|
// generic parameters).
|
||||||
|
@ -191,27 +191,27 @@ pub fn create_substs_for_generic_args<'tcx, 'a>(
|
||||||
// We manually build up the substitution, rather than using convenience
|
// We manually build up the substitution, rather than using convenience
|
||||||
// methods in `subst.rs`, so that we can iterate over the arguments and
|
// methods in `subst.rs`, so that we can iterate over the arguments and
|
||||||
// parameters in lock-step linearly, instead of trying to match each pair.
|
// parameters in lock-step linearly, instead of trying to match each pair.
|
||||||
let mut substs: SmallVec<[subst::GenericArg<'tcx>; 8]> = SmallVec::with_capacity(count);
|
let mut args: SmallVec<[ty::GenericArg<'tcx>; 8]> = SmallVec::with_capacity(count);
|
||||||
// Iterate over each segment of the path.
|
// Iterate over each segment of the path.
|
||||||
while let Some((def_id, defs)) = stack.pop() {
|
while let Some((def_id, defs)) = stack.pop() {
|
||||||
let mut params = defs.params.iter().peekable();
|
let mut params = defs.params.iter().peekable();
|
||||||
|
|
||||||
// If we have already computed substitutions for parents, we can use those directly.
|
// If we have already computed substitutions for parents, we can use those directly.
|
||||||
while let Some(¶m) = params.peek() {
|
while let Some(¶m) = params.peek() {
|
||||||
if let Some(&kind) = parent_substs.get(param.index as usize) {
|
if let Some(&kind) = parent_args.get(param.index as usize) {
|
||||||
substs.push(kind);
|
args.push(kind);
|
||||||
params.next();
|
params.next();
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// `Self` is handled first, unless it's been handled in `parent_substs`.
|
// `Self` is handled first, unless it's been handled in `parent_args`.
|
||||||
if has_self {
|
if has_self {
|
||||||
if let Some(¶m) = params.peek() {
|
if let Some(¶m) = params.peek() {
|
||||||
if param.index == 0 {
|
if param.index == 0 {
|
||||||
if let GenericParamDefKind::Type { .. } = param.kind {
|
if let GenericParamDefKind::Type { .. } = param.kind {
|
||||||
substs.push(
|
args.push(
|
||||||
self_ty
|
self_ty
|
||||||
.map(|ty| ty.into())
|
.map(|ty| ty.into())
|
||||||
.unwrap_or_else(|| ctx.inferred_kind(None, param, true)),
|
.unwrap_or_else(|| ctx.inferred_kind(None, param, true)),
|
||||||
|
@ -226,7 +226,7 @@ pub fn create_substs_for_generic_args<'tcx, 'a>(
|
||||||
let (generic_args, infer_args) = ctx.args_for_def_id(def_id);
|
let (generic_args, infer_args) = ctx.args_for_def_id(def_id);
|
||||||
|
|
||||||
let args_iter = generic_args.iter().flat_map(|generic_args| generic_args.args.iter());
|
let args_iter = generic_args.iter().flat_map(|generic_args| generic_args.args.iter());
|
||||||
let mut args = args_iter.clone().peekable();
|
let mut args_iter = args_iter.clone().peekable();
|
||||||
|
|
||||||
// If we encounter a type or const when we expect a lifetime, we infer the lifetimes.
|
// If we encounter a type or const when we expect a lifetime, we infer the lifetimes.
|
||||||
// If we later encounter a lifetime, we know that the arguments were provided in the
|
// If we later encounter a lifetime, we know that the arguments were provided in the
|
||||||
|
@ -239,7 +239,7 @@ pub fn create_substs_for_generic_args<'tcx, 'a>(
|
||||||
// provided, matching them with the generic parameters we expect.
|
// provided, matching them with the generic parameters we expect.
|
||||||
// Mismatches can occur as a result of elided lifetimes, or for malformed
|
// Mismatches can occur as a result of elided lifetimes, or for malformed
|
||||||
// input. We try to handle both sensibly.
|
// input. We try to handle both sensibly.
|
||||||
match (args.peek(), params.peek()) {
|
match (args_iter.peek(), params.peek()) {
|
||||||
(Some(&arg), Some(¶m)) => {
|
(Some(&arg), Some(¶m)) => {
|
||||||
match (arg, ¶m.kind, arg_count.explicit_late_bound) {
|
match (arg, ¶m.kind, arg_count.explicit_late_bound) {
|
||||||
(GenericArg::Lifetime(_), GenericParamDefKind::Lifetime, _)
|
(GenericArg::Lifetime(_), GenericParamDefKind::Lifetime, _)
|
||||||
|
@ -253,8 +253,8 @@ pub fn create_substs_for_generic_args<'tcx, 'a>(
|
||||||
GenericParamDefKind::Const { .. },
|
GenericParamDefKind::Const { .. },
|
||||||
_,
|
_,
|
||||||
) => {
|
) => {
|
||||||
substs.push(ctx.provided_kind(param, arg));
|
args.push(ctx.provided_kind(param, arg));
|
||||||
args.next();
|
args_iter.next();
|
||||||
params.next();
|
params.next();
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
|
@ -264,7 +264,7 @@ pub fn create_substs_for_generic_args<'tcx, 'a>(
|
||||||
) => {
|
) => {
|
||||||
// We expected a lifetime argument, but got a type or const
|
// We expected a lifetime argument, but got a type or const
|
||||||
// argument. That means we're inferring the lifetimes.
|
// argument. That means we're inferring the lifetimes.
|
||||||
substs.push(ctx.inferred_kind(None, param, infer_args));
|
args.push(ctx.inferred_kind(None, param, infer_args));
|
||||||
force_infer_lt = Some((arg, param));
|
force_infer_lt = Some((arg, param));
|
||||||
params.next();
|
params.next();
|
||||||
}
|
}
|
||||||
|
@ -273,7 +273,7 @@ pub fn create_substs_for_generic_args<'tcx, 'a>(
|
||||||
// the presence of explicit late bounds. This is most likely
|
// the presence of explicit late bounds. This is most likely
|
||||||
// due to the presence of the explicit bound so we're just going to
|
// due to the presence of the explicit bound so we're just going to
|
||||||
// ignore it.
|
// ignore it.
|
||||||
args.next();
|
args_iter.next();
|
||||||
}
|
}
|
||||||
(_, _, _) => {
|
(_, _, _) => {
|
||||||
// We expected one kind of parameter, but the user provided
|
// We expected one kind of parameter, but the user provided
|
||||||
|
@ -327,7 +327,7 @@ pub fn create_substs_for_generic_args<'tcx, 'a>(
|
||||||
// errors. In this case, we're simply going to ignore the argument
|
// errors. In this case, we're simply going to ignore the argument
|
||||||
// and any following arguments. The rest of the parameters will be
|
// and any following arguments. The rest of the parameters will be
|
||||||
// inferred.
|
// inferred.
|
||||||
while args.next().is_some() {}
|
while args_iter.next().is_some() {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -360,7 +360,7 @@ pub fn create_substs_for_generic_args<'tcx, 'a>(
|
||||||
(None, Some(¶m)) => {
|
(None, Some(¶m)) => {
|
||||||
// If there are fewer arguments than parameters, it means
|
// If there are fewer arguments than parameters, it means
|
||||||
// we're inferring the remaining arguments.
|
// we're inferring the remaining arguments.
|
||||||
substs.push(ctx.inferred_kind(Some(&substs), param, infer_args));
|
args.push(ctx.inferred_kind(Some(&args), param, infer_args));
|
||||||
params.next();
|
params.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,7 +369,7 @@ pub fn create_substs_for_generic_args<'tcx, 'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tcx.mk_substs(&substs)
|
tcx.mk_args(&args)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks that the correct number of generic arguments have been provided.
|
/// Checks that the correct number of generic arguments have been provided.
|
||||||
|
|
|
@ -9,7 +9,7 @@ mod lint;
|
||||||
mod object_safety;
|
mod object_safety;
|
||||||
|
|
||||||
use crate::astconv::errors::prohibit_assoc_ty_binding;
|
use crate::astconv::errors::prohibit_assoc_ty_binding;
|
||||||
use crate::astconv::generics::{check_generic_arg_count, create_substs_for_generic_args};
|
use crate::astconv::generics::{check_generic_arg_count, create_args_for_parent_generic_args};
|
||||||
use crate::bounds::Bounds;
|
use crate::bounds::Bounds;
|
||||||
use crate::collect::HirPlaceholderCollector;
|
use crate::collect::HirPlaceholderCollector;
|
||||||
use crate::errors::{AmbiguousLifetimeBound, TypeofReservedKeywordUsed};
|
use crate::errors::{AmbiguousLifetimeBound, TypeofReservedKeywordUsed};
|
||||||
|
@ -29,9 +29,10 @@ use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
|
||||||
use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
|
use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
|
||||||
use rustc_infer::traits::ObligationCause;
|
use rustc_infer::traits::ObligationCause;
|
||||||
use rustc_middle::middle::stability::AllowUnstable;
|
use rustc_middle::middle::stability::AllowUnstable;
|
||||||
use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef};
|
|
||||||
use rustc_middle::ty::GenericParamDefKind;
|
use rustc_middle::ty::GenericParamDefKind;
|
||||||
use rustc_middle::ty::{self, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
|
use rustc_middle::ty::{
|
||||||
|
self, Const, GenericArgKind, GenericArgsRef, IsSuggestable, Ty, TyCtxt, TypeVisitableExt,
|
||||||
|
};
|
||||||
use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
|
use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
|
||||||
use rustc_span::edit_distance::find_best_match_for_name;
|
use rustc_span::edit_distance::find_best_match_for_name;
|
||||||
use rustc_span::symbol::{kw, Ident, Symbol};
|
use rustc_span::symbol::{kw, Ident, Symbol};
|
||||||
|
@ -220,14 +221,14 @@ pub trait CreateSubstsForGenericArgsCtxt<'a, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
param: &ty::GenericParamDef,
|
param: &ty::GenericParamDef,
|
||||||
arg: &GenericArg<'_>,
|
arg: &GenericArg<'_>,
|
||||||
) -> subst::GenericArg<'tcx>;
|
) -> ty::GenericArg<'tcx>;
|
||||||
|
|
||||||
fn inferred_kind(
|
fn inferred_kind(
|
||||||
&mut self,
|
&mut self,
|
||||||
substs: Option<&[subst::GenericArg<'tcx>]>,
|
args: Option<&[ty::GenericArg<'tcx>]>,
|
||||||
param: &ty::GenericParamDef,
|
param: &ty::GenericParamDef,
|
||||||
infer_args: bool,
|
infer_args: bool,
|
||||||
) -> subst::GenericArg<'tcx>;
|
) -> ty::GenericArg<'tcx>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
|
@ -291,13 +292,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
|
|
||||||
/// Given a path `path` that refers to an item `I` with the declared generics `decl_generics`,
|
/// Given a path `path` that refers to an item `I` with the declared generics `decl_generics`,
|
||||||
/// returns an appropriate set of substitutions for this particular reference to `I`.
|
/// returns an appropriate set of substitutions for this particular reference to `I`.
|
||||||
pub fn ast_path_substs_for_ty(
|
pub fn ast_path_args_for_ty(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
item_segment: &hir::PathSegment<'_>,
|
item_segment: &hir::PathSegment<'_>,
|
||||||
) -> SubstsRef<'tcx> {
|
) -> GenericArgsRef<'tcx> {
|
||||||
let (substs, _) = self.create_substs_for_ast_path(
|
let (args, _) = self.create_args_for_ast_path(
|
||||||
span,
|
span,
|
||||||
def_id,
|
def_id,
|
||||||
&[],
|
&[],
|
||||||
|
@ -311,7 +312,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
prohibit_assoc_ty_binding(self.tcx(), b.span, Some((item_segment, span)));
|
prohibit_assoc_ty_binding(self.tcx(), b.span, Some((item_segment, span)));
|
||||||
}
|
}
|
||||||
|
|
||||||
substs
|
args
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given the type/lifetime/const arguments provided to some path (along with
|
/// Given the type/lifetime/const arguments provided to some path (along with
|
||||||
|
@ -330,7 +331,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
/// 2. The path in question is the path to the trait `std::ops::Index`,
|
/// 2. The path in question is the path to the trait `std::ops::Index`,
|
||||||
/// which will have been resolved to a `def_id`
|
/// which will have been resolved to a `def_id`
|
||||||
/// 3. The `generic_args` contains info on the `<...>` contents. The `usize` type
|
/// 3. The `generic_args` contains info on the `<...>` contents. The `usize` type
|
||||||
/// parameters are returned in the `SubstsRef`, the associated type bindings like
|
/// parameters are returned in the `GenericArgsRef`, the associated type bindings like
|
||||||
/// `Output = u32` are returned from `create_assoc_bindings_for_generic_args`.
|
/// `Output = u32` are returned from `create_assoc_bindings_for_generic_args`.
|
||||||
///
|
///
|
||||||
/// Note that the type listing given here is *exactly* what the user provided.
|
/// Note that the type listing given here is *exactly* what the user provided.
|
||||||
|
@ -341,22 +342,22 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
/// <Vec<u8> as Iterable<u8>>::Iter::<'a>
|
/// <Vec<u8> as Iterable<u8>>::Iter::<'a>
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// We have the parent substs are the substs for the parent trait:
|
/// We have the parent args are the args for the parent trait:
|
||||||
/// `[Vec<u8>, u8]` and `generic_args` are the arguments for the associated
|
/// `[Vec<u8>, u8]` and `generic_args` are the arguments for the associated
|
||||||
/// type itself: `['a]`. The returned `SubstsRef` concatenates these two
|
/// type itself: `['a]`. The returned `GenericArgsRef` concatenates these two
|
||||||
/// lists: `[Vec<u8>, u8, 'a]`.
|
/// lists: `[Vec<u8>, u8, 'a]`.
|
||||||
#[instrument(level = "debug", skip(self, span), ret)]
|
#[instrument(level = "debug", skip(self, span), ret)]
|
||||||
fn create_substs_for_ast_path<'a>(
|
fn create_args_for_ast_path<'a>(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
parent_substs: &[subst::GenericArg<'tcx>],
|
parent_args: &[ty::GenericArg<'tcx>],
|
||||||
seg: &hir::PathSegment<'_>,
|
seg: &hir::PathSegment<'_>,
|
||||||
generic_args: &'a hir::GenericArgs<'_>,
|
generic_args: &'a hir::GenericArgs<'_>,
|
||||||
infer_args: bool,
|
infer_args: bool,
|
||||||
self_ty: Option<Ty<'tcx>>,
|
self_ty: Option<Ty<'tcx>>,
|
||||||
constness: ty::BoundConstness,
|
constness: ty::BoundConstness,
|
||||||
) -> (SubstsRef<'tcx>, GenericArgCountResult) {
|
) -> (GenericArgsRef<'tcx>, GenericArgCountResult) {
|
||||||
// If the type is parameterized by this region, then replace this
|
// If the type is parameterized by this region, then replace this
|
||||||
// region with the current anon region binding (in other words,
|
// region with the current anon region binding (in other words,
|
||||||
// whatever & would get replaced with).
|
// whatever & would get replaced with).
|
||||||
|
@ -369,7 +370,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
if generics.parent.is_some() {
|
if generics.parent.is_some() {
|
||||||
// The parent is a trait so it should have at least one subst
|
// The parent is a trait so it should have at least one subst
|
||||||
// for the `Self` type.
|
// for the `Self` type.
|
||||||
assert!(!parent_substs.is_empty())
|
assert!(!parent_args.is_empty())
|
||||||
} else {
|
} else {
|
||||||
// This item (presumably a trait) needs a self-type.
|
// This item (presumably a trait) needs a self-type.
|
||||||
assert!(self_ty.is_some());
|
assert!(self_ty.is_some());
|
||||||
|
@ -395,7 +396,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
// here and so associated type bindings will be handled regardless of whether there are any
|
// here and so associated type bindings will be handled regardless of whether there are any
|
||||||
// non-`Self` generic parameters.
|
// non-`Self` generic parameters.
|
||||||
if generics.params.is_empty() {
|
if generics.params.is_empty() {
|
||||||
return (tcx.mk_substs(parent_substs), arg_count);
|
return (tcx.mk_args(parent_args), arg_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SubstsForAstPathCtxt<'a, 'tcx> {
|
struct SubstsForAstPathCtxt<'a, 'tcx> {
|
||||||
|
@ -421,7 +422,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
&mut self,
|
&mut self,
|
||||||
param: &ty::GenericParamDef,
|
param: &ty::GenericParamDef,
|
||||||
arg: &GenericArg<'_>,
|
arg: &GenericArg<'_>,
|
||||||
) -> subst::GenericArg<'tcx> {
|
) -> ty::GenericArg<'tcx> {
|
||||||
let tcx = self.astconv.tcx();
|
let tcx = self.astconv.tcx();
|
||||||
|
|
||||||
let mut handle_ty_args = |has_default, ty: &hir::Ty<'_>| {
|
let mut handle_ty_args = |has_default, ty: &hir::Ty<'_>| {
|
||||||
|
@ -483,10 +484,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
|
|
||||||
fn inferred_kind(
|
fn inferred_kind(
|
||||||
&mut self,
|
&mut self,
|
||||||
substs: Option<&[subst::GenericArg<'tcx>]>,
|
args: Option<&[ty::GenericArg<'tcx>]>,
|
||||||
param: &ty::GenericParamDef,
|
param: &ty::GenericParamDef,
|
||||||
infer_args: bool,
|
infer_args: bool,
|
||||||
) -> subst::GenericArg<'tcx> {
|
) -> ty::GenericArg<'tcx> {
|
||||||
let tcx = self.astconv.tcx();
|
let tcx = self.astconv.tcx();
|
||||||
match param.kind {
|
match param.kind {
|
||||||
GenericParamDefKind::Lifetime => self
|
GenericParamDefKind::Lifetime => self
|
||||||
|
@ -506,15 +507,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
GenericParamDefKind::Type { has_default, .. } => {
|
GenericParamDefKind::Type { has_default, .. } => {
|
||||||
if !infer_args && has_default {
|
if !infer_args && has_default {
|
||||||
// No type parameter provided, but a default exists.
|
// No type parameter provided, but a default exists.
|
||||||
let substs = substs.unwrap();
|
let args = args.unwrap();
|
||||||
if substs.iter().any(|arg| match arg.unpack() {
|
if args.iter().any(|arg| match arg.unpack() {
|
||||||
GenericArgKind::Type(ty) => ty.references_error(),
|
GenericArgKind::Type(ty) => ty.references_error(),
|
||||||
_ => false,
|
_ => false,
|
||||||
}) {
|
}) {
|
||||||
// Avoid ICE #86756 when type error recovery goes awry.
|
// Avoid ICE #86756 when type error recovery goes awry.
|
||||||
return Ty::new_misc_error(tcx).into();
|
return Ty::new_misc_error(tcx).into();
|
||||||
}
|
}
|
||||||
tcx.at(self.span).type_of(param.def_id).subst(tcx, substs).into()
|
tcx.at(self.span).type_of(param.def_id).instantiate(tcx, args).into()
|
||||||
} else if infer_args {
|
} else if infer_args {
|
||||||
self.astconv.ty_infer(Some(param), self.span).into()
|
self.astconv.ty_infer(Some(param), self.span).into()
|
||||||
} else {
|
} else {
|
||||||
|
@ -532,7 +533,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
return ty::Const::new_error(tcx, guar, ty).into();
|
return ty::Const::new_error(tcx, guar, ty).into();
|
||||||
}
|
}
|
||||||
if !infer_args && has_default {
|
if !infer_args && has_default {
|
||||||
tcx.const_param_default(param.def_id).subst(tcx, substs.unwrap()).into()
|
tcx.const_param_default(param.def_id)
|
||||||
|
.instantiate(tcx, args.unwrap())
|
||||||
|
.into()
|
||||||
} else {
|
} else {
|
||||||
if infer_args {
|
if infer_args {
|
||||||
self.astconv.ct_infer(ty, Some(param), self.span).into()
|
self.astconv.ct_infer(ty, Some(param), self.span).into()
|
||||||
|
@ -546,7 +549,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut substs_ctx = SubstsForAstPathCtxt {
|
let mut args_ctx = SubstsForAstPathCtxt {
|
||||||
astconv: self,
|
astconv: self,
|
||||||
def_id,
|
def_id,
|
||||||
span,
|
span,
|
||||||
|
@ -554,14 +557,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
inferred_params: vec![],
|
inferred_params: vec![],
|
||||||
infer_args,
|
infer_args,
|
||||||
};
|
};
|
||||||
let substs = create_substs_for_generic_args(
|
let args = create_args_for_parent_generic_args(
|
||||||
tcx,
|
tcx,
|
||||||
def_id,
|
def_id,
|
||||||
parent_substs,
|
parent_args,
|
||||||
self_ty.is_some(),
|
self_ty.is_some(),
|
||||||
self_ty,
|
self_ty,
|
||||||
&arg_count,
|
&arg_count,
|
||||||
&mut substs_ctx,
|
&mut args_ctx,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let ty::BoundConstness::ConstIfConst = constness
|
if let ty::BoundConstness::ConstIfConst = constness
|
||||||
|
@ -570,7 +573,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
tcx.sess.emit_err(crate::errors::ConstBoundForNonConstTrait { span } );
|
tcx.sess.emit_err(crate::errors::ConstBoundForNonConstTrait { span } );
|
||||||
}
|
}
|
||||||
|
|
||||||
(substs, arg_count)
|
(args, arg_count)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_assoc_bindings_for_generic_args<'a>(
|
fn create_assoc_bindings_for_generic_args<'a>(
|
||||||
|
@ -617,21 +620,21 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
assoc_bindings
|
assoc_bindings
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_substs_for_associated_item(
|
pub fn create_args_for_associated_item(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
item_def_id: DefId,
|
item_def_id: DefId,
|
||||||
item_segment: &hir::PathSegment<'_>,
|
item_segment: &hir::PathSegment<'_>,
|
||||||
parent_substs: SubstsRef<'tcx>,
|
parent_args: GenericArgsRef<'tcx>,
|
||||||
) -> SubstsRef<'tcx> {
|
) -> GenericArgsRef<'tcx> {
|
||||||
debug!(
|
debug!(
|
||||||
"create_substs_for_associated_item(span: {:?}, item_def_id: {:?}, item_segment: {:?}",
|
"create_args_for_associated_item(span: {:?}, item_def_id: {:?}, item_segment: {:?}",
|
||||||
span, item_def_id, item_segment
|
span, item_def_id, item_segment
|
||||||
);
|
);
|
||||||
let (args, _) = self.create_substs_for_ast_path(
|
let (args, _) = self.create_args_for_ast_path(
|
||||||
span,
|
span,
|
||||||
item_def_id,
|
item_def_id,
|
||||||
parent_substs,
|
parent_args,
|
||||||
item_segment,
|
item_segment,
|
||||||
item_segment.args(),
|
item_segment.args(),
|
||||||
item_segment.infer_args,
|
item_segment.infer_args,
|
||||||
|
@ -687,7 +690,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
self_ty: Ty<'tcx>,
|
self_ty: Ty<'tcx>,
|
||||||
only_self_bounds: OnlySelfBounds,
|
only_self_bounds: OnlySelfBounds,
|
||||||
) -> GenericArgCountResult {
|
) -> GenericArgCountResult {
|
||||||
let (substs, arg_count) = self.create_substs_for_ast_path(
|
let (generic_args, arg_count) = self.create_args_for_ast_path(
|
||||||
trait_ref_span,
|
trait_ref_span,
|
||||||
trait_def_id,
|
trait_def_id,
|
||||||
&[],
|
&[],
|
||||||
|
@ -704,8 +707,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
|
|
||||||
let assoc_bindings = self.create_assoc_bindings_for_generic_args(args);
|
let assoc_bindings = self.create_assoc_bindings_for_generic_args(args);
|
||||||
|
|
||||||
let poly_trait_ref =
|
let poly_trait_ref = ty::Binder::bind_with_vars(
|
||||||
ty::Binder::bind_with_vars(ty::TraitRef::new(tcx, trait_def_id, substs), bound_vars);
|
ty::TraitRef::new(tcx, trait_def_id, generic_args),
|
||||||
|
bound_vars,
|
||||||
|
);
|
||||||
|
|
||||||
debug!(?poly_trait_ref, ?assoc_bindings);
|
debug!(?poly_trait_ref, ?assoc_bindings);
|
||||||
bounds.push_trait_bound(tcx, poly_trait_ref, span, constness, polarity);
|
bounds.push_trait_bound(tcx, poly_trait_ref, span, constness, polarity);
|
||||||
|
@ -846,7 +851,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
is_impl: bool,
|
is_impl: bool,
|
||||||
constness: ty::BoundConstness,
|
constness: ty::BoundConstness,
|
||||||
) -> ty::TraitRef<'tcx> {
|
) -> ty::TraitRef<'tcx> {
|
||||||
let (substs, _) = self.create_substs_for_ast_trait_ref(
|
let (generic_args, _) = self.create_args_for_ast_trait_ref(
|
||||||
span,
|
span,
|
||||||
trait_def_id,
|
trait_def_id,
|
||||||
self_ty,
|
self_ty,
|
||||||
|
@ -857,11 +862,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
if let Some(b) = trait_segment.args().bindings.first() {
|
if let Some(b) = trait_segment.args().bindings.first() {
|
||||||
prohibit_assoc_ty_binding(self.tcx(), b.span, Some((trait_segment, span)));
|
prohibit_assoc_ty_binding(self.tcx(), b.span, Some((trait_segment, span)));
|
||||||
}
|
}
|
||||||
ty::TraitRef::new(self.tcx(), trait_def_id, substs)
|
ty::TraitRef::new(self.tcx(), trait_def_id, generic_args)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self, span))]
|
#[instrument(level = "debug", skip(self, span))]
|
||||||
fn create_substs_for_ast_trait_ref<'a>(
|
fn create_args_for_ast_trait_ref<'a>(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
trait_def_id: DefId,
|
trait_def_id: DefId,
|
||||||
|
@ -869,10 +874,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
trait_segment: &'a hir::PathSegment<'a>,
|
trait_segment: &'a hir::PathSegment<'a>,
|
||||||
is_impl: bool,
|
is_impl: bool,
|
||||||
constness: ty::BoundConstness,
|
constness: ty::BoundConstness,
|
||||||
) -> (SubstsRef<'tcx>, GenericArgCountResult) {
|
) -> (GenericArgsRef<'tcx>, GenericArgCountResult) {
|
||||||
self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, is_impl);
|
self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, is_impl);
|
||||||
|
|
||||||
self.create_substs_for_ast_path(
|
self.create_args_for_ast_path(
|
||||||
span,
|
span,
|
||||||
trait_def_id,
|
trait_def_id,
|
||||||
&[],
|
&[],
|
||||||
|
@ -902,7 +907,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
did: DefId,
|
did: DefId,
|
||||||
item_segment: &hir::PathSegment<'_>,
|
item_segment: &hir::PathSegment<'_>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
let substs = self.ast_path_substs_for_ty(span, did, item_segment);
|
let args = self.ast_path_args_for_ty(span, did, item_segment);
|
||||||
let ty = self.tcx().at(span).type_of(did);
|
let ty = self.tcx().at(span).type_of(did);
|
||||||
|
|
||||||
if matches!(self.tcx().def_kind(did), DefKind::TyAlias)
|
if matches!(self.tcx().def_kind(did), DefKind::TyAlias)
|
||||||
|
@ -911,10 +916,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
// Type aliases referring to types that contain opaque types (but aren't just directly
|
// Type aliases referring to types that contain opaque types (but aren't just directly
|
||||||
// referencing a single opaque type) get encoded as a type alias that normalization will
|
// referencing a single opaque type) get encoded as a type alias that normalization will
|
||||||
// then actually instantiate the where bounds of.
|
// then actually instantiate the where bounds of.
|
||||||
let alias_ty = self.tcx().mk_alias_ty(did, substs);
|
let alias_ty = self.tcx().mk_alias_ty(did, args);
|
||||||
Ty::new_alias(self.tcx(), ty::Weak, alias_ty)
|
Ty::new_alias(self.tcx(), ty::Weak, alias_ty)
|
||||||
} else {
|
} else {
|
||||||
ty.subst(self.tcx(), substs)
|
ty.instantiate(self.tcx(), args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1383,7 +1388,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
};
|
};
|
||||||
|
|
||||||
self.one_bound_for_assoc_type(
|
self.one_bound_for_assoc_type(
|
||||||
|| traits::supertraits(tcx, ty::Binder::dummy(trait_ref.subst_identity())),
|
|| {
|
||||||
|
traits::supertraits(
|
||||||
|
tcx,
|
||||||
|
ty::Binder::dummy(trait_ref.instantiate_identity()),
|
||||||
|
)
|
||||||
|
},
|
||||||
kw::SelfUpper,
|
kw::SelfUpper,
|
||||||
assoc_ident,
|
assoc_ident,
|
||||||
span,
|
span,
|
||||||
|
@ -1620,8 +1630,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
let ocx = ObligationCtxt::new(&infcx);
|
let ocx = ObligationCtxt::new(&infcx);
|
||||||
ocx.register_obligations(obligations.clone());
|
ocx.register_obligations(obligations.clone());
|
||||||
|
|
||||||
let impl_substs = infcx.fresh_substs_for_item(span, impl_);
|
let impl_args = infcx.fresh_args_for_item(span, impl_);
|
||||||
let impl_ty = tcx.type_of(impl_).subst(tcx, impl_substs);
|
let impl_ty = tcx.type_of(impl_).instantiate(tcx, impl_args);
|
||||||
let impl_ty = ocx.normalize(&cause, param_env, impl_ty);
|
let impl_ty = ocx.normalize(&cause, param_env, impl_ty);
|
||||||
|
|
||||||
// Check that the self types can be related.
|
// Check that the self types can be related.
|
||||||
|
@ -1633,7 +1643,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether the impl imposes obligations we have to worry about.
|
// Check whether the impl imposes obligations we have to worry about.
|
||||||
let impl_bounds = tcx.predicates_of(impl_).instantiate(tcx, impl_substs);
|
let impl_bounds = tcx.predicates_of(impl_).instantiate(tcx, impl_args);
|
||||||
let impl_bounds = ocx.normalize(&cause, param_env, impl_bounds);
|
let impl_bounds = ocx.normalize(&cause, param_env, impl_bounds);
|
||||||
let impl_obligations = traits::predicates_for_generics(
|
let impl_obligations = traits::predicates_for_generics(
|
||||||
|_, _| cause.clone(),
|
|_, _| cause.clone(),
|
||||||
|
@ -1665,18 +1675,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
if let Some((impl_, (assoc_item, def_scope))) = applicable_candidates.pop() {
|
if let Some((impl_, (assoc_item, def_scope))) = applicable_candidates.pop() {
|
||||||
self.check_assoc_ty(assoc_item, name, def_scope, block, span);
|
self.check_assoc_ty(assoc_item, name, def_scope, block, span);
|
||||||
|
|
||||||
// FIXME(fmease): Currently creating throwaway `parent_substs` to please
|
// FIXME(fmease): Currently creating throwaway `parent_args` to please
|
||||||
// `create_substs_for_associated_item`. Modify the latter instead (or sth. similar) to
|
// `create_args_for_associated_item`. Modify the latter instead (or sth. similar) to
|
||||||
// not require the parent substs logic.
|
// not require the parent args logic.
|
||||||
let parent_substs = InternalSubsts::identity_for_item(tcx, impl_);
|
let parent_args = ty::GenericArgs::identity_for_item(tcx, impl_);
|
||||||
let substs =
|
let args = self.create_args_for_associated_item(span, assoc_item, segment, parent_args);
|
||||||
self.create_substs_for_associated_item(span, assoc_item, segment, parent_substs);
|
let args = tcx.mk_args_from_iter(
|
||||||
let substs = tcx.mk_substs_from_iter(
|
|
||||||
std::iter::once(ty::GenericArg::from(self_ty))
|
std::iter::once(ty::GenericArg::from(self_ty))
|
||||||
.chain(substs.into_iter().skip(parent_substs.len())),
|
.chain(args.into_iter().skip(parent_args.len())),
|
||||||
);
|
);
|
||||||
|
|
||||||
let ty = Ty::new_alias(tcx, ty::Inherent, tcx.mk_alias_ty(assoc_item, substs));
|
let ty = Ty::new_alias(tcx, ty::Inherent, tcx.mk_alias_ty(assoc_item, args));
|
||||||
|
|
||||||
return Ok(Some((ty, assoc_item)));
|
return Ok(Some((ty, assoc_item)));
|
||||||
}
|
}
|
||||||
|
@ -1780,9 +1789,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
.any(|impl_def_id| {
|
.any(|impl_def_id| {
|
||||||
let trait_ref = tcx.impl_trait_ref(impl_def_id);
|
let trait_ref = tcx.impl_trait_ref(impl_def_id);
|
||||||
trait_ref.is_some_and(|trait_ref| {
|
trait_ref.is_some_and(|trait_ref| {
|
||||||
let impl_ = trait_ref.subst(
|
let impl_ = trait_ref.instantiate(
|
||||||
tcx,
|
tcx,
|
||||||
infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id),
|
infcx.fresh_args_for_item(DUMMY_SP, impl_def_id),
|
||||||
);
|
);
|
||||||
let value = tcx.fold_regions(qself_ty, |_, _| tcx.lifetimes.re_erased);
|
let value = tcx.fold_regions(qself_ty, |_, _| tcx.lifetimes.re_erased);
|
||||||
// FIXME: Don't bother dealing with non-lifetime binders here...
|
// FIXME: Don't bother dealing with non-lifetime binders here...
|
||||||
|
@ -1848,7 +1857,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
&& tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative
|
&& tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative
|
||||||
})
|
})
|
||||||
.filter_map(|impl_def_id| tcx.impl_trait_ref(impl_def_id))
|
.filter_map(|impl_def_id| tcx.impl_trait_ref(impl_def_id))
|
||||||
.map(|impl_| impl_.subst_identity().self_ty())
|
.map(|impl_| impl_.instantiate_identity().self_ty())
|
||||||
// We don't care about blanket impls.
|
// We don't care about blanket impls.
|
||||||
.filter(|self_ty| !self_ty.has_non_region_param())
|
.filter(|self_ty| !self_ty.has_non_region_param())
|
||||||
.map(|self_ty| tcx.erase_regions(self_ty).to_string())
|
.map(|self_ty| tcx.erase_regions(self_ty).to_string())
|
||||||
|
@ -1877,16 +1886,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
constness,
|
constness,
|
||||||
);
|
);
|
||||||
|
|
||||||
let item_substs = self.create_substs_for_associated_item(
|
let item_args =
|
||||||
span,
|
self.create_args_for_associated_item(span, item_def_id, item_segment, trait_ref.args);
|
||||||
item_def_id,
|
|
||||||
item_segment,
|
|
||||||
trait_ref.substs,
|
|
||||||
);
|
|
||||||
|
|
||||||
debug!("qpath_to_ty: trait_ref={:?}", trait_ref);
|
debug!("qpath_to_ty: trait_ref={:?}", trait_ref);
|
||||||
|
|
||||||
Ty::new_projection(tcx, item_def_id, item_substs)
|
Ty::new_projection(tcx, item_def_id, item_args)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prohibit_generics<'a>(
|
pub fn prohibit_generics<'a>(
|
||||||
|
@ -2148,8 +2153,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
self.prohibit_generics(item_segment.1.iter(), |err| {
|
self.prohibit_generics(item_segment.1.iter(), |err| {
|
||||||
err.note("`impl Trait` types can't have type parameters");
|
err.note("`impl Trait` types can't have type parameters");
|
||||||
});
|
});
|
||||||
let substs = self.ast_path_substs_for_ty(span, did, item_segment.0);
|
let args = self.ast_path_args_for_ty(span, did, item_segment.0);
|
||||||
Ty::new_opaque(tcx, did, substs)
|
Ty::new_opaque(tcx, did, args)
|
||||||
}
|
}
|
||||||
Res::Def(
|
Res::Def(
|
||||||
DefKind::Enum
|
DefKind::Enum
|
||||||
|
@ -2233,7 +2238,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
// `Self` in impl (we know the concrete type).
|
// `Self` in impl (we know the concrete type).
|
||||||
assert_eq!(opt_self_ty, None);
|
assert_eq!(opt_self_ty, None);
|
||||||
// Try to evaluate any array length constants.
|
// Try to evaluate any array length constants.
|
||||||
let ty = tcx.at(span).type_of(def_id).subst_identity();
|
let ty = tcx.at(span).type_of(def_id).instantiate_identity();
|
||||||
let span_of_impl = tcx.span_of_impl(def_id);
|
let span_of_impl = tcx.span_of_impl(def_id);
|
||||||
self.prohibit_generics(path.segments.iter(), |err| {
|
self.prohibit_generics(path.segments.iter(), |err| {
|
||||||
let def_id = match *ty.kind() {
|
let def_id = match *ty.kind() {
|
||||||
|
@ -2471,7 +2476,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
}
|
}
|
||||||
&hir::TyKind::Path(hir::QPath::LangItem(lang_item, span, _)) => {
|
&hir::TyKind::Path(hir::QPath::LangItem(lang_item, span, _)) => {
|
||||||
let def_id = tcx.require_lang_item(lang_item, Some(span));
|
let def_id = tcx.require_lang_item(lang_item, Some(span));
|
||||||
let (substs, _) = self.create_substs_for_ast_path(
|
let (args, _) = self.create_args_for_ast_path(
|
||||||
span,
|
span,
|
||||||
def_id,
|
def_id,
|
||||||
&[],
|
&[],
|
||||||
|
@ -2481,7 +2486,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
None,
|
None,
|
||||||
ty::BoundConstness::NotConst,
|
ty::BoundConstness::NotConst,
|
||||||
);
|
);
|
||||||
tcx.at(span).type_of(def_id).subst(tcx, substs)
|
tcx.at(span).type_of(def_id).instantiate(tcx, args)
|
||||||
}
|
}
|
||||||
hir::TyKind::Array(ty, length) => {
|
hir::TyKind::Array(ty, length) => {
|
||||||
let length = match length {
|
let length = match length {
|
||||||
|
@ -2494,7 +2499,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
Ty::new_array_with_const_len(tcx, self.ast_ty_to_ty(ty), length)
|
Ty::new_array_with_const_len(tcx, self.ast_ty_to_ty(ty), length)
|
||||||
}
|
}
|
||||||
hir::TyKind::Typeof(e) => {
|
hir::TyKind::Typeof(e) => {
|
||||||
let ty_erased = tcx.type_of(e.def_id).subst_identity();
|
let ty_erased = tcx.type_of(e.def_id).instantiate_identity();
|
||||||
let ty = tcx.fold_regions(ty_erased, |r, _| {
|
let ty = tcx.fold_regions(ty_erased, |r, _| {
|
||||||
if r.is_erased() { tcx.lifetimes.re_static } else { r }
|
if r.is_erased() { tcx.lifetimes.re_static } else { r }
|
||||||
});
|
});
|
||||||
|
@ -2536,7 +2541,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
let generics = tcx.generics_of(def_id);
|
let generics = tcx.generics_of(def_id);
|
||||||
|
|
||||||
debug!("impl_trait_ty_to_ty: generics={:?}", generics);
|
debug!("impl_trait_ty_to_ty: generics={:?}", generics);
|
||||||
let substs = InternalSubsts::for_item(tcx, def_id, |param, _| {
|
let args = ty::GenericArgs::for_item(tcx, def_id, |param, _| {
|
||||||
// We use `generics.count() - lifetimes.len()` here instead of `generics.parent_count`
|
// We use `generics.count() - lifetimes.len()` here instead of `generics.parent_count`
|
||||||
// since return-position impl trait in trait squashes all of the generics from its source fn
|
// since return-position impl trait in trait squashes all of the generics from its source fn
|
||||||
// into its own generics, so the opaque's "own" params isn't always just lifetimes.
|
// into its own generics, so the opaque's "own" params isn't always just lifetimes.
|
||||||
|
@ -2550,12 +2555,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
tcx.mk_param_from_def(param)
|
tcx.mk_param_from_def(param)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
debug!("impl_trait_ty_to_ty: substs={:?}", substs);
|
debug!("impl_trait_ty_to_ty: args={:?}", args);
|
||||||
|
|
||||||
if in_trait {
|
if in_trait {
|
||||||
Ty::new_projection(tcx, def_id, substs)
|
Ty::new_projection(tcx, def_id, args)
|
||||||
} else {
|
} else {
|
||||||
Ty::new_opaque(tcx, def_id, substs)
|
Ty::new_opaque(tcx, def_id, args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2720,9 +2725,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
trait_ref.def_id,
|
trait_ref.def_id,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let fn_sig = tcx.fn_sig(assoc.def_id).subst(
|
let fn_sig = tcx.fn_sig(assoc.def_id).instantiate(
|
||||||
tcx,
|
tcx,
|
||||||
trait_ref.substs.extend_to(tcx, assoc.def_id, |param, _| tcx.mk_param_from_def(param)),
|
trait_ref.args.extend_to(tcx, assoc.def_id, |param, _| tcx.mk_param_from_def(param)),
|
||||||
);
|
);
|
||||||
let fn_sig = tcx.liberate_late_bound_regions(fn_hir_id.expect_owner().to_def_id(), fn_sig);
|
let fn_sig = tcx.liberate_late_bound_regions(fn_hir_id.expect_owner().to_def_id(), fn_sig);
|
||||||
|
|
||||||
|
|
|
@ -262,8 +262,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
let mut missing_type_params = vec![];
|
let mut missing_type_params = vec![];
|
||||||
let mut references_self = false;
|
let mut references_self = false;
|
||||||
let generics = tcx.generics_of(trait_ref.def_id);
|
let generics = tcx.generics_of(trait_ref.def_id);
|
||||||
let substs: Vec<_> = trait_ref
|
let args: Vec<_> = trait_ref
|
||||||
.substs
|
.args
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.skip(1) // Remove `Self` for `ExistentialPredicate`.
|
.skip(1) // Remove `Self` for `ExistentialPredicate`.
|
||||||
|
@ -279,7 +279,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
arg
|
arg
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let substs = tcx.mk_substs(&substs);
|
let args = tcx.mk_args(&args);
|
||||||
|
|
||||||
let span = i.bottom().1;
|
let span = i.bottom().1;
|
||||||
let empty_generic_args = hir_trait_bounds.iter().any(|hir_bound| {
|
let empty_generic_args = hir_trait_bounds.iter().any(|hir_bound| {
|
||||||
|
@ -310,7 +310,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
err.emit();
|
err.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ExistentialTraitRef { def_id: trait_ref.def_id, substs }
|
ty::ExistentialTraitRef { def_id: trait_ref.def_id, args }
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -325,7 +325,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
|
|
||||||
// Like for trait refs, verify that `dummy_self` did not leak inside default type
|
// Like for trait refs, verify that `dummy_self` did not leak inside default type
|
||||||
// parameters.
|
// parameters.
|
||||||
let references_self = b.projection_ty.substs.iter().skip(1).any(|arg| {
|
let references_self = b.projection_ty.args.iter().skip(1).any(|arg| {
|
||||||
if arg.walk().any(|arg| arg == dummy_self.into()) {
|
if arg.walk().any(|arg| arg == dummy_self.into()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -336,9 +336,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
span,
|
span,
|
||||||
"trait object projection bounds reference `Self`",
|
"trait object projection bounds reference `Self`",
|
||||||
);
|
);
|
||||||
let substs: Vec<_> = b
|
let args: Vec<_> = b
|
||||||
.projection_ty
|
.projection_ty
|
||||||
.substs
|
.args
|
||||||
.iter()
|
.iter()
|
||||||
.map(|arg| {
|
.map(|arg| {
|
||||||
if arg.walk().any(|arg| arg == dummy_self.into()) {
|
if arg.walk().any(|arg| arg == dummy_self.into()) {
|
||||||
|
@ -347,7 +347,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
arg
|
arg
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
b.projection_ty.substs = tcx.mk_substs(&substs);
|
b.projection_ty.args = tcx.mk_args(&args);
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ExistentialProjection::erase_self_ty(tcx, b)
|
ty::ExistentialProjection::erase_self_ty(tcx, b)
|
||||||
|
|
|
@ -20,8 +20,8 @@ use rustc_middle::hir::nested_filter;
|
||||||
use rustc_middle::middle::stability::EvalResult;
|
use rustc_middle::middle::stability::EvalResult;
|
||||||
use rustc_middle::traits::DefiningAnchor;
|
use rustc_middle::traits::DefiningAnchor;
|
||||||
use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
|
use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
|
||||||
use rustc_middle::ty::subst::GenericArgKind;
|
|
||||||
use rustc_middle::ty::util::{Discr, IntTypeExt};
|
use rustc_middle::ty::util::{Discr, IntTypeExt};
|
||||||
|
use rustc_middle::ty::GenericArgKind;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, AdtDef, ParamEnv, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
|
self, AdtDef, ParamEnv, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
|
||||||
};
|
};
|
||||||
|
@ -96,8 +96,8 @@ fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||||
|
|
||||||
/// Check that the fields of the `union` do not need dropping.
|
/// Check that the fields of the `union` do not need dropping.
|
||||||
fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool {
|
fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool {
|
||||||
let item_type = tcx.type_of(item_def_id).subst_identity();
|
let item_type = tcx.type_of(item_def_id).instantiate_identity();
|
||||||
if let ty::Adt(def, substs) = item_type.kind() {
|
if let ty::Adt(def, args) = item_type.kind() {
|
||||||
assert!(def.is_union());
|
assert!(def.is_union());
|
||||||
|
|
||||||
fn allowed_union_field<'tcx>(
|
fn allowed_union_field<'tcx>(
|
||||||
|
@ -128,7 +128,7 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
|
||||||
|
|
||||||
let param_env = tcx.param_env(item_def_id);
|
let param_env = tcx.param_env(item_def_id);
|
||||||
for field in &def.non_enum_variant().fields {
|
for field in &def.non_enum_variant().fields {
|
||||||
let field_ty = tcx.normalize_erasing_regions(param_env, field.ty(tcx, substs));
|
let field_ty = tcx.normalize_erasing_regions(param_env, field.ty(tcx, args));
|
||||||
|
|
||||||
if !allowed_union_field(field_ty, tcx, param_env) {
|
if !allowed_union_field(field_ty, tcx, param_env) {
|
||||||
let (field_span, ty_span) = match tcx.hir().get_if_local(field.did) {
|
let (field_span, ty_span) = match tcx.hir().get_if_local(field.did) {
|
||||||
|
@ -163,7 +163,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||||
// would be enough to check this for `extern` statics, as statics with an initializer will
|
// would be enough to check this for `extern` statics, as statics with an initializer will
|
||||||
// have UB during initialization if they are uninhabited, but there also seems to be no good
|
// have UB during initialization if they are uninhabited, but there also seems to be no good
|
||||||
// reason to allow any statics to be uninhabited.
|
// reason to allow any statics to be uninhabited.
|
||||||
let ty = tcx.type_of(def_id).subst_identity();
|
let ty = tcx.type_of(def_id).instantiate_identity();
|
||||||
let span = tcx.def_span(def_id);
|
let span = tcx.def_span(def_id);
|
||||||
let layout = match tcx.layout_of(ParamEnv::reveal_all().and(ty)) {
|
let layout = match tcx.layout_of(ParamEnv::reveal_all().and(ty)) {
|
||||||
Ok(l) => l,
|
Ok(l) => l,
|
||||||
|
@ -212,16 +212,16 @@ fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let substs = InternalSubsts::identity_for_item(tcx, item.owner_id);
|
let args = GenericArgs::identity_for_item(tcx, item.owner_id);
|
||||||
let span = tcx.def_span(item.owner_id.def_id);
|
let span = tcx.def_span(item.owner_id.def_id);
|
||||||
|
|
||||||
if !tcx.features().impl_trait_projections {
|
if !tcx.features().impl_trait_projections {
|
||||||
check_opaque_for_inheriting_lifetimes(tcx, item.owner_id.def_id, span);
|
check_opaque_for_inheriting_lifetimes(tcx, item.owner_id.def_id, span);
|
||||||
}
|
}
|
||||||
if tcx.type_of(item.owner_id.def_id).subst_identity().references_error() {
|
if tcx.type_of(item.owner_id.def_id).instantiate_identity().references_error() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if check_opaque_for_cycles(tcx, item.owner_id.def_id, substs, span, &origin).is_err() {
|
if check_opaque_for_cycles(tcx, item.owner_id.def_id, args, span, &origin).is_err() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,8 +305,8 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
|
||||||
..
|
..
|
||||||
}) = item.kind
|
}) = item.kind
|
||||||
{
|
{
|
||||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
let args = GenericArgs::identity_for_item(tcx, def_id);
|
||||||
let opaque_identity_ty = Ty::new_opaque(tcx, def_id.to_def_id(), substs);
|
let opaque_identity_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
|
||||||
let mut visitor = ProhibitOpaqueVisitor {
|
let mut visitor = ProhibitOpaqueVisitor {
|
||||||
opaque_identity_ty,
|
opaque_identity_ty,
|
||||||
parent_count: tcx.generics_of(def_id).parent_count as u32,
|
parent_count: tcx.generics_of(def_id).parent_count as u32,
|
||||||
|
@ -316,7 +316,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
|
||||||
};
|
};
|
||||||
let prohibit_opaque = tcx
|
let prohibit_opaque = tcx
|
||||||
.explicit_item_bounds(def_id)
|
.explicit_item_bounds(def_id)
|
||||||
.subst_identity_iter_copied()
|
.instantiate_identity_iter_copied()
|
||||||
.try_for_each(|(predicate, _)| predicate.visit_with(&mut visitor));
|
.try_for_each(|(predicate, _)| predicate.visit_with(&mut visitor));
|
||||||
|
|
||||||
if let Some(ty) = prohibit_opaque.break_value() {
|
if let Some(ty) = prohibit_opaque.break_value() {
|
||||||
|
@ -355,11 +355,11 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
|
||||||
pub(super) fn check_opaque_for_cycles<'tcx>(
|
pub(super) fn check_opaque_for_cycles<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
def_id: LocalDefId,
|
def_id: LocalDefId,
|
||||||
substs: SubstsRef<'tcx>,
|
args: GenericArgsRef<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
origin: &hir::OpaqueTyOrigin,
|
origin: &hir::OpaqueTyOrigin,
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
if tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs).is_err() {
|
if tcx.try_expand_impl_trait_type(def_id.to_def_id(), args).is_err() {
|
||||||
let reported = match origin {
|
let reported = match origin {
|
||||||
hir::OpaqueTyOrigin::AsyncFn(..) => async_opaque_type_cycle_error(tcx, span),
|
hir::OpaqueTyOrigin::AsyncFn(..) => async_opaque_type_cycle_error(tcx, span),
|
||||||
_ => opaque_type_cycle_error(tcx, def_id, span),
|
_ => opaque_type_cycle_error(tcx, def_id, span),
|
||||||
|
@ -404,16 +404,16 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||||
.build();
|
.build();
|
||||||
let ocx = ObligationCtxt::new(&infcx);
|
let ocx = ObligationCtxt::new(&infcx);
|
||||||
|
|
||||||
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
|
let args = GenericArgs::identity_for_item(tcx, def_id.to_def_id());
|
||||||
let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), substs);
|
let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
|
||||||
|
|
||||||
// `ReErased` regions appear in the "parent_substs" of closures/generators.
|
// `ReErased` regions appear in the "parent_args" of closures/generators.
|
||||||
// We're ignoring them here and replacing them with fresh region variables.
|
// We're ignoring them here and replacing them with fresh region variables.
|
||||||
// See tests in ui/type-alias-impl-trait/closure_{parent_substs,wf_outlives}.rs.
|
// See tests in ui/type-alias-impl-trait/closure_{parent_args,wf_outlives}.rs.
|
||||||
//
|
//
|
||||||
// FIXME: Consider wrapping the hidden type in an existential `Binder` and instantiating it
|
// FIXME: Consider wrapping the hidden type in an existential `Binder` and instantiating it
|
||||||
// here rather than using ReErased.
|
// here rather than using ReErased.
|
||||||
let hidden_ty = tcx.type_of(def_id.to_def_id()).subst(tcx, substs);
|
let hidden_ty = tcx.type_of(def_id.to_def_id()).instantiate(tcx, args);
|
||||||
let hidden_ty = tcx.fold_regions(hidden_ty, |re, _dbi| match re.kind() {
|
let hidden_ty = tcx.fold_regions(hidden_ty, |re, _dbi| match re.kind() {
|
||||||
ty::ReErased => infcx.next_region_var(RegionVariableOrigin::MiscVariable(span)),
|
ty::ReErased => infcx.next_region_var(RegionVariableOrigin::MiscVariable(span)),
|
||||||
_ => re,
|
_ => re,
|
||||||
|
@ -472,7 +472,7 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||||
fn is_enum_of_nonnullable_ptr<'tcx>(
|
fn is_enum_of_nonnullable_ptr<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
adt_def: AdtDef<'tcx>,
|
adt_def: AdtDef<'tcx>,
|
||||||
substs: SubstsRef<'tcx>,
|
args: GenericArgsRef<'tcx>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if adt_def.repr().inhibit_enum_layout_opt() {
|
if adt_def.repr().inhibit_enum_layout_opt() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -484,14 +484,14 @@ fn is_enum_of_nonnullable_ptr<'tcx>(
|
||||||
let (([], [field]) | ([field], [])) = (&var_one.fields.raw[..], &var_two.fields.raw[..]) else {
|
let (([], [field]) | ([field], [])) = (&var_one.fields.raw[..], &var_two.fields.raw[..]) else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
matches!(field.ty(tcx, substs).kind(), ty::FnPtr(..) | ty::Ref(..))
|
matches!(field.ty(tcx, args).kind(), ty::FnPtr(..) | ty::Ref(..))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||||
if tcx.codegen_fn_attrs(def_id).import_linkage.is_some() {
|
if tcx.codegen_fn_attrs(def_id).import_linkage.is_some() {
|
||||||
if match tcx.type_of(def_id).subst_identity().kind() {
|
if match tcx.type_of(def_id).instantiate_identity().kind() {
|
||||||
ty::RawPtr(_) => false,
|
ty::RawPtr(_) => false,
|
||||||
ty::Adt(adt_def, substs) => !is_enum_of_nonnullable_ptr(tcx, *adt_def, *substs),
|
ty::Adt(adt_def, args) => !is_enum_of_nonnullable_ptr(tcx, *adt_def, *args),
|
||||||
_ => true,
|
_ => true,
|
||||||
} {
|
} {
|
||||||
tcx.sess.emit_err(LinkageType { span: tcx.def_span(def_id) });
|
tcx.sess.emit_err(LinkageType { span: tcx.def_span(def_id) });
|
||||||
|
@ -525,7 +525,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
|
||||||
check_impl_items_against_trait(
|
check_impl_items_against_trait(
|
||||||
tcx,
|
tcx,
|
||||||
id.owner_id.def_id,
|
id.owner_id.def_id,
|
||||||
impl_trait_ref.subst_identity(),
|
impl_trait_ref.instantiate_identity(),
|
||||||
);
|
);
|
||||||
check_on_unimplemented(tcx, id);
|
check_on_unimplemented(tcx, id);
|
||||||
}
|
}
|
||||||
|
@ -541,13 +541,13 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
|
||||||
fn_maybe_err(tcx, assoc_item.ident(tcx).span, abi);
|
fn_maybe_err(tcx, assoc_item.ident(tcx).span, abi);
|
||||||
}
|
}
|
||||||
ty::AssocKind::Type if assoc_item.defaultness(tcx).has_value() => {
|
ty::AssocKind::Type if assoc_item.defaultness(tcx).has_value() => {
|
||||||
let trait_substs =
|
let trait_args =
|
||||||
InternalSubsts::identity_for_item(tcx, id.owner_id);
|
GenericArgs::identity_for_item(tcx, id.owner_id);
|
||||||
let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds(
|
let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds(
|
||||||
tcx,
|
tcx,
|
||||||
assoc_item,
|
assoc_item,
|
||||||
assoc_item,
|
assoc_item,
|
||||||
ty::TraitRef::new(tcx, id.owner_id.to_def_id(), trait_substs),
|
ty::TraitRef::new(tcx, id.owner_id.to_def_id(), trait_args),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -572,7 +572,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DefKind::TyAlias => {
|
DefKind::TyAlias => {
|
||||||
let pty_ty = tcx.type_of(id.owner_id).subst_identity();
|
let pty_ty = tcx.type_of(id.owner_id).instantiate_identity();
|
||||||
let generics = tcx.generics_of(id.owner_id);
|
let generics = tcx.generics_of(id.owner_id);
|
||||||
check_type_params_are_used(tcx, &generics, pty_ty);
|
check_type_params_are_used(tcx, &generics, pty_ty);
|
||||||
}
|
}
|
||||||
|
@ -886,8 +886,8 @@ fn check_impl_items_against_trait<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
|
pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
|
||||||
let t = tcx.type_of(def_id).subst_identity();
|
let t = tcx.type_of(def_id).instantiate_identity();
|
||||||
if let ty::Adt(def, substs) = t.kind()
|
if let ty::Adt(def, args) = t.kind()
|
||||||
&& def.is_struct()
|
&& def.is_struct()
|
||||||
{
|
{
|
||||||
let fields = &def.non_enum_variant().fields;
|
let fields = &def.non_enum_variant().fields;
|
||||||
|
@ -895,8 +895,8 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
|
||||||
struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
|
struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let e = fields[FieldIdx::from_u32(0)].ty(tcx, substs);
|
let e = fields[FieldIdx::from_u32(0)].ty(tcx, args);
|
||||||
if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
|
if !fields.iter().all(|f| f.ty(tcx, args) == e) {
|
||||||
struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
|
struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
|
||||||
.span_label(sp, "SIMD elements must have the same type")
|
.span_label(sp, "SIMD elements must have the same type")
|
||||||
.emit();
|
.emit();
|
||||||
|
@ -1003,7 +1003,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) {
|
||||||
if first {
|
if first {
|
||||||
format!(
|
format!(
|
||||||
"`{}` contains a field of type `{}`",
|
"`{}` contains a field of type `{}`",
|
||||||
tcx.type_of(def.did()).subst_identity(),
|
tcx.type_of(def.did()).instantiate_identity(),
|
||||||
ident
|
ident
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1025,7 +1025,7 @@ pub(super) fn check_packed_inner(
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
stack: &mut Vec<DefId>,
|
stack: &mut Vec<DefId>,
|
||||||
) -> Option<Vec<(DefId, Span)>> {
|
) -> Option<Vec<(DefId, Span)>> {
|
||||||
if let ty::Adt(def, substs) = tcx.type_of(def_id).subst_identity().kind() {
|
if let ty::Adt(def, args) = tcx.type_of(def_id).instantiate_identity().kind() {
|
||||||
if def.is_struct() || def.is_union() {
|
if def.is_struct() || def.is_union() {
|
||||||
if def.repr().align.is_some() {
|
if def.repr().align.is_some() {
|
||||||
return Some(vec![(def.did(), DUMMY_SP)]);
|
return Some(vec![(def.did(), DUMMY_SP)]);
|
||||||
|
@ -1033,7 +1033,7 @@ pub(super) fn check_packed_inner(
|
||||||
|
|
||||||
stack.push(def_id);
|
stack.push(def_id);
|
||||||
for field in &def.non_enum_variant().fields {
|
for field in &def.non_enum_variant().fields {
|
||||||
if let ty::Adt(def, _) = field.ty(tcx, substs).kind()
|
if let ty::Adt(def, _) = field.ty(tcx, args).kind()
|
||||||
&& !stack.contains(&def.did())
|
&& !stack.contains(&def.did())
|
||||||
&& let Some(mut defs) = check_packed_inner(tcx, def.did(), stack)
|
&& let Some(mut defs) = check_packed_inner(tcx, def.did(), stack)
|
||||||
{
|
{
|
||||||
|
@ -1072,7 +1072,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
|
||||||
// For each field, figure out if it's known to be a ZST and align(1), with "known"
|
// For each field, figure out if it's known to be a ZST and align(1), with "known"
|
||||||
// respecting #[non_exhaustive] attributes.
|
// respecting #[non_exhaustive] attributes.
|
||||||
let field_infos = adt.all_fields().map(|field| {
|
let field_infos = adt.all_fields().map(|field| {
|
||||||
let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
|
let ty = field.ty(tcx, GenericArgs::identity_for_item(tcx, field.did));
|
||||||
let param_env = tcx.param_env(field.did);
|
let param_env = tcx.param_env(field.did);
|
||||||
let layout = tcx.layout_of(param_env.and(ty));
|
let layout = tcx.layout_of(param_env.and(ty));
|
||||||
// We are currently checking the type this field came from, so it must be local
|
// We are currently checking the type this field came from, so it must be local
|
||||||
|
@ -1086,7 +1086,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
|
||||||
fn check_non_exhaustive<'tcx>(
|
fn check_non_exhaustive<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
t: Ty<'tcx>,
|
t: Ty<'tcx>,
|
||||||
) -> ControlFlow<(&'static str, DefId, SubstsRef<'tcx>, bool)> {
|
) -> ControlFlow<(&'static str, DefId, GenericArgsRef<'tcx>, bool)> {
|
||||||
match t.kind() {
|
match t.kind() {
|
||||||
ty::Tuple(list) => list.iter().try_for_each(|t| check_non_exhaustive(tcx, t)),
|
ty::Tuple(list) => list.iter().try_for_each(|t| check_non_exhaustive(tcx, t)),
|
||||||
ty::Array(ty, _) => check_non_exhaustive(tcx, *ty),
|
ty::Array(ty, _) => check_non_exhaustive(tcx, *ty),
|
||||||
|
@ -1140,7 +1140,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
|
||||||
.span_label(span, "has alignment larger than 1")
|
.span_label(span, "has alignment larger than 1")
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
if incompat && let Some((descr, def_id, substs, non_exhaustive)) = non_exhaustive {
|
if incompat && let Some((descr, def_id, args, non_exhaustive)) = non_exhaustive {
|
||||||
tcx.struct_span_lint_hir(
|
tcx.struct_span_lint_hir(
|
||||||
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS,
|
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS,
|
||||||
tcx.hir().local_def_id_to_hir_id(adt.did().expect_local()),
|
tcx.hir().local_def_id_to_hir_id(adt.did().expect_local()),
|
||||||
|
@ -1152,7 +1152,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
|
||||||
} else {
|
} else {
|
||||||
"contains private fields"
|
"contains private fields"
|
||||||
};
|
};
|
||||||
let field_ty = tcx.def_path_str_with_substs(def_id, substs);
|
let field_ty = tcx.def_path_str_with_args(def_id, args);
|
||||||
lint
|
lint
|
||||||
.note(format!("this {descr} contains `{field_ty}`, which {note}, \
|
.note(format!("this {descr} contains `{field_ty}`, which {note}, \
|
||||||
and makes it not a breaking change to become non-zero-sized in the future."))
|
and makes it not a breaking change to become non-zero-sized in the future."))
|
||||||
|
|
|
@ -16,7 +16,7 @@ use rustc_infer::traits::util;
|
||||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||||
use rustc_middle::ty::util::ExplicitSelf;
|
use rustc_middle::ty::util::ExplicitSelf;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, InternalSubsts, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
|
self, GenericArgs, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt};
|
use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt};
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
|
@ -96,15 +96,15 @@ fn check_method_is_structurally_compatible<'tcx>(
|
||||||
/// For this we have to show that, assuming the bounds of the impl hold, the
|
/// For this we have to show that, assuming the bounds of the impl hold, the
|
||||||
/// bounds of `trait_m` imply the bounds of `impl_m`.
|
/// bounds of `trait_m` imply the bounds of `impl_m`.
|
||||||
///
|
///
|
||||||
/// We start out with `trait_to_impl_substs`, that maps the trait
|
/// We start out with `trait_to_impl_args`, that maps the trait
|
||||||
/// type parameters to impl type parameters. This is taken from the
|
/// type parameters to impl type parameters. This is taken from the
|
||||||
/// impl trait reference:
|
/// impl trait reference:
|
||||||
///
|
///
|
||||||
/// ```rust,ignore (pseudo-Rust)
|
/// ```rust,ignore (pseudo-Rust)
|
||||||
/// trait_to_impl_substs = {'t => 'j, T => &'i U, Self => Foo}
|
/// trait_to_impl_args = {'t => 'j, T => &'i U, Self => Foo}
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// We create a mapping `dummy_substs` that maps from the impl type
|
/// We create a mapping `dummy_args` that maps from the impl type
|
||||||
/// parameters to fresh types and regions. For type parameters,
|
/// parameters to fresh types and regions. For type parameters,
|
||||||
/// this is the identity transform, but we could as well use any
|
/// this is the identity transform, but we could as well use any
|
||||||
/// placeholder types. For regions, we convert from bound to free
|
/// placeholder types. For regions, we convert from bound to free
|
||||||
|
@ -112,10 +112,10 @@ fn check_method_is_structurally_compatible<'tcx>(
|
||||||
/// declared on the impl or used in type parameter bounds).
|
/// declared on the impl or used in type parameter bounds).
|
||||||
///
|
///
|
||||||
/// ```rust,ignore (pseudo-Rust)
|
/// ```rust,ignore (pseudo-Rust)
|
||||||
/// impl_to_placeholder_substs = {'i => 'i0, U => U0, N => N0 }
|
/// impl_to_placeholder_args = {'i => 'i0, U => U0, N => N0 }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Now we can apply `placeholder_substs` to the type of the impl method
|
/// Now we can apply `placeholder_args` to the type of the impl method
|
||||||
/// to yield a new function type in terms of our fresh, placeholder
|
/// to yield a new function type in terms of our fresh, placeholder
|
||||||
/// types:
|
/// types:
|
||||||
///
|
///
|
||||||
|
@ -125,13 +125,13 @@ fn check_method_is_structurally_compatible<'tcx>(
|
||||||
///
|
///
|
||||||
/// We now want to extract and substitute the type of the *trait*
|
/// We now want to extract and substitute the type of the *trait*
|
||||||
/// method and compare it. To do so, we must create a compound
|
/// method and compare it. To do so, we must create a compound
|
||||||
/// substitution by combining `trait_to_impl_substs` and
|
/// substitution by combining `trait_to_impl_args` and
|
||||||
/// `impl_to_placeholder_substs`, and also adding a mapping for the method
|
/// `impl_to_placeholder_args`, and also adding a mapping for the method
|
||||||
/// type parameters. We extend the mapping to also include
|
/// type parameters. We extend the mapping to also include
|
||||||
/// the method parameters.
|
/// the method parameters.
|
||||||
///
|
///
|
||||||
/// ```rust,ignore (pseudo-Rust)
|
/// ```rust,ignore (pseudo-Rust)
|
||||||
/// trait_to_placeholder_substs = { T => &'i0 U0, Self => Foo, M => N0 }
|
/// trait_to_placeholder_args = { T => &'i0 U0, Self => Foo, M => N0 }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Applying this to the trait method type yields:
|
/// Applying this to the trait method type yields:
|
||||||
|
@ -148,8 +148,8 @@ fn check_method_is_structurally_compatible<'tcx>(
|
||||||
/// satisfied by the implementation's method.
|
/// satisfied by the implementation's method.
|
||||||
///
|
///
|
||||||
/// We do this by creating a parameter environment which contains a
|
/// We do this by creating a parameter environment which contains a
|
||||||
/// substitution corresponding to `impl_to_placeholder_substs`. We then build
|
/// substitution corresponding to `impl_to_placeholder_args`. We then build
|
||||||
/// `trait_to_placeholder_substs` and use it to convert the predicates contained
|
/// `trait_to_placeholder_args` and use it to convert the predicates contained
|
||||||
/// in the `trait_m` generics to the placeholder form.
|
/// in the `trait_m` generics to the placeholder form.
|
||||||
///
|
///
|
||||||
/// Finally we register each of these predicates as an obligation and check that
|
/// Finally we register each of these predicates as an obligation and check that
|
||||||
|
@ -162,7 +162,7 @@ fn compare_method_predicate_entailment<'tcx>(
|
||||||
impl_trait_ref: ty::TraitRef<'tcx>,
|
impl_trait_ref: ty::TraitRef<'tcx>,
|
||||||
check_implied_wf: CheckImpliedWfMode,
|
check_implied_wf: CheckImpliedWfMode,
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
let trait_to_impl_substs = impl_trait_ref.substs;
|
let trait_to_impl_args = impl_trait_ref.args;
|
||||||
|
|
||||||
// This node-id should be used for the `body_id` field on each
|
// This node-id should be used for the `body_id` field on each
|
||||||
// `ObligationCause` (and the `FnCtxt`).
|
// `ObligationCause` (and the `FnCtxt`).
|
||||||
|
@ -182,12 +182,12 @@ fn compare_method_predicate_entailment<'tcx>(
|
||||||
);
|
);
|
||||||
|
|
||||||
// Create mapping from impl to placeholder.
|
// Create mapping from impl to placeholder.
|
||||||
let impl_to_placeholder_substs = InternalSubsts::identity_for_item(tcx, impl_m.def_id);
|
let impl_to_placeholder_args = GenericArgs::identity_for_item(tcx, impl_m.def_id);
|
||||||
|
|
||||||
// Create mapping from trait to placeholder.
|
// Create mapping from trait to placeholder.
|
||||||
let trait_to_placeholder_substs =
|
let trait_to_placeholder_args =
|
||||||
impl_to_placeholder_substs.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_substs);
|
impl_to_placeholder_args.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_args);
|
||||||
debug!("compare_impl_method: trait_to_placeholder_substs={:?}", trait_to_placeholder_substs);
|
debug!("compare_impl_method: trait_to_placeholder_args={:?}", trait_to_placeholder_args);
|
||||||
|
|
||||||
let impl_m_predicates = tcx.predicates_of(impl_m.def_id);
|
let impl_m_predicates = tcx.predicates_of(impl_m.def_id);
|
||||||
let trait_m_predicates = tcx.predicates_of(trait_m.def_id);
|
let trait_m_predicates = tcx.predicates_of(trait_m.def_id);
|
||||||
|
@ -211,7 +211,7 @@ fn compare_method_predicate_entailment<'tcx>(
|
||||||
// if all constraints hold.
|
// if all constraints hold.
|
||||||
hybrid_preds.predicates.extend(
|
hybrid_preds.predicates.extend(
|
||||||
trait_m_predicates
|
trait_m_predicates
|
||||||
.instantiate_own(tcx, trait_to_placeholder_substs)
|
.instantiate_own(tcx, trait_to_placeholder_args)
|
||||||
.map(|(predicate, _)| predicate),
|
.map(|(predicate, _)| predicate),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -231,7 +231,7 @@ fn compare_method_predicate_entailment<'tcx>(
|
||||||
|
|
||||||
debug!("compare_impl_method: caller_bounds={:?}", param_env.caller_bounds());
|
debug!("compare_impl_method: caller_bounds={:?}", param_env.caller_bounds());
|
||||||
|
|
||||||
let impl_m_own_bounds = impl_m_predicates.instantiate_own(tcx, impl_to_placeholder_substs);
|
let impl_m_own_bounds = impl_m_predicates.instantiate_own(tcx, impl_to_placeholder_args);
|
||||||
for (predicate, span) in impl_m_own_bounds {
|
for (predicate, span) in impl_m_own_bounds {
|
||||||
let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id);
|
let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id);
|
||||||
let predicate = ocx.normalize(&normalize_cause, param_env, predicate);
|
let predicate = ocx.normalize(&normalize_cause, param_env, predicate);
|
||||||
|
@ -269,7 +269,7 @@ fn compare_method_predicate_entailment<'tcx>(
|
||||||
let unnormalized_impl_sig = infcx.instantiate_binder_with_fresh_vars(
|
let unnormalized_impl_sig = infcx.instantiate_binder_with_fresh_vars(
|
||||||
impl_m_span,
|
impl_m_span,
|
||||||
infer::HigherRankedType,
|
infer::HigherRankedType,
|
||||||
tcx.fn_sig(impl_m.def_id).subst_identity(),
|
tcx.fn_sig(impl_m.def_id).instantiate_identity(),
|
||||||
);
|
);
|
||||||
let unnormalized_impl_fty = Ty::new_fn_ptr(tcx, ty::Binder::dummy(unnormalized_impl_sig));
|
let unnormalized_impl_fty = Ty::new_fn_ptr(tcx, ty::Binder::dummy(unnormalized_impl_sig));
|
||||||
|
|
||||||
|
@ -277,7 +277,7 @@ fn compare_method_predicate_entailment<'tcx>(
|
||||||
let impl_sig = ocx.normalize(&norm_cause, param_env, unnormalized_impl_sig);
|
let impl_sig = ocx.normalize(&norm_cause, param_env, unnormalized_impl_sig);
|
||||||
debug!("compare_impl_method: impl_fty={:?}", impl_sig);
|
debug!("compare_impl_method: impl_fty={:?}", impl_sig);
|
||||||
|
|
||||||
let trait_sig = tcx.fn_sig(trait_m.def_id).subst(tcx, trait_to_placeholder_substs);
|
let trait_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_placeholder_args);
|
||||||
let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_sig);
|
let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_sig);
|
||||||
|
|
||||||
// Next, add all inputs and output as well-formed tys. Importantly,
|
// Next, add all inputs and output as well-formed tys. Importantly,
|
||||||
|
@ -615,14 +615,14 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
||||||
let impl_m = tcx.opt_associated_item(impl_m_def_id.to_def_id()).unwrap();
|
let impl_m = tcx.opt_associated_item(impl_m_def_id.to_def_id()).unwrap();
|
||||||
let trait_m = tcx.opt_associated_item(impl_m.trait_item_def_id.unwrap()).unwrap();
|
let trait_m = tcx.opt_associated_item(impl_m.trait_item_def_id.unwrap()).unwrap();
|
||||||
let impl_trait_ref =
|
let impl_trait_ref =
|
||||||
tcx.impl_trait_ref(impl_m.impl_container(tcx).unwrap()).unwrap().subst_identity();
|
tcx.impl_trait_ref(impl_m.impl_container(tcx).unwrap()).unwrap().instantiate_identity();
|
||||||
let param_env = tcx.param_env(impl_m_def_id);
|
let param_env = tcx.param_env(impl_m_def_id);
|
||||||
|
|
||||||
// First, check a few of the same things as `compare_impl_method`,
|
// First, check a few of the same things as `compare_impl_method`,
|
||||||
// just so we don't ICE during substitution later.
|
// just so we don't ICE during substitution later.
|
||||||
check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?;
|
check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?;
|
||||||
|
|
||||||
let trait_to_impl_substs = impl_trait_ref.substs;
|
let trait_to_impl_args = impl_trait_ref.args;
|
||||||
|
|
||||||
let impl_m_hir_id = tcx.hir().local_def_id_to_hir_id(impl_m_def_id);
|
let impl_m_hir_id = tcx.hir().local_def_id_to_hir_id(impl_m_def_id);
|
||||||
let return_span = tcx.hir().fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span();
|
let return_span = tcx.hir().fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span();
|
||||||
|
@ -637,11 +637,11 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
||||||
);
|
);
|
||||||
|
|
||||||
// Create mapping from impl to placeholder.
|
// Create mapping from impl to placeholder.
|
||||||
let impl_to_placeholder_substs = InternalSubsts::identity_for_item(tcx, impl_m.def_id);
|
let impl_to_placeholder_args = GenericArgs::identity_for_item(tcx, impl_m.def_id);
|
||||||
|
|
||||||
// Create mapping from trait to placeholder.
|
// Create mapping from trait to placeholder.
|
||||||
let trait_to_placeholder_substs =
|
let trait_to_placeholder_args =
|
||||||
impl_to_placeholder_substs.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_substs);
|
impl_to_placeholder_args.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_args);
|
||||||
|
|
||||||
let infcx = &tcx.infer_ctxt().build();
|
let infcx = &tcx.infer_ctxt().build();
|
||||||
let ocx = ObligationCtxt::new(infcx);
|
let ocx = ObligationCtxt::new(infcx);
|
||||||
|
@ -651,7 +651,10 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
||||||
let impl_sig = ocx.normalize(
|
let impl_sig = ocx.normalize(
|
||||||
&norm_cause,
|
&norm_cause,
|
||||||
param_env,
|
param_env,
|
||||||
tcx.liberate_late_bound_regions(impl_m.def_id, tcx.fn_sig(impl_m.def_id).subst_identity()),
|
tcx.liberate_late_bound_regions(
|
||||||
|
impl_m.def_id,
|
||||||
|
tcx.fn_sig(impl_m.def_id).instantiate_identity(),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
impl_sig.error_reported()?;
|
impl_sig.error_reported()?;
|
||||||
let impl_return_ty = impl_sig.output();
|
let impl_return_ty = impl_sig.output();
|
||||||
|
@ -665,7 +668,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
||||||
.instantiate_binder_with_fresh_vars(
|
.instantiate_binder_with_fresh_vars(
|
||||||
return_span,
|
return_span,
|
||||||
infer::HigherRankedType,
|
infer::HigherRankedType,
|
||||||
tcx.fn_sig(trait_m.def_id).subst(tcx, trait_to_placeholder_substs),
|
tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_placeholder_args),
|
||||||
)
|
)
|
||||||
.fold_with(&mut collector);
|
.fold_with(&mut collector);
|
||||||
|
|
||||||
|
@ -758,47 +761,47 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
||||||
ocx.resolve_regions_and_report_errors(impl_m_def_id, &outlives_env)?;
|
ocx.resolve_regions_and_report_errors(impl_m_def_id, &outlives_env)?;
|
||||||
|
|
||||||
let mut collected_tys = FxHashMap::default();
|
let mut collected_tys = FxHashMap::default();
|
||||||
for (def_id, (ty, substs)) in collected_types {
|
for (def_id, (ty, args)) in collected_types {
|
||||||
match infcx.fully_resolve((ty, substs)) {
|
match infcx.fully_resolve((ty, args)) {
|
||||||
Ok((ty, substs)) => {
|
Ok((ty, args)) => {
|
||||||
// `ty` contains free regions that we created earlier while liberating the
|
// `ty` contains free regions that we created earlier while liberating the
|
||||||
// trait fn signature. However, projection normalization expects `ty` to
|
// trait fn signature. However, projection normalization expects `ty` to
|
||||||
// contains `def_id`'s early-bound regions.
|
// contains `def_id`'s early-bound regions.
|
||||||
let id_substs = InternalSubsts::identity_for_item(tcx, def_id);
|
let id_args = GenericArgs::identity_for_item(tcx, def_id);
|
||||||
debug!(?id_substs, ?substs);
|
debug!(?id_args, ?args);
|
||||||
let map: FxHashMap<_, _> = std::iter::zip(substs, id_substs)
|
let map: FxHashMap<_, _> = std::iter::zip(args, id_args)
|
||||||
.skip(tcx.generics_of(trait_m.def_id).count())
|
.skip(tcx.generics_of(trait_m.def_id).count())
|
||||||
.filter_map(|(a, b)| Some((a.as_region()?, b.as_region()?)))
|
.filter_map(|(a, b)| Some((a.as_region()?, b.as_region()?)))
|
||||||
.collect();
|
.collect();
|
||||||
debug!(?map);
|
debug!(?map);
|
||||||
|
|
||||||
// NOTE(compiler-errors): RPITITs, like all other RPITs, have early-bound
|
// NOTE(compiler-errors): RPITITs, like all other RPITs, have early-bound
|
||||||
// region substs that are synthesized during AST lowering. These are substs
|
// region args that are synthesized during AST lowering. These are args
|
||||||
// that are appended to the parent substs (trait and trait method). However,
|
// that are appended to the parent args (trait and trait method). However,
|
||||||
// we're trying to infer the unsubstituted type value of the RPITIT inside
|
// we're trying to infer the unsubstituted type value of the RPITIT inside
|
||||||
// the *impl*, so we can later use the impl's method substs to normalize
|
// the *impl*, so we can later use the impl's method args to normalize
|
||||||
// an RPITIT to a concrete type (`confirm_impl_trait_in_trait_candidate`).
|
// an RPITIT to a concrete type (`confirm_impl_trait_in_trait_candidate`).
|
||||||
//
|
//
|
||||||
// Due to the design of RPITITs, during AST lowering, we have no idea that
|
// Due to the design of RPITITs, during AST lowering, we have no idea that
|
||||||
// an impl method corresponds to a trait method with RPITITs in it. Therefore,
|
// an impl method corresponds to a trait method with RPITITs in it. Therefore,
|
||||||
// we don't have a list of early-bound region substs for the RPITIT in the impl.
|
// we don't have a list of early-bound region args for the RPITIT in the impl.
|
||||||
// Since early region parameters are index-based, we can't just rebase these
|
// Since early region parameters are index-based, we can't just rebase these
|
||||||
// (trait method) early-bound region substs onto the impl, and there's no
|
// (trait method) early-bound region args onto the impl, and there's no
|
||||||
// guarantee that the indices from the trait substs and impl substs line up.
|
// guarantee that the indices from the trait args and impl args line up.
|
||||||
// So to fix this, we subtract the number of trait substs and add the number of
|
// So to fix this, we subtract the number of trait args and add the number of
|
||||||
// impl substs to *renumber* these early-bound regions to their corresponding
|
// impl args to *renumber* these early-bound regions to their corresponding
|
||||||
// indices in the impl's substitutions list.
|
// indices in the impl's substitutions list.
|
||||||
//
|
//
|
||||||
// Also, we only need to account for a difference in trait and impl substs,
|
// Also, we only need to account for a difference in trait and impl args,
|
||||||
// since we previously enforce that the trait method and impl method have the
|
// since we previously enforce that the trait method and impl method have the
|
||||||
// same generics.
|
// same generics.
|
||||||
let num_trait_substs = trait_to_impl_substs.len();
|
let num_trait_args = trait_to_impl_args.len();
|
||||||
let num_impl_substs = tcx.generics_of(impl_m.container_id(tcx)).params.len();
|
let num_impl_args = tcx.generics_of(impl_m.container_id(tcx)).params.len();
|
||||||
let ty = match ty.try_fold_with(&mut RemapHiddenTyRegions {
|
let ty = match ty.try_fold_with(&mut RemapHiddenTyRegions {
|
||||||
tcx,
|
tcx,
|
||||||
map,
|
map,
|
||||||
num_trait_substs,
|
num_trait_args,
|
||||||
num_impl_substs,
|
num_impl_args,
|
||||||
def_id,
|
def_id,
|
||||||
impl_def_id: impl_m.container_id(tcx),
|
impl_def_id: impl_m.container_id(tcx),
|
||||||
ty,
|
ty,
|
||||||
|
@ -824,7 +827,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
||||||
|
|
||||||
struct ImplTraitInTraitCollector<'a, 'tcx> {
|
struct ImplTraitInTraitCollector<'a, 'tcx> {
|
||||||
ocx: &'a ObligationCtxt<'a, 'tcx>,
|
ocx: &'a ObligationCtxt<'a, 'tcx>,
|
||||||
types: FxHashMap<DefId, (Ty<'tcx>, ty::SubstsRef<'tcx>)>,
|
types: FxHashMap<DefId, (Ty<'tcx>, ty::GenericArgsRef<'tcx>)>,
|
||||||
span: Span,
|
span: Span,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
body_id: LocalDefId,
|
body_id: LocalDefId,
|
||||||
|
@ -853,8 +856,8 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> {
|
||||||
if let Some((ty, _)) = self.types.get(&proj.def_id) {
|
if let Some((ty, _)) = self.types.get(&proj.def_id) {
|
||||||
return *ty;
|
return *ty;
|
||||||
}
|
}
|
||||||
//FIXME(RPITIT): Deny nested RPITIT in substs too
|
//FIXME(RPITIT): Deny nested RPITIT in args too
|
||||||
if proj.substs.has_escaping_bound_vars() {
|
if proj.args.has_escaping_bound_vars() {
|
||||||
bug!("FIXME(RPITIT): error here");
|
bug!("FIXME(RPITIT): error here");
|
||||||
}
|
}
|
||||||
// Replace with infer var
|
// Replace with infer var
|
||||||
|
@ -862,9 +865,9 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> {
|
||||||
span: self.span,
|
span: self.span,
|
||||||
kind: TypeVariableOriginKind::MiscVariable,
|
kind: TypeVariableOriginKind::MiscVariable,
|
||||||
});
|
});
|
||||||
self.types.insert(proj.def_id, (infer_ty, proj.substs));
|
self.types.insert(proj.def_id, (infer_ty, proj.args));
|
||||||
// Recurse into bounds
|
// Recurse into bounds
|
||||||
for (pred, pred_span) in self.interner().explicit_item_bounds(proj.def_id).subst_iter_copied(self.interner(), proj.substs) {
|
for (pred, pred_span) in self.interner().explicit_item_bounds(proj.def_id).arg_iter_copied(self.interner(), proj.args) {
|
||||||
let pred = pred.fold_with(self);
|
let pred = pred.fold_with(self);
|
||||||
let pred = self.ocx.normalize(
|
let pred = self.ocx.normalize(
|
||||||
&ObligationCause::misc(self.span, self.body_id),
|
&ObligationCause::misc(self.span, self.body_id),
|
||||||
|
@ -893,8 +896,8 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> {
|
||||||
struct RemapHiddenTyRegions<'tcx> {
|
struct RemapHiddenTyRegions<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
map: FxHashMap<ty::Region<'tcx>, ty::Region<'tcx>>,
|
map: FxHashMap<ty::Region<'tcx>, ty::Region<'tcx>>,
|
||||||
num_trait_substs: usize,
|
num_trait_args: usize,
|
||||||
num_impl_substs: usize,
|
num_impl_args: usize,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
impl_def_id: DefId,
|
impl_def_id: DefId,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
|
@ -909,16 +912,16 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||||
if let ty::Alias(ty::Opaque, ty::AliasTy { substs, def_id, .. }) = *t.kind() {
|
if let ty::Alias(ty::Opaque, ty::AliasTy { args, def_id, .. }) = *t.kind() {
|
||||||
let mut mapped_substs = Vec::with_capacity(substs.len());
|
let mut mapped_args = Vec::with_capacity(args.len());
|
||||||
for (arg, v) in std::iter::zip(substs, self.tcx.variances_of(def_id)) {
|
for (arg, v) in std::iter::zip(args, self.tcx.variances_of(def_id)) {
|
||||||
mapped_substs.push(match (arg.unpack(), v) {
|
mapped_args.push(match (arg.unpack(), v) {
|
||||||
// Skip uncaptured opaque substs
|
// Skip uncaptured opaque args
|
||||||
(ty::GenericArgKind::Lifetime(_), ty::Bivariant) => arg,
|
(ty::GenericArgKind::Lifetime(_), ty::Bivariant) => arg,
|
||||||
_ => arg.try_fold_with(self)?,
|
_ => arg.try_fold_with(self)?,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Ok(Ty::new_opaque(self.tcx, def_id, self.tcx.mk_substs(&mapped_substs)))
|
Ok(Ty::new_opaque(self.tcx, def_id, self.tcx.mk_args(&mapped_args)))
|
||||||
} else {
|
} else {
|
||||||
t.try_super_fold_with(self)
|
t.try_super_fold_with(self)
|
||||||
}
|
}
|
||||||
|
@ -975,7 +978,7 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
|
||||||
ty::EarlyBoundRegion {
|
ty::EarlyBoundRegion {
|
||||||
def_id: e.def_id,
|
def_id: e.def_id,
|
||||||
name: e.name,
|
name: e.name,
|
||||||
index: (e.index as usize - self.num_trait_substs + self.num_impl_substs) as u32,
|
index: (e.index as usize - self.num_trait_args + self.num_impl_args) as u32,
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -1214,7 +1217,7 @@ fn compare_self_type<'tcx>(
|
||||||
ty::ImplContainer => impl_trait_ref.self_ty(),
|
ty::ImplContainer => impl_trait_ref.self_ty(),
|
||||||
ty::TraitContainer => tcx.types.self_param,
|
ty::TraitContainer => tcx.types.self_param,
|
||||||
};
|
};
|
||||||
let self_arg_ty = tcx.fn_sig(method.def_id).subst_identity().input(0);
|
let self_arg_ty = tcx.fn_sig(method.def_id).instantiate_identity().input(0);
|
||||||
let param_env = ty::ParamEnv::reveal_all();
|
let param_env = ty::ParamEnv::reveal_all();
|
||||||
|
|
||||||
let infcx = tcx.infer_ctxt().build();
|
let infcx = tcx.infer_ctxt().build();
|
||||||
|
@ -1738,7 +1741,7 @@ fn compare_generic_param_kinds<'tcx>(
|
||||||
format!(
|
format!(
|
||||||
"{} const parameter of type `{}`",
|
"{} const parameter of type `{}`",
|
||||||
prefix,
|
prefix,
|
||||||
tcx.type_of(param.def_id).subst_identity()
|
tcx.type_of(param.def_id).instantiate_identity()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Type { .. } => format!("{} type parameter", prefix),
|
Type { .. } => format!("{} type parameter", prefix),
|
||||||
|
@ -1769,7 +1772,7 @@ pub(super) fn compare_impl_const_raw(
|
||||||
let impl_const_item = tcx.associated_item(impl_const_item_def);
|
let impl_const_item = tcx.associated_item(impl_const_item_def);
|
||||||
let trait_const_item = tcx.associated_item(trait_const_item_def);
|
let trait_const_item = tcx.associated_item(trait_const_item_def);
|
||||||
let impl_trait_ref =
|
let impl_trait_ref =
|
||||||
tcx.impl_trait_ref(impl_const_item.container_id(tcx)).unwrap().subst_identity();
|
tcx.impl_trait_ref(impl_const_item.container_id(tcx)).unwrap().instantiate_identity();
|
||||||
debug!("compare_const_impl(impl_trait_ref={:?})", impl_trait_ref);
|
debug!("compare_const_impl(impl_trait_ref={:?})", impl_trait_ref);
|
||||||
|
|
||||||
let impl_c_span = tcx.def_span(impl_const_item_def.to_def_id());
|
let impl_c_span = tcx.def_span(impl_const_item_def.to_def_id());
|
||||||
|
@ -1783,13 +1786,13 @@ pub(super) fn compare_impl_const_raw(
|
||||||
// because we shouldn't really have to deal with lifetimes or
|
// because we shouldn't really have to deal with lifetimes or
|
||||||
// predicates. In fact some of this should probably be put into
|
// predicates. In fact some of this should probably be put into
|
||||||
// shared functions because of DRY violations...
|
// shared functions because of DRY violations...
|
||||||
let trait_to_impl_substs = impl_trait_ref.substs;
|
let trait_to_impl_args = impl_trait_ref.args;
|
||||||
|
|
||||||
// Create a parameter environment that represents the implementation's
|
// Create a parameter environment that represents the implementation's
|
||||||
// method.
|
// method.
|
||||||
// Compute placeholder form of impl and trait const tys.
|
// Compute placeholder form of impl and trait const tys.
|
||||||
let impl_ty = tcx.type_of(impl_const_item_def.to_def_id()).subst_identity();
|
let impl_ty = tcx.type_of(impl_const_item_def.to_def_id()).instantiate_identity();
|
||||||
let trait_ty = tcx.type_of(trait_const_item_def).subst(tcx, trait_to_impl_substs);
|
let trait_ty = tcx.type_of(trait_const_item_def).instantiate(tcx, trait_to_impl_args);
|
||||||
let mut cause = ObligationCause::new(
|
let mut cause = ObligationCause::new(
|
||||||
impl_c_span,
|
impl_c_span,
|
||||||
impl_const_item_def,
|
impl_const_item_def,
|
||||||
|
@ -1885,16 +1888,16 @@ fn compare_type_predicate_entailment<'tcx>(
|
||||||
trait_ty: ty::AssocItem,
|
trait_ty: ty::AssocItem,
|
||||||
impl_trait_ref: ty::TraitRef<'tcx>,
|
impl_trait_ref: ty::TraitRef<'tcx>,
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
let impl_substs = InternalSubsts::identity_for_item(tcx, impl_ty.def_id);
|
let impl_args = GenericArgs::identity_for_item(tcx, impl_ty.def_id);
|
||||||
let trait_to_impl_substs =
|
let trait_to_impl_args =
|
||||||
impl_substs.rebase_onto(tcx, impl_ty.container_id(tcx), impl_trait_ref.substs);
|
impl_args.rebase_onto(tcx, impl_ty.container_id(tcx), impl_trait_ref.args);
|
||||||
|
|
||||||
let impl_ty_predicates = tcx.predicates_of(impl_ty.def_id);
|
let impl_ty_predicates = tcx.predicates_of(impl_ty.def_id);
|
||||||
let trait_ty_predicates = tcx.predicates_of(trait_ty.def_id);
|
let trait_ty_predicates = tcx.predicates_of(trait_ty.def_id);
|
||||||
|
|
||||||
check_region_bounds_on_impl_item(tcx, impl_ty, trait_ty, false)?;
|
check_region_bounds_on_impl_item(tcx, impl_ty, trait_ty, false)?;
|
||||||
|
|
||||||
let impl_ty_own_bounds = impl_ty_predicates.instantiate_own(tcx, impl_substs);
|
let impl_ty_own_bounds = impl_ty_predicates.instantiate_own(tcx, impl_args);
|
||||||
if impl_ty_own_bounds.len() == 0 {
|
if impl_ty_own_bounds.len() == 0 {
|
||||||
// Nothing to check.
|
// Nothing to check.
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -1904,7 +1907,7 @@ fn compare_type_predicate_entailment<'tcx>(
|
||||||
// `ObligationCause` (and the `FnCtxt`). This is what
|
// `ObligationCause` (and the `FnCtxt`). This is what
|
||||||
// `regionck_item` expects.
|
// `regionck_item` expects.
|
||||||
let impl_ty_def_id = impl_ty.def_id.expect_local();
|
let impl_ty_def_id = impl_ty.def_id.expect_local();
|
||||||
debug!("compare_type_predicate_entailment: trait_to_impl_substs={:?}", trait_to_impl_substs);
|
debug!("compare_type_predicate_entailment: trait_to_impl_args={:?}", trait_to_impl_args);
|
||||||
|
|
||||||
// The predicates declared by the impl definition, the trait and the
|
// The predicates declared by the impl definition, the trait and the
|
||||||
// associated type in the trait are assumed.
|
// associated type in the trait are assumed.
|
||||||
|
@ -1912,7 +1915,7 @@ fn compare_type_predicate_entailment<'tcx>(
|
||||||
let mut hybrid_preds = impl_predicates.instantiate_identity(tcx);
|
let mut hybrid_preds = impl_predicates.instantiate_identity(tcx);
|
||||||
hybrid_preds.predicates.extend(
|
hybrid_preds.predicates.extend(
|
||||||
trait_ty_predicates
|
trait_ty_predicates
|
||||||
.instantiate_own(tcx, trait_to_impl_substs)
|
.instantiate_own(tcx, trait_to_impl_args)
|
||||||
.map(|(predicate, _)| predicate),
|
.map(|(predicate, _)| predicate),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1990,9 +1993,9 @@ pub(super) fn check_type_bounds<'tcx>(
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// - `impl_trait_ref` would be `<(A, B) as Foo<u32>>`
|
// - `impl_trait_ref` would be `<(A, B) as Foo<u32>>`
|
||||||
// - `normalize_impl_ty_substs` would be `[A, B, ^0.0]` (`^0.0` here is the bound var with db 0 and index 0)
|
// - `normalize_impl_ty_args` would be `[A, B, ^0.0]` (`^0.0` here is the bound var with db 0 and index 0)
|
||||||
// - `normalize_impl_ty` would be `Wrapper<A, B, ^0.0>`
|
// - `normalize_impl_ty` would be `Wrapper<A, B, ^0.0>`
|
||||||
// - `rebased_substs` would be `[(A, B), u32, ^0.0]`, combining the substs from
|
// - `rebased_args` would be `[(A, B), u32, ^0.0]`, combining the args from
|
||||||
// the *trait* with the generic associated type parameters (as bound vars).
|
// the *trait* with the generic associated type parameters (as bound vars).
|
||||||
//
|
//
|
||||||
// A note regarding the use of bound vars here:
|
// A note regarding the use of bound vars here:
|
||||||
|
@ -2022,9 +2025,11 @@ pub(super) fn check_type_bounds<'tcx>(
|
||||||
// the trait (notably, that X: Eq and T: Family).
|
// the trait (notably, that X: Eq and T: Family).
|
||||||
let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> =
|
let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> =
|
||||||
smallvec::SmallVec::with_capacity(tcx.generics_of(impl_ty.def_id).params.len());
|
smallvec::SmallVec::with_capacity(tcx.generics_of(impl_ty.def_id).params.len());
|
||||||
// Extend the impl's identity substs with late-bound GAT vars
|
// Extend the impl's identity args with late-bound GAT vars
|
||||||
let normalize_impl_ty_substs = ty::InternalSubsts::identity_for_item(tcx, container_id)
|
let normalize_impl_ty_args = ty::GenericArgs::identity_for_item(tcx, container_id).extend_to(
|
||||||
.extend_to(tcx, impl_ty.def_id, |param, _| match param.kind {
|
tcx,
|
||||||
|
impl_ty.def_id,
|
||||||
|
|param, _| match param.kind {
|
||||||
GenericParamDefKind::Type { .. } => {
|
GenericParamDefKind::Type { .. } => {
|
||||||
let kind = ty::BoundTyKind::Param(param.def_id, param.name);
|
let kind = ty::BoundTyKind::Param(param.def_id, param.name);
|
||||||
let bound_var = ty::BoundVariableKind::Ty(kind);
|
let bound_var = ty::BoundVariableKind::Ty(kind);
|
||||||
|
@ -2060,7 +2065,8 @@ pub(super) fn check_type_bounds<'tcx>(
|
||||||
)
|
)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
);
|
||||||
// When checking something like
|
// When checking something like
|
||||||
//
|
//
|
||||||
// trait X { type Y: PartialEq<<Self as X>::Y> }
|
// trait X { type Y: PartialEq<<Self as X>::Y> }
|
||||||
|
@ -2070,15 +2076,14 @@ pub(super) fn check_type_bounds<'tcx>(
|
||||||
// we want <T as X>::Y to normalize to S. This is valid because we are
|
// we want <T as X>::Y to normalize to S. This is valid because we are
|
||||||
// checking the default value specifically here. Add this equality to the
|
// checking the default value specifically here. Add this equality to the
|
||||||
// ParamEnv for normalization specifically.
|
// ParamEnv for normalization specifically.
|
||||||
let normalize_impl_ty = tcx.type_of(impl_ty.def_id).subst(tcx, normalize_impl_ty_substs);
|
let normalize_impl_ty = tcx.type_of(impl_ty.def_id).instantiate(tcx, normalize_impl_ty_args);
|
||||||
let rebased_substs =
|
let rebased_args = normalize_impl_ty_args.rebase_onto(tcx, container_id, impl_trait_ref.args);
|
||||||
normalize_impl_ty_substs.rebase_onto(tcx, container_id, impl_trait_ref.substs);
|
|
||||||
let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars);
|
let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars);
|
||||||
let normalize_param_env = {
|
let normalize_param_env = {
|
||||||
let mut predicates = param_env.caller_bounds().iter().collect::<Vec<_>>();
|
let mut predicates = param_env.caller_bounds().iter().collect::<Vec<_>>();
|
||||||
match normalize_impl_ty.kind() {
|
match normalize_impl_ty.kind() {
|
||||||
ty::Alias(ty::Projection, proj)
|
ty::Alias(ty::Projection, proj)
|
||||||
if proj.def_id == trait_ty.def_id && proj.substs == rebased_substs =>
|
if proj.def_id == trait_ty.def_id && proj.args == rebased_args =>
|
||||||
{
|
{
|
||||||
// Don't include this predicate if the projected type is
|
// Don't include this predicate if the projected type is
|
||||||
// exactly the same as the projection. This can occur in
|
// exactly the same as the projection. This can occur in
|
||||||
|
@ -2089,7 +2094,7 @@ pub(super) fn check_type_bounds<'tcx>(
|
||||||
_ => predicates.push(
|
_ => predicates.push(
|
||||||
ty::Binder::bind_with_vars(
|
ty::Binder::bind_with_vars(
|
||||||
ty::ProjectionPredicate {
|
ty::ProjectionPredicate {
|
||||||
projection_ty: tcx.mk_alias_ty(trait_ty.def_id, rebased_substs),
|
projection_ty: tcx.mk_alias_ty(trait_ty.def_id, rebased_args),
|
||||||
term: normalize_impl_ty.into(),
|
term: normalize_impl_ty.into(),
|
||||||
},
|
},
|
||||||
bound_vars,
|
bound_vars,
|
||||||
|
@ -2102,8 +2107,8 @@ pub(super) fn check_type_bounds<'tcx>(
|
||||||
debug!(?normalize_param_env);
|
debug!(?normalize_param_env);
|
||||||
|
|
||||||
let impl_ty_def_id = impl_ty.def_id.expect_local();
|
let impl_ty_def_id = impl_ty.def_id.expect_local();
|
||||||
let impl_ty_substs = InternalSubsts::identity_for_item(tcx, impl_ty.def_id);
|
let impl_ty_args = GenericArgs::identity_for_item(tcx, impl_ty.def_id);
|
||||||
let rebased_substs = impl_ty_substs.rebase_onto(tcx, container_id, impl_trait_ref.substs);
|
let rebased_args = impl_ty_args.rebase_onto(tcx, container_id, impl_trait_ref.args);
|
||||||
|
|
||||||
let infcx = tcx.infer_ctxt().build();
|
let infcx = tcx.infer_ctxt().build();
|
||||||
let ocx = ObligationCtxt::new(&infcx);
|
let ocx = ObligationCtxt::new(&infcx);
|
||||||
|
@ -2144,7 +2149,7 @@ pub(super) fn check_type_bounds<'tcx>(
|
||||||
|
|
||||||
let obligations: Vec<_> = tcx
|
let obligations: Vec<_> = tcx
|
||||||
.explicit_item_bounds(trait_ty.def_id)
|
.explicit_item_bounds(trait_ty.def_id)
|
||||||
.subst_iter_copied(tcx, rebased_substs)
|
.arg_iter_copied(tcx, rebased_args)
|
||||||
.map(|(concrete_ty_bound, span)| {
|
.map(|(concrete_ty_bound, span)| {
|
||||||
debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound);
|
debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound);
|
||||||
traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound)
|
traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound)
|
||||||
|
|
|
@ -5,8 +5,8 @@ use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_errors::{struct_span_err, ErrorGuaranteed};
|
use rustc_errors::{struct_span_err, ErrorGuaranteed};
|
||||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||||
use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt};
|
use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt};
|
||||||
use rustc_middle::ty::subst::SubstsRef;
|
|
||||||
use rustc_middle::ty::util::CheckRegions;
|
use rustc_middle::ty::util::CheckRegions;
|
||||||
|
use rustc_middle::ty::GenericArgsRef;
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
use rustc_trait_selection::traits::{self, ObligationCtxt};
|
use rustc_trait_selection::traits::{self, ObligationCtxt};
|
||||||
|
|
||||||
|
@ -44,21 +44,21 @@ pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), Erro
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let dtor_self_type = tcx.type_of(drop_impl_did).subst_identity();
|
let dtor_self_type = tcx.type_of(drop_impl_did).instantiate_identity();
|
||||||
match dtor_self_type.kind() {
|
match dtor_self_type.kind() {
|
||||||
ty::Adt(adt_def, adt_to_impl_substs) => {
|
ty::Adt(adt_def, adt_to_impl_args) => {
|
||||||
ensure_drop_params_and_item_params_correspond(
|
ensure_drop_params_and_item_params_correspond(
|
||||||
tcx,
|
tcx,
|
||||||
drop_impl_did.expect_local(),
|
drop_impl_did.expect_local(),
|
||||||
adt_def.did(),
|
adt_def.did(),
|
||||||
adt_to_impl_substs,
|
adt_to_impl_args,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
ensure_drop_predicates_are_implied_by_item_defn(
|
ensure_drop_predicates_are_implied_by_item_defn(
|
||||||
tcx,
|
tcx,
|
||||||
drop_impl_did.expect_local(),
|
drop_impl_did.expect_local(),
|
||||||
adt_def.did().expect_local(),
|
adt_def.did().expect_local(),
|
||||||
adt_to_impl_substs,
|
adt_to_impl_args,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -79,9 +79,9 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
drop_impl_did: LocalDefId,
|
drop_impl_did: LocalDefId,
|
||||||
self_type_did: DefId,
|
self_type_did: DefId,
|
||||||
adt_to_impl_substs: SubstsRef<'tcx>,
|
adt_to_impl_args: GenericArgsRef<'tcx>,
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_substs, CheckRegions::OnlyEarlyBound)
|
let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_args, CheckRegions::OnlyEarlyBound)
|
||||||
else {
|
else {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
|
@ -115,12 +115,12 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
drop_impl_def_id: LocalDefId,
|
drop_impl_def_id: LocalDefId,
|
||||||
adt_def_id: LocalDefId,
|
adt_def_id: LocalDefId,
|
||||||
adt_to_impl_substs: SubstsRef<'tcx>,
|
adt_to_impl_args: GenericArgsRef<'tcx>,
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
let infcx = tcx.infer_ctxt().build();
|
let infcx = tcx.infer_ctxt().build();
|
||||||
let ocx = ObligationCtxt::new(&infcx);
|
let ocx = ObligationCtxt::new(&infcx);
|
||||||
|
|
||||||
// Take the param-env of the adt and substitute the substs that show up in
|
// Take the param-env of the adt and substitute the args that show up in
|
||||||
// the implementation's self type. This gives us the assumptions that the
|
// the implementation's self type. This gives us the assumptions that the
|
||||||
// self ty of the implementation is allowed to know just from it being a
|
// self ty of the implementation is allowed to know just from it being a
|
||||||
// well-formed adt, since that's all we're allowed to assume while proving
|
// well-formed adt, since that's all we're allowed to assume while proving
|
||||||
|
@ -130,7 +130,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
|
||||||
// substituting it with free params, so no additional param-env normalization
|
// substituting it with free params, so no additional param-env normalization
|
||||||
// can occur on top of what has been done in the param_env query itself.
|
// can occur on top of what has been done in the param_env query itself.
|
||||||
let param_env = ty::EarlyBinder::bind(tcx.param_env(adt_def_id))
|
let param_env = ty::EarlyBinder::bind(tcx.param_env(adt_def_id))
|
||||||
.subst(tcx, adt_to_impl_substs)
|
.instantiate(tcx, adt_to_impl_args)
|
||||||
.with_constness(tcx.constness(drop_impl_def_id));
|
.with_constness(tcx.constness(drop_impl_def_id));
|
||||||
|
|
||||||
for (pred, span) in tcx.predicates_of(drop_impl_def_id).instantiate_identity(tcx) {
|
for (pred, span) in tcx.predicates_of(drop_impl_def_id).instantiate_identity(tcx) {
|
||||||
|
|
|
@ -60,7 +60,7 @@ fn equate_intrinsic_type<'tcx>(
|
||||||
tcx,
|
tcx,
|
||||||
&cause,
|
&cause,
|
||||||
ty::ParamEnv::empty(), // FIXME: do all intrinsics have an empty param env?
|
ty::ParamEnv::empty(), // FIXME: do all intrinsics have an empty param env?
|
||||||
Ty::new_fn_ptr(tcx, tcx.fn_sig(it.owner_id).subst_identity()),
|
Ty::new_fn_ptr(tcx, tcx.fn_sig(it.owner_id).instantiate_identity()),
|
||||||
fty,
|
fty,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
|
||||||
ty::INNERMOST,
|
ty::INNERMOST,
|
||||||
ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrEnv },
|
ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrEnv },
|
||||||
);
|
);
|
||||||
let va_list_ty = tcx.type_of(did).subst(tcx, &[region.into()]);
|
let va_list_ty = tcx.type_of(did).instantiate(tcx, &[region.into()]);
|
||||||
(Ty::new_ref(tcx, env_region, ty::TypeAndMut { ty: va_list_ty, mutbl }), va_list_ty)
|
(Ty::new_ref(tcx, env_region, ty::TypeAndMut { ty: va_list_ty, mutbl }), va_list_ty)
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
@ -238,7 +238,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
|
||||||
ty: Ty::new_adt(
|
ty: Ty::new_adt(
|
||||||
tcx,
|
tcx,
|
||||||
tcx.adt_def(option_def_id),
|
tcx.adt_def(option_def_id),
|
||||||
tcx.mk_substs_from_iter([ty::GenericArg::from(p0)].into_iter()),
|
tcx.mk_args_from_iter([ty::GenericArg::from(p0)].into_iter()),
|
||||||
),
|
),
|
||||||
mutbl: hir::Mutability::Not,
|
mutbl: hir::Mutability::Not,
|
||||||
},
|
},
|
||||||
|
@ -412,7 +412,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
|
||||||
ty::Region::new_late_bound(tcx, ty::INNERMOST, br),
|
ty::Region::new_late_bound(tcx, ty::INNERMOST, br),
|
||||||
param(0),
|
param(0),
|
||||||
)],
|
)],
|
||||||
Ty::new_projection(tcx, discriminant_def_id, tcx.mk_substs(&[param(0).into()])),
|
Ty::new_projection(tcx, discriminant_def_id, tcx.mk_args(&[param(0).into()])),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,9 +81,9 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||||
ty::RawPtr(ty::TypeAndMut { ty, mutbl: _ }) if self.is_thin_ptr_ty(ty) => {
|
ty::RawPtr(ty::TypeAndMut { ty, mutbl: _ }) if self.is_thin_ptr_ty(ty) => {
|
||||||
Some(asm_ty_isize)
|
Some(asm_ty_isize)
|
||||||
}
|
}
|
||||||
ty::Adt(adt, substs) if adt.repr().simd() => {
|
ty::Adt(adt, args) if adt.repr().simd() => {
|
||||||
let fields = &adt.non_enum_variant().fields;
|
let fields = &adt.non_enum_variant().fields;
|
||||||
let elem_ty = fields[FieldIdx::from_u32(0)].ty(self.tcx, substs);
|
let elem_ty = fields[FieldIdx::from_u32(0)].ty(self.tcx, args);
|
||||||
|
|
||||||
let (size, ty) = match elem_ty.kind() {
|
let (size, ty) = match elem_ty.kind() {
|
||||||
ty::Array(ty, len) => {
|
ty::Array(ty, len) => {
|
||||||
|
@ -423,7 +423,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||||
// Check that sym actually points to a function. Later passes
|
// Check that sym actually points to a function. Later passes
|
||||||
// depend on this.
|
// depend on this.
|
||||||
hir::InlineAsmOperand::SymFn { anon_const } => {
|
hir::InlineAsmOperand::SymFn { anon_const } => {
|
||||||
let ty = self.tcx.type_of(anon_const.def_id).subst_identity();
|
let ty = self.tcx.type_of(anon_const.def_id).instantiate_identity();
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
ty::Never | ty::Error(_) => {}
|
ty::Never | ty::Error(_) => {}
|
||||||
ty::FnDef(..) => {}
|
ty::FnDef(..) => {}
|
||||||
|
|
|
@ -38,7 +38,7 @@ can be broken down into several distinct phases:
|
||||||
|
|
||||||
While type checking a function, the intermediate types for the
|
While type checking a function, the intermediate types for the
|
||||||
expressions, blocks, and so forth contained within the function are
|
expressions, blocks, and so forth contained within the function are
|
||||||
stored in `fcx.node_types` and `fcx.node_substs`. These types
|
stored in `fcx.node_types` and `fcx.node_args`. These types
|
||||||
may contain unresolved type variables. After type checking is
|
may contain unresolved type variables. After type checking is
|
||||||
complete, the functions in the writeback module are used to take the
|
complete, the functions in the writeback module are used to take the
|
||||||
types from this table, resolve them, and then write them into their
|
types from this table, resolve them, and then write them into their
|
||||||
|
@ -80,7 +80,7 @@ use rustc_hir::intravisit::Visitor;
|
||||||
use rustc_index::bit_set::BitSet;
|
use rustc_index::bit_set::BitSet;
|
||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_middle::ty::{InternalSubsts, SubstsRef};
|
use rustc_middle::ty::{GenericArgs, GenericArgsRef};
|
||||||
use rustc_session::parse::feature_err;
|
use rustc_session::parse::feature_err;
|
||||||
use rustc_span::source_map::DUMMY_SP;
|
use rustc_span::source_map::DUMMY_SP;
|
||||||
use rustc_span::symbol::{kw, Ident};
|
use rustc_span::symbol::{kw, Ident};
|
||||||
|
@ -211,7 +211,7 @@ fn missing_items_err(
|
||||||
let snippet = suggestion_signature(
|
let snippet = suggestion_signature(
|
||||||
tcx,
|
tcx,
|
||||||
trait_item,
|
trait_item,
|
||||||
tcx.impl_trait_ref(impl_def_id).unwrap().subst_identity(),
|
tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity(),
|
||||||
);
|
);
|
||||||
let code = format!("{}{}\n{}", padding, snippet, padding);
|
let code = format!("{}{}\n{}", padding, snippet, padding);
|
||||||
if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
|
if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
|
||||||
|
@ -408,7 +408,7 @@ fn fn_sig_suggestion<'tcx>(
|
||||||
let asyncness = if tcx.asyncness(assoc.def_id).is_async() {
|
let asyncness = if tcx.asyncness(assoc.def_id).is_async() {
|
||||||
output = if let ty::Alias(_, alias_ty) = *output.kind() {
|
output = if let ty::Alias(_, alias_ty) = *output.kind() {
|
||||||
tcx.explicit_item_bounds(alias_ty.def_id)
|
tcx.explicit_item_bounds(alias_ty.def_id)
|
||||||
.subst_iter_copied(tcx, alias_ty.substs)
|
.arg_iter_copied(tcx, alias_ty.args)
|
||||||
.find_map(|(bound, _)| bound.as_projection_clause()?.no_bound_vars()?.term.ty())
|
.find_map(|(bound, _)| bound.as_projection_clause()?.no_bound_vars()?.term.ty())
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
span_bug!(
|
span_bug!(
|
||||||
|
@ -461,10 +461,10 @@ fn suggestion_signature<'tcx>(
|
||||||
assoc: ty::AssocItem,
|
assoc: ty::AssocItem,
|
||||||
impl_trait_ref: ty::TraitRef<'tcx>,
|
impl_trait_ref: ty::TraitRef<'tcx>,
|
||||||
) -> String {
|
) -> String {
|
||||||
let substs = ty::InternalSubsts::identity_for_item(tcx, assoc.def_id).rebase_onto(
|
let args = ty::GenericArgs::identity_for_item(tcx, assoc.def_id).rebase_onto(
|
||||||
tcx,
|
tcx,
|
||||||
assoc.container_id(tcx),
|
assoc.container_id(tcx),
|
||||||
impl_trait_ref.with_self_ty(tcx, tcx.types.self_param).substs,
|
impl_trait_ref.with_self_ty(tcx, tcx.types.self_param).args,
|
||||||
);
|
);
|
||||||
|
|
||||||
match assoc.kind {
|
match assoc.kind {
|
||||||
|
@ -472,21 +472,21 @@ fn suggestion_signature<'tcx>(
|
||||||
tcx,
|
tcx,
|
||||||
tcx.liberate_late_bound_regions(
|
tcx.liberate_late_bound_regions(
|
||||||
assoc.def_id,
|
assoc.def_id,
|
||||||
tcx.fn_sig(assoc.def_id).subst(tcx, substs),
|
tcx.fn_sig(assoc.def_id).instantiate(tcx, args),
|
||||||
),
|
),
|
||||||
assoc.ident(tcx),
|
assoc.ident(tcx),
|
||||||
tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs),
|
tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args),
|
||||||
assoc,
|
assoc,
|
||||||
),
|
),
|
||||||
ty::AssocKind::Type => {
|
ty::AssocKind::Type => {
|
||||||
let (generics, where_clauses) = bounds_from_generic_predicates(
|
let (generics, where_clauses) = bounds_from_generic_predicates(
|
||||||
tcx,
|
tcx,
|
||||||
tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs),
|
tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args),
|
||||||
);
|
);
|
||||||
format!("type {}{generics} = /* Type */{where_clauses};", assoc.name)
|
format!("type {}{generics} = /* Type */{where_clauses};", assoc.name)
|
||||||
}
|
}
|
||||||
ty::AssocKind::Const => {
|
ty::AssocKind::Const => {
|
||||||
let ty = tcx.type_of(assoc.def_id).subst_identity();
|
let ty = tcx.type_of(assoc.def_id).instantiate_identity();
|
||||||
let val = ty_kind_suggestion(ty).unwrap_or("todo!()");
|
let val = ty_kind_suggestion(ty).unwrap_or("todo!()");
|
||||||
format!("const {}: {} = {};", assoc.name, ty, val)
|
format!("const {}: {} = {};", assoc.name, ty, val)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ use rustc_middle::ty::{
|
||||||
self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
|
self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
|
||||||
TypeVisitable, TypeVisitableExt, TypeVisitor,
|
TypeVisitable, TypeVisitableExt, TypeVisitor,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::{GenericArgKind, InternalSubsts};
|
use rustc_middle::ty::{GenericArgKind, GenericArgs};
|
||||||
use rustc_session::parse::feature_err;
|
use rustc_session::parse::feature_err;
|
||||||
use rustc_span::symbol::{sym, Ident, Symbol};
|
use rustc_span::symbol::{sym, Ident, Symbol};
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
|
@ -290,7 +290,7 @@ fn check_trait_item(tcx: TyCtxt<'_>, trait_item: &hir::TraitItem<'_>) {
|
||||||
|
|
||||||
/// Require that the user writes where clauses on GATs for the implicit
|
/// Require that the user writes where clauses on GATs for the implicit
|
||||||
/// outlives bounds involving trait parameters in trait functions and
|
/// outlives bounds involving trait parameters in trait functions and
|
||||||
/// lifetimes passed as GAT substs. See `self-outlives-lint` test.
|
/// lifetimes passed as GAT args. See `self-outlives-lint` test.
|
||||||
///
|
///
|
||||||
/// We use the following trait as an example throughout this function:
|
/// We use the following trait as an example throughout this function:
|
||||||
/// ```rust,ignore (this code fails due to this lint)
|
/// ```rust,ignore (this code fails due to this lint)
|
||||||
|
@ -314,7 +314,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
|
||||||
for gat_item in associated_items {
|
for gat_item in associated_items {
|
||||||
let gat_def_id = gat_item.id.owner_id;
|
let gat_def_id = gat_item.id.owner_id;
|
||||||
let gat_item = tcx.associated_item(gat_def_id);
|
let gat_item = tcx.associated_item(gat_def_id);
|
||||||
// If this item is not an assoc ty, or has no substs, then it's not a GAT
|
// If this item is not an assoc ty, or has no args, then it's not a GAT
|
||||||
if gat_item.kind != ty::AssocKind::Type {
|
if gat_item.kind != ty::AssocKind::Type {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -345,7 +345,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
|
||||||
// `Self::Iter<'a>` is a GAT we want to gather any potential missing bounds from.
|
// `Self::Iter<'a>` is a GAT we want to gather any potential missing bounds from.
|
||||||
let sig: ty::FnSig<'_> = tcx.liberate_late_bound_regions(
|
let sig: ty::FnSig<'_> = tcx.liberate_late_bound_regions(
|
||||||
item_def_id.to_def_id(),
|
item_def_id.to_def_id(),
|
||||||
tcx.fn_sig(item_def_id).subst_identity(),
|
tcx.fn_sig(item_def_id).instantiate_identity(),
|
||||||
);
|
);
|
||||||
gather_gat_bounds(
|
gather_gat_bounds(
|
||||||
tcx,
|
tcx,
|
||||||
|
@ -374,7 +374,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
|
||||||
param_env,
|
param_env,
|
||||||
item_def_id,
|
item_def_id,
|
||||||
tcx.explicit_item_bounds(item_def_id)
|
tcx.explicit_item_bounds(item_def_id)
|
||||||
.subst_identity_iter_copied()
|
.instantiate_identity_iter_copied()
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
&FxIndexSet::default(),
|
&FxIndexSet::default(),
|
||||||
gat_def_id.def_id,
|
gat_def_id.def_id,
|
||||||
|
@ -737,7 +737,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GATSubstCollector<'tcx> {
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||||
match t.kind() {
|
match t.kind() {
|
||||||
ty::Alias(ty::Projection, p) if p.def_id == self.gat => {
|
ty::Alias(ty::Projection, p) if p.def_id == self.gat => {
|
||||||
for (idx, subst) in p.substs.iter().enumerate() {
|
for (idx, subst) in p.args.iter().enumerate() {
|
||||||
match subst.unpack() {
|
match subst.unpack() {
|
||||||
GenericArgKind::Lifetime(lt) if !lt.is_late_bound() => {
|
GenericArgKind::Lifetime(lt) if !lt.is_late_bound() => {
|
||||||
self.regions.insert((lt, idx));
|
self.regions.insert((lt, idx));
|
||||||
|
@ -836,7 +836,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
|
||||||
|
|
||||||
// Const parameters are well formed if their type is structural match.
|
// Const parameters are well formed if their type is structural match.
|
||||||
hir::GenericParamKind::Const { ty: hir_ty, default: _ } => {
|
hir::GenericParamKind::Const { ty: hir_ty, default: _ } => {
|
||||||
let ty = tcx.type_of(param.def_id).subst_identity();
|
let ty = tcx.type_of(param.def_id).instantiate_identity();
|
||||||
|
|
||||||
if tcx.features().adt_const_params {
|
if tcx.features().adt_const_params {
|
||||||
enter_wf_checking_ctxt(tcx, hir_ty.span, param.def_id, |wfcx| {
|
enter_wf_checking_ctxt(tcx, hir_ty.span, param.def_id, |wfcx| {
|
||||||
|
@ -910,17 +910,17 @@ fn check_associated_item(
|
||||||
|
|
||||||
let self_ty = match item.container {
|
let self_ty = match item.container {
|
||||||
ty::TraitContainer => tcx.types.self_param,
|
ty::TraitContainer => tcx.types.self_param,
|
||||||
ty::ImplContainer => tcx.type_of(item.container_id(tcx)).subst_identity(),
|
ty::ImplContainer => tcx.type_of(item.container_id(tcx)).instantiate_identity(),
|
||||||
};
|
};
|
||||||
|
|
||||||
match item.kind {
|
match item.kind {
|
||||||
ty::AssocKind::Const => {
|
ty::AssocKind::Const => {
|
||||||
let ty = tcx.type_of(item.def_id).subst_identity();
|
let ty = tcx.type_of(item.def_id).instantiate_identity();
|
||||||
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
|
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
|
||||||
wfcx.register_wf_obligation(span, loc, ty.into());
|
wfcx.register_wf_obligation(span, loc, ty.into());
|
||||||
}
|
}
|
||||||
ty::AssocKind::Fn => {
|
ty::AssocKind::Fn => {
|
||||||
let sig = tcx.fn_sig(item.def_id).subst_identity();
|
let sig = tcx.fn_sig(item.def_id).instantiate_identity();
|
||||||
let hir_sig = sig_if_method.expect("bad signature for method");
|
let hir_sig = sig_if_method.expect("bad signature for method");
|
||||||
check_fn_or_method(
|
check_fn_or_method(
|
||||||
wfcx,
|
wfcx,
|
||||||
|
@ -936,7 +936,7 @@ fn check_associated_item(
|
||||||
check_associated_type_bounds(wfcx, item, span)
|
check_associated_type_bounds(wfcx, item, span)
|
||||||
}
|
}
|
||||||
if item.defaultness(tcx).has_value() {
|
if item.defaultness(tcx).has_value() {
|
||||||
let ty = tcx.type_of(item.def_id).subst_identity();
|
let ty = tcx.type_of(item.def_id).instantiate_identity();
|
||||||
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
|
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
|
||||||
wfcx.register_wf_obligation(span, loc, ty.into());
|
wfcx.register_wf_obligation(span, loc, ty.into());
|
||||||
}
|
}
|
||||||
|
@ -969,7 +969,11 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b
|
||||||
let field_id = field.did.expect_local();
|
let field_id = field.did.expect_local();
|
||||||
let hir::FieldDef { ty: hir_ty, .. } =
|
let hir::FieldDef { ty: hir_ty, .. } =
|
||||||
tcx.hir().get_by_def_id(field_id).expect_field();
|
tcx.hir().get_by_def_id(field_id).expect_field();
|
||||||
let ty = wfcx.normalize(hir_ty.span, None, tcx.type_of(field.did).subst_identity());
|
let ty = wfcx.normalize(
|
||||||
|
hir_ty.span,
|
||||||
|
None,
|
||||||
|
tcx.type_of(field.did).instantiate_identity(),
|
||||||
|
);
|
||||||
wfcx.register_wf_obligation(
|
wfcx.register_wf_obligation(
|
||||||
hir_ty.span,
|
hir_ty.span,
|
||||||
Some(WellFormedLoc::Ty(field_id)),
|
Some(WellFormedLoc::Ty(field_id)),
|
||||||
|
@ -981,7 +985,7 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b
|
||||||
// intermediate types must be sized.
|
// intermediate types must be sized.
|
||||||
let needs_drop_copy = || {
|
let needs_drop_copy = || {
|
||||||
packed && {
|
packed && {
|
||||||
let ty = tcx.type_of(variant.tail().did).subst_identity();
|
let ty = tcx.type_of(variant.tail().did).instantiate_identity();
|
||||||
let ty = tcx.erase_regions(ty);
|
let ty = tcx.erase_regions(ty);
|
||||||
if ty.has_infer() {
|
if ty.has_infer() {
|
||||||
tcx.sess
|
tcx.sess
|
||||||
|
@ -1003,7 +1007,11 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b
|
||||||
let field_id = field.did.expect_local();
|
let field_id = field.did.expect_local();
|
||||||
let hir::FieldDef { ty: hir_ty, .. } =
|
let hir::FieldDef { ty: hir_ty, .. } =
|
||||||
tcx.hir().get_by_def_id(field_id).expect_field();
|
tcx.hir().get_by_def_id(field_id).expect_field();
|
||||||
let ty = wfcx.normalize(hir_ty.span, None, tcx.type_of(field.did).subst_identity());
|
let ty = wfcx.normalize(
|
||||||
|
hir_ty.span,
|
||||||
|
None,
|
||||||
|
tcx.type_of(field.did).instantiate_identity(),
|
||||||
|
);
|
||||||
wfcx.register_bound(
|
wfcx.register_bound(
|
||||||
traits::ObligationCause::new(
|
traits::ObligationCause::new(
|
||||||
hir_ty.span,
|
hir_ty.span,
|
||||||
|
@ -1083,16 +1091,17 @@ fn check_associated_type_bounds(wfcx: &WfCheckingCtxt<'_, '_>, item: ty::AssocIt
|
||||||
let bounds = wfcx.tcx().explicit_item_bounds(item.def_id);
|
let bounds = wfcx.tcx().explicit_item_bounds(item.def_id);
|
||||||
|
|
||||||
debug!("check_associated_type_bounds: bounds={:?}", bounds);
|
debug!("check_associated_type_bounds: bounds={:?}", bounds);
|
||||||
let wf_obligations = bounds.subst_identity_iter_copied().flat_map(|(bound, bound_span)| {
|
let wf_obligations =
|
||||||
let normalized_bound = wfcx.normalize(span, None, bound);
|
bounds.instantiate_identity_iter_copied().flat_map(|(bound, bound_span)| {
|
||||||
traits::wf::predicate_obligations(
|
let normalized_bound = wfcx.normalize(span, None, bound);
|
||||||
wfcx.infcx,
|
traits::wf::predicate_obligations(
|
||||||
wfcx.param_env,
|
wfcx.infcx,
|
||||||
wfcx.body_def_id,
|
wfcx.param_env,
|
||||||
normalized_bound.as_predicate(),
|
wfcx.body_def_id,
|
||||||
bound_span,
|
normalized_bound.as_predicate(),
|
||||||
)
|
bound_span,
|
||||||
});
|
)
|
||||||
|
});
|
||||||
|
|
||||||
wfcx.register_obligations(wf_obligations);
|
wfcx.register_obligations(wf_obligations);
|
||||||
}
|
}
|
||||||
|
@ -1105,7 +1114,7 @@ fn check_item_fn(
|
||||||
decl: &hir::FnDecl<'_>,
|
decl: &hir::FnDecl<'_>,
|
||||||
) {
|
) {
|
||||||
enter_wf_checking_ctxt(tcx, span, def_id, |wfcx| {
|
enter_wf_checking_ctxt(tcx, span, def_id, |wfcx| {
|
||||||
let sig = tcx.fn_sig(def_id).subst_identity();
|
let sig = tcx.fn_sig(def_id).instantiate_identity();
|
||||||
check_fn_or_method(wfcx, ident.span, sig, decl, def_id);
|
check_fn_or_method(wfcx, ident.span, sig, decl, def_id);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1125,7 +1134,7 @@ fn check_item_type(
|
||||||
debug!("check_item_type: {:?}", item_id);
|
debug!("check_item_type: {:?}", item_id);
|
||||||
|
|
||||||
enter_wf_checking_ctxt(tcx, ty_span, item_id, |wfcx| {
|
enter_wf_checking_ctxt(tcx, ty_span, item_id, |wfcx| {
|
||||||
let ty = tcx.type_of(item_id).subst_identity();
|
let ty = tcx.type_of(item_id).instantiate_identity();
|
||||||
let item_ty = wfcx.normalize(ty_span, Some(WellFormedLoc::Ty(item_id)), ty);
|
let item_ty = wfcx.normalize(ty_span, Some(WellFormedLoc::Ty(item_id)), ty);
|
||||||
|
|
||||||
let forbid_unsized = match unsized_handling {
|
let forbid_unsized = match unsized_handling {
|
||||||
|
@ -1178,7 +1187,7 @@ fn check_impl<'tcx>(
|
||||||
// `#[rustc_reservation_impl]` impls are not real impls and
|
// `#[rustc_reservation_impl]` impls are not real impls and
|
||||||
// therefore don't need to be WF (the trait's `Self: Trait` predicate
|
// therefore don't need to be WF (the trait's `Self: Trait` predicate
|
||||||
// won't hold).
|
// won't hold).
|
||||||
let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap().subst_identity();
|
let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap().instantiate_identity();
|
||||||
let trait_ref = wfcx.normalize(
|
let trait_ref = wfcx.normalize(
|
||||||
ast_trait_ref.path.span,
|
ast_trait_ref.path.span,
|
||||||
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
|
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
|
||||||
|
@ -1211,7 +1220,7 @@ fn check_impl<'tcx>(
|
||||||
wfcx.register_obligations(obligations);
|
wfcx.register_obligations(obligations);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let self_ty = tcx.type_of(item.owner_id).subst_identity();
|
let self_ty = tcx.type_of(item.owner_id).instantiate_identity();
|
||||||
let self_ty = wfcx.normalize(
|
let self_ty = wfcx.normalize(
|
||||||
item.span,
|
item.span,
|
||||||
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
|
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
|
||||||
|
@ -1256,7 +1265,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
|
||||||
match param.kind {
|
match param.kind {
|
||||||
GenericParamDefKind::Type { .. } => {
|
GenericParamDefKind::Type { .. } => {
|
||||||
if is_our_default(param) {
|
if is_our_default(param) {
|
||||||
let ty = tcx.type_of(param.def_id).subst_identity();
|
let ty = tcx.type_of(param.def_id).instantiate_identity();
|
||||||
// Ignore dependent defaults -- that is, where the default of one type
|
// Ignore dependent defaults -- that is, where the default of one type
|
||||||
// parameter includes another (e.g., `<T, U = T>`). In those cases, we can't
|
// parameter includes another (e.g., `<T, U = T>`). In those cases, we can't
|
||||||
// be sure if it will error or not as user might always specify the other.
|
// be sure if it will error or not as user might always specify the other.
|
||||||
|
@ -1272,10 +1281,10 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
|
||||||
GenericParamDefKind::Const { .. } => {
|
GenericParamDefKind::Const { .. } => {
|
||||||
if is_our_default(param) {
|
if is_our_default(param) {
|
||||||
// FIXME(const_generics_defaults): This
|
// FIXME(const_generics_defaults): This
|
||||||
// is incorrect when dealing with unused substs, for example
|
// is incorrect when dealing with unused args, for example
|
||||||
// for `struct Foo<const N: usize, const M: usize = { 1 - 2 }>`
|
// for `struct Foo<const N: usize, const M: usize = { 1 - 2 }>`
|
||||||
// we should eagerly error.
|
// we should eagerly error.
|
||||||
let default_ct = tcx.const_param_default(param.def_id).subst_identity();
|
let default_ct = tcx.const_param_default(param.def_id).instantiate_identity();
|
||||||
if !default_ct.has_param() {
|
if !default_ct.has_param() {
|
||||||
wfcx.register_wf_obligation(
|
wfcx.register_wf_obligation(
|
||||||
tcx.def_span(param.def_id),
|
tcx.def_span(param.def_id),
|
||||||
|
@ -1298,7 +1307,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
|
||||||
// For more examples see tests `defaults-well-formedness.rs` and `type-check-defaults.rs`.
|
// For more examples see tests `defaults-well-formedness.rs` and `type-check-defaults.rs`.
|
||||||
//
|
//
|
||||||
// First we build the defaulted substitution.
|
// First we build the defaulted substitution.
|
||||||
let substs = InternalSubsts::for_item(tcx, def_id.to_def_id(), |param, _| {
|
let args = GenericArgs::for_item(tcx, def_id.to_def_id(), |param, _| {
|
||||||
match param.kind {
|
match param.kind {
|
||||||
GenericParamDefKind::Lifetime => {
|
GenericParamDefKind::Lifetime => {
|
||||||
// All regions are identity.
|
// All regions are identity.
|
||||||
|
@ -1308,7 +1317,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
|
||||||
GenericParamDefKind::Type { .. } => {
|
GenericParamDefKind::Type { .. } => {
|
||||||
// If the param has a default, ...
|
// If the param has a default, ...
|
||||||
if is_our_default(param) {
|
if is_our_default(param) {
|
||||||
let default_ty = tcx.type_of(param.def_id).subst_identity();
|
let default_ty = tcx.type_of(param.def_id).instantiate_identity();
|
||||||
// ... and it's not a dependent default, ...
|
// ... and it's not a dependent default, ...
|
||||||
if !default_ty.has_param() {
|
if !default_ty.has_param() {
|
||||||
// ... then substitute it with the default.
|
// ... then substitute it with the default.
|
||||||
|
@ -1321,7 +1330,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
|
||||||
GenericParamDefKind::Const { .. } => {
|
GenericParamDefKind::Const { .. } => {
|
||||||
// If the param has a default, ...
|
// If the param has a default, ...
|
||||||
if is_our_default(param) {
|
if is_our_default(param) {
|
||||||
let default_ct = tcx.const_param_default(param.def_id).subst_identity();
|
let default_ct = tcx.const_param_default(param.def_id).instantiate_identity();
|
||||||
// ... and it's not a dependent default, ...
|
// ... and it's not a dependent default, ...
|
||||||
if !default_ct.has_param() {
|
if !default_ct.has_param() {
|
||||||
// ... then substitute it with the default.
|
// ... then substitute it with the default.
|
||||||
|
@ -1366,7 +1375,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
|
||||||
}
|
}
|
||||||
let mut param_count = CountParams::default();
|
let mut param_count = CountParams::default();
|
||||||
let has_region = pred.visit_with(&mut param_count).is_break();
|
let has_region = pred.visit_with(&mut param_count).is_break();
|
||||||
let substituted_pred = ty::EarlyBinder::bind(pred).subst(tcx, substs);
|
let substituted_pred = ty::EarlyBinder::bind(pred).instantiate(tcx, args);
|
||||||
// Don't check non-defaulted params, dependent defaults (including lifetimes)
|
// Don't check non-defaulted params, dependent defaults (including lifetimes)
|
||||||
// or preds with multiple params.
|
// or preds with multiple params.
|
||||||
if substituted_pred.has_non_region_param() || param_count.params.len() > 1 || has_region
|
if substituted_pred.has_non_region_param() || param_count.params.len() > 1 || has_region
|
||||||
|
@ -1529,7 +1538,7 @@ fn check_return_position_impl_trait_in_trait_bounds<'tcx>(
|
||||||
// strategy, we can't just call `check_associated_item` on the new RPITITs,
|
// strategy, we can't just call `check_associated_item` on the new RPITITs,
|
||||||
// because tests like `tests/ui/async-await/in-trait/implied-bounds.rs` will fail.
|
// because tests like `tests/ui/async-await/in-trait/implied-bounds.rs` will fail.
|
||||||
// That's because we need to check that the bounds of the RPITIT hold using
|
// That's because we need to check that the bounds of the RPITIT hold using
|
||||||
// the special substs that we create during opaque type lowering, otherwise we're
|
// the special args that we create during opaque type lowering, otherwise we're
|
||||||
// getting a bunch of early bound and free regions mixed up... Haven't looked too
|
// getting a bunch of early bound and free regions mixed up... Haven't looked too
|
||||||
// deep into this, though.
|
// deep into this, though.
|
||||||
struct ImplTraitInTraitFinder<'a, 'tcx> {
|
struct ImplTraitInTraitFinder<'a, 'tcx> {
|
||||||
|
@ -1558,7 +1567,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
|
||||||
});
|
});
|
||||||
for (bound, bound_span) in tcx
|
for (bound, bound_span) in tcx
|
||||||
.explicit_item_bounds(opaque_ty.def_id)
|
.explicit_item_bounds(opaque_ty.def_id)
|
||||||
.subst_iter_copied(tcx, opaque_ty.substs)
|
.arg_iter_copied(tcx, opaque_ty.args)
|
||||||
{
|
{
|
||||||
let bound = self.wfcx.normalize(bound_span, None, bound);
|
let bound = self.wfcx.normalize(bound_span, None, bound);
|
||||||
self.wfcx.register_obligations(traits::wf::predicate_obligations(
|
self.wfcx.register_obligations(traits::wf::predicate_obligations(
|
||||||
|
@ -1569,7 +1578,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
|
||||||
bound_span,
|
bound_span,
|
||||||
));
|
));
|
||||||
// Set the debruijn index back to innermost here, since we already eagerly
|
// Set the debruijn index back to innermost here, since we already eagerly
|
||||||
// shifted the substs that we use to generate these bounds. This is unfortunately
|
// shifted the args that we use to generate these bounds. This is unfortunately
|
||||||
// subtly different behavior than the `ImplTraitInTraitFinder` we use in `param_env`,
|
// subtly different behavior than the `ImplTraitInTraitFinder` we use in `param_env`,
|
||||||
// but that function doesn't actually need to normalize the bound it's visiting
|
// but that function doesn't actually need to normalize the bound it's visiting
|
||||||
// (whereas we have to do so here)...
|
// (whereas we have to do so here)...
|
||||||
|
@ -1601,7 +1610,7 @@ fn check_method_receiver<'tcx>(
|
||||||
|
|
||||||
let span = fn_sig.decl.inputs[0].span;
|
let span = fn_sig.decl.inputs[0].span;
|
||||||
|
|
||||||
let sig = tcx.fn_sig(method.def_id).subst_identity();
|
let sig = tcx.fn_sig(method.def_id).instantiate_identity();
|
||||||
let sig = tcx.liberate_late_bound_regions(method.def_id, sig);
|
let sig = tcx.liberate_late_bound_regions(method.def_id, sig);
|
||||||
let sig = wfcx.normalize(span, None, sig);
|
let sig = wfcx.normalize(span, None, sig);
|
||||||
|
|
||||||
|
@ -1773,9 +1782,9 @@ fn check_variances_for_type_defn<'tcx>(
|
||||||
item: &hir::Item<'tcx>,
|
item: &hir::Item<'tcx>,
|
||||||
hir_generics: &hir::Generics<'_>,
|
hir_generics: &hir::Generics<'_>,
|
||||||
) {
|
) {
|
||||||
let identity_substs = ty::InternalSubsts::identity_for_item(tcx, item.owner_id);
|
let identity_args = ty::GenericArgs::identity_for_item(tcx, item.owner_id);
|
||||||
for field in tcx.adt_def(item.owner_id).all_fields() {
|
for field in tcx.adt_def(item.owner_id).all_fields() {
|
||||||
if field.ty(tcx, identity_substs).references_error() {
|
if field.ty(tcx, identity_args).references_error() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ impl<'tcx> Checker<'tcx> {
|
||||||
|
|
||||||
fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
|
fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
|
||||||
// Destructors only work on local ADT types.
|
// Destructors only work on local ADT types.
|
||||||
match tcx.type_of(impl_did).subst_identity().kind() {
|
match tcx.type_of(impl_did).instantiate_identity().kind() {
|
||||||
ty::Adt(def, _) if def.did().is_local() => return,
|
ty::Adt(def, _) if def.did().is_local() => return,
|
||||||
ty::Error(_) => return,
|
ty::Error(_) => return,
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -71,7 +71,7 @@ fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
|
||||||
fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
|
fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
|
||||||
debug!("visit_implementation_of_copy: impl_did={:?}", impl_did);
|
debug!("visit_implementation_of_copy: impl_did={:?}", impl_did);
|
||||||
|
|
||||||
let self_type = tcx.type_of(impl_did).subst_identity();
|
let self_type = tcx.type_of(impl_did).instantiate_identity();
|
||||||
debug!("visit_implementation_of_copy: self_type={:?} (bound)", self_type);
|
debug!("visit_implementation_of_copy: self_type={:?} (bound)", self_type);
|
||||||
|
|
||||||
let param_env = tcx.param_env(impl_did);
|
let param_env = tcx.param_env(impl_did);
|
||||||
|
@ -100,7 +100,7 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_implementation_of_const_param_ty(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
|
fn visit_implementation_of_const_param_ty(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
|
||||||
let self_type = tcx.type_of(impl_did).subst_identity();
|
let self_type = tcx.type_of(impl_did).instantiate_identity();
|
||||||
assert!(!self_type.has_escaping_bound_vars());
|
assert!(!self_type.has_escaping_bound_vars());
|
||||||
|
|
||||||
let param_env = tcx.param_env(impl_did);
|
let param_env = tcx.param_env(impl_did);
|
||||||
|
@ -139,13 +139,13 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
|
||||||
|
|
||||||
let dispatch_from_dyn_trait = tcx.require_lang_item(LangItem::DispatchFromDyn, Some(span));
|
let dispatch_from_dyn_trait = tcx.require_lang_item(LangItem::DispatchFromDyn, Some(span));
|
||||||
|
|
||||||
let source = tcx.type_of(impl_did).subst_identity();
|
let source = tcx.type_of(impl_did).instantiate_identity();
|
||||||
assert!(!source.has_escaping_bound_vars());
|
assert!(!source.has_escaping_bound_vars());
|
||||||
let target = {
|
let target = {
|
||||||
let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().subst_identity();
|
let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().instantiate_identity();
|
||||||
assert_eq!(trait_ref.def_id, dispatch_from_dyn_trait);
|
assert_eq!(trait_ref.def_id, dispatch_from_dyn_trait);
|
||||||
|
|
||||||
trait_ref.substs.type_at(1)
|
trait_ref.args.type_at(1)
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("visit_implementation_of_dispatch_from_dyn: {:?} -> {:?}", source, target);
|
debug!("visit_implementation_of_dispatch_from_dyn: {:?} -> {:?}", source, target);
|
||||||
|
@ -163,9 +163,7 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
|
||||||
if infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, r_a, *r_b).is_ok()
|
if infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, r_a, *r_b).is_ok()
|
||||||
&& mutbl_a == *mutbl_b => {}
|
&& mutbl_a == *mutbl_b => {}
|
||||||
(&RawPtr(tm_a), &RawPtr(tm_b)) if tm_a.mutbl == tm_b.mutbl => (),
|
(&RawPtr(tm_a), &RawPtr(tm_b)) if tm_a.mutbl == tm_b.mutbl => (),
|
||||||
(&Adt(def_a, substs_a), &Adt(def_b, substs_b))
|
(&Adt(def_a, args_a), &Adt(def_b, args_b)) if def_a.is_struct() && def_b.is_struct() => {
|
||||||
if def_a.is_struct() && def_b.is_struct() =>
|
|
||||||
{
|
|
||||||
if def_a != def_b {
|
if def_a != def_b {
|
||||||
let source_path = tcx.def_path_str(def_a.did());
|
let source_path = tcx.def_path_str(def_a.did());
|
||||||
let target_path = tcx.def_path_str(def_b.did());
|
let target_path = tcx.def_path_str(def_b.did());
|
||||||
|
@ -194,8 +192,8 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
|
||||||
let coerced_fields = fields
|
let coerced_fields = fields
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|field| {
|
.filter(|field| {
|
||||||
let ty_a = field.ty(tcx, substs_a);
|
let ty_a = field.ty(tcx, args_a);
|
||||||
let ty_b = field.ty(tcx, substs_b);
|
let ty_b = field.ty(tcx, args_b);
|
||||||
|
|
||||||
if let Ok(layout) = tcx.layout_of(param_env.and(ty_a)) {
|
if let Ok(layout) = tcx.layout_of(param_env.and(ty_a)) {
|
||||||
if layout.is_zst() && layout.align.abi.bytes() == 1 {
|
if layout.is_zst() && layout.align.abi.bytes() == 1 {
|
||||||
|
@ -250,8 +248,8 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
|
||||||
format!(
|
format!(
|
||||||
"`{}` (`{}` to `{}`)",
|
"`{}` (`{}` to `{}`)",
|
||||||
field.name,
|
field.name,
|
||||||
field.ty(tcx, substs_a),
|
field.ty(tcx, args_a),
|
||||||
field.ty(tcx, substs_b),
|
field.ty(tcx, args_b),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
|
@ -268,7 +266,7 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
|
||||||
ty::TraitRef::new(
|
ty::TraitRef::new(
|
||||||
tcx,
|
tcx,
|
||||||
dispatch_from_dyn_trait,
|
dispatch_from_dyn_trait,
|
||||||
[field.ty(tcx, substs_a), field.ty(tcx, substs_b)],
|
[field.ty(tcx, args_a), field.ty(tcx, args_b)],
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -300,10 +298,10 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
|
||||||
|
|
||||||
let unsize_trait = tcx.require_lang_item(LangItem::Unsize, Some(span));
|
let unsize_trait = tcx.require_lang_item(LangItem::Unsize, Some(span));
|
||||||
|
|
||||||
let source = tcx.type_of(impl_did).subst_identity();
|
let source = tcx.type_of(impl_did).instantiate_identity();
|
||||||
let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().subst_identity();
|
let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().instantiate_identity();
|
||||||
assert_eq!(trait_ref.def_id, coerce_unsized_trait);
|
assert_eq!(trait_ref.def_id, coerce_unsized_trait);
|
||||||
let target = trait_ref.substs.type_at(1);
|
let target = trait_ref.args.type_at(1);
|
||||||
debug!("visit_implementation_of_coerce_unsized: {:?} -> {:?} (bound)", source, target);
|
debug!("visit_implementation_of_coerce_unsized: {:?} -> {:?} (bound)", source, target);
|
||||||
|
|
||||||
let param_env = tcx.param_env(impl_did);
|
let param_env = tcx.param_env(impl_did);
|
||||||
|
@ -348,7 +346,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
|
||||||
check_mutbl(mt_a, mt_b, &|ty| Ty::new_imm_ptr(tcx, ty))
|
check_mutbl(mt_a, mt_b, &|ty| Ty::new_imm_ptr(tcx, ty))
|
||||||
}
|
}
|
||||||
|
|
||||||
(&ty::Adt(def_a, substs_a), &ty::Adt(def_b, substs_b))
|
(&ty::Adt(def_a, args_a), &ty::Adt(def_b, args_b))
|
||||||
if def_a.is_struct() && def_b.is_struct() =>
|
if def_a.is_struct() && def_b.is_struct() =>
|
||||||
{
|
{
|
||||||
if def_a != def_b {
|
if def_a != def_b {
|
||||||
|
@ -411,9 +409,9 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
|
||||||
let diff_fields = fields
|
let diff_fields = fields
|
||||||
.iter_enumerated()
|
.iter_enumerated()
|
||||||
.filter_map(|(i, f)| {
|
.filter_map(|(i, f)| {
|
||||||
let (a, b) = (f.ty(tcx, substs_a), f.ty(tcx, substs_b));
|
let (a, b) = (f.ty(tcx, args_a), f.ty(tcx, args_b));
|
||||||
|
|
||||||
if tcx.type_of(f.did).subst_identity().is_phantom_data() {
|
if tcx.type_of(f.did).instantiate_identity().is_phantom_data() {
|
||||||
// Ignore PhantomData fields
|
// Ignore PhantomData fields
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,7 +171,7 @@ impl<'tcx> InherentCollect<'tcx> {
|
||||||
|
|
||||||
let id = id.owner_id.def_id;
|
let id = id.owner_id.def_id;
|
||||||
let item_span = self.tcx.def_span(id);
|
let item_span = self.tcx.def_span(id);
|
||||||
let self_ty = self.tcx.type_of(id).subst_identity();
|
let self_ty = self.tcx.type_of(id).instantiate_identity();
|
||||||
match *self_ty.kind() {
|
match *self_ty.kind() {
|
||||||
ty::Adt(def, _) => self.check_def_id(id, self_ty, def.did()),
|
ty::Adt(def, _) => self.check_def_id(id, self_ty, def.did()),
|
||||||
ty::Foreign(did) => self.check_def_id(id, self_ty, did),
|
ty::Foreign(did) => self.check_def_id(id, self_ty, did),
|
||||||
|
|
|
@ -122,7 +122,7 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) {
|
||||||
|
|
||||||
let impls = tcx.hir().trait_impls(def_id);
|
let impls = tcx.hir().trait_impls(def_id);
|
||||||
for &impl_def_id in impls {
|
for &impl_def_id in impls {
|
||||||
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().subst_identity();
|
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity();
|
||||||
|
|
||||||
check_impl(tcx, impl_def_id, trait_ref);
|
check_impl(tcx, impl_def_id, trait_ref);
|
||||||
check_object_overlap(tcx, impl_def_id, trait_ref);
|
check_object_overlap(tcx, impl_def_id, trait_ref);
|
||||||
|
|
|
@ -5,8 +5,8 @@ use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_errors::{struct_span_err, DelayDm};
|
use rustc_errors::{struct_span_err, DelayDm};
|
||||||
use rustc_errors::{Diagnostic, ErrorGuaranteed};
|
use rustc_errors::{Diagnostic, ErrorGuaranteed};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_middle::ty::subst::InternalSubsts;
|
|
||||||
use rustc_middle::ty::util::CheckRegions;
|
use rustc_middle::ty::util::CheckRegions;
|
||||||
|
use rustc_middle::ty::GenericArgs;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, AliasKind, ImplPolarity, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
|
self, AliasKind, ImplPolarity, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
|
||||||
TypeVisitor,
|
TypeVisitor,
|
||||||
|
@ -22,7 +22,7 @@ pub(crate) fn orphan_check_impl(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
impl_def_id: LocalDefId,
|
impl_def_id: LocalDefId,
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().subst_identity();
|
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity();
|
||||||
trait_ref.error_reported()?;
|
trait_ref.error_reported()?;
|
||||||
|
|
||||||
let ret = do_orphan_check_impl(tcx, trait_ref, impl_def_id);
|
let ret = do_orphan_check_impl(tcx, trait_ref, impl_def_id);
|
||||||
|
@ -488,10 +488,10 @@ fn lint_auto_trait_impl<'tcx>(
|
||||||
trait_ref: ty::TraitRef<'tcx>,
|
trait_ref: ty::TraitRef<'tcx>,
|
||||||
impl_def_id: LocalDefId,
|
impl_def_id: LocalDefId,
|
||||||
) {
|
) {
|
||||||
assert_eq!(trait_ref.substs.len(), 1);
|
assert_eq!(trait_ref.args.len(), 1);
|
||||||
let self_ty = trait_ref.self_ty();
|
let self_ty = trait_ref.self_ty();
|
||||||
let (self_type_did, substs) = match self_ty.kind() {
|
let (self_type_did, args) = match self_ty.kind() {
|
||||||
ty::Adt(def, substs) => (def.did(), substs),
|
ty::Adt(def, args) => (def.did(), args),
|
||||||
_ => {
|
_ => {
|
||||||
// FIXME: should also lint for stuff like `&i32` but
|
// FIXME: should also lint for stuff like `&i32` but
|
||||||
// considering that auto traits are unstable, that
|
// considering that auto traits are unstable, that
|
||||||
|
@ -502,9 +502,9 @@ fn lint_auto_trait_impl<'tcx>(
|
||||||
};
|
};
|
||||||
|
|
||||||
// Impls which completely cover a given root type are fine as they
|
// Impls which completely cover a given root type are fine as they
|
||||||
// disable auto impls entirely. So only lint if the substs
|
// disable auto impls entirely. So only lint if the args
|
||||||
// are not a permutation of the identity substs.
|
// are not a permutation of the identity args.
|
||||||
let Err(arg) = tcx.uses_unique_generic_params(substs, CheckRegions::No) else {
|
let Err(arg) = tcx.uses_unique_generic_params(args, CheckRegions::No) else {
|
||||||
// ok
|
// ok
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -585,14 +585,14 @@ fn fast_reject_auto_impl<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, self_ty:
|
||||||
}
|
}
|
||||||
|
|
||||||
match t.kind() {
|
match t.kind() {
|
||||||
ty::Adt(def, substs) if def.is_phantom_data() => substs.visit_with(self),
|
ty::Adt(def, args) if def.is_phantom_data() => args.visit_with(self),
|
||||||
ty::Adt(def, substs) => {
|
ty::Adt(def, args) => {
|
||||||
// @lcnr: This is the only place where cycles can happen. We avoid this
|
// @lcnr: This is the only place where cycles can happen. We avoid this
|
||||||
// by only visiting each `DefId` once.
|
// by only visiting each `DefId` once.
|
||||||
//
|
//
|
||||||
// This will be is incorrect in subtle cases, but I don't care :)
|
// This will be is incorrect in subtle cases, but I don't care :)
|
||||||
if self.seen.insert(def.did()) {
|
if self.seen.insert(def.did()) {
|
||||||
for ty in def.all_fields().map(|field| field.ty(tcx, substs)) {
|
for ty in def.all_fields().map(|field| field.ty(tcx, args)) {
|
||||||
ty.visit_with(self)?;
|
ty.visit_with(self)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -605,9 +605,7 @@ fn fast_reject_auto_impl<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, self_ty:
|
||||||
}
|
}
|
||||||
|
|
||||||
let self_ty_root = match self_ty.kind() {
|
let self_ty_root = match self_ty.kind() {
|
||||||
ty::Adt(def, _) => {
|
ty::Adt(def, _) => Ty::new_adt(tcx, *def, GenericArgs::identity_for_item(tcx, def.did())),
|
||||||
Ty::new_adt(tcx, *def, InternalSubsts::identity_for_item(tcx, def.did()))
|
|
||||||
}
|
|
||||||
_ => unimplemented!("unexpected self ty {:?}", self_ty),
|
_ => unimplemented!("unexpected self ty {:?}", self_ty),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||||
let impl_ = item.expect_impl();
|
let impl_ = item.expect_impl();
|
||||||
|
|
||||||
if let Some(trait_ref) = tcx.impl_trait_ref(item.owner_id) {
|
if let Some(trait_ref) = tcx.impl_trait_ref(item.owner_id) {
|
||||||
let trait_ref = trait_ref.subst_identity();
|
let trait_ref = trait_ref.instantiate_identity();
|
||||||
let trait_def = tcx.trait_def(trait_ref.def_id);
|
let trait_def = tcx.trait_def(trait_ref.def_id);
|
||||||
let unsafe_attr =
|
let unsafe_attr =
|
||||||
impl_.generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle");
|
impl_.generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle");
|
||||||
|
|
|
@ -401,13 +401,13 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
|
||||||
poly_trait_ref: ty::PolyTraitRef<'tcx>,
|
poly_trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
if let Some(trait_ref) = poly_trait_ref.no_bound_vars() {
|
if let Some(trait_ref) = poly_trait_ref.no_bound_vars() {
|
||||||
let item_substs = self.astconv().create_substs_for_associated_item(
|
let item_args = self.astconv().create_args_for_associated_item(
|
||||||
span,
|
span,
|
||||||
item_def_id,
|
item_def_id,
|
||||||
item_segment,
|
item_segment,
|
||||||
trait_ref.substs,
|
trait_ref.args,
|
||||||
);
|
);
|
||||||
Ty::new_projection(self.tcx(), item_def_id, item_substs)
|
Ty::new_projection(self.tcx(), item_def_id, item_args)
|
||||||
} else {
|
} else {
|
||||||
// There are no late-bound regions; we can just ignore the binder.
|
// There are no late-bound regions; we can just ignore the binder.
|
||||||
let (mut mpart_sugg, mut inferred_sugg) = (None, None);
|
let (mut mpart_sugg, mut inferred_sugg) = (None, None);
|
||||||
|
@ -1145,8 +1145,8 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig<
|
||||||
}
|
}
|
||||||
|
|
||||||
Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor().is_some() => {
|
Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor().is_some() => {
|
||||||
let ty = tcx.type_of(tcx.hir().get_parent_item(hir_id)).subst_identity();
|
let ty = tcx.type_of(tcx.hir().get_parent_item(hir_id)).instantiate_identity();
|
||||||
let inputs = data.fields().iter().map(|f| tcx.type_of(f.def_id).subst_identity());
|
let inputs = data.fields().iter().map(|f| tcx.type_of(f.def_id).instantiate_identity());
|
||||||
ty::Binder::dummy(tcx.mk_fn_sig(
|
ty::Binder::dummy(tcx.mk_fn_sig(
|
||||||
inputs,
|
inputs,
|
||||||
ty,
|
ty,
|
||||||
|
@ -1161,15 +1161,13 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig<
|
||||||
// signatures and cannot be accessed through `fn_sig`. For
|
// signatures and cannot be accessed through `fn_sig`. For
|
||||||
// example, a closure signature excludes the `self`
|
// example, a closure signature excludes the `self`
|
||||||
// argument. In any case they are embedded within the
|
// argument. In any case they are embedded within the
|
||||||
// closure type as part of the `ClosureSubsts`.
|
// closure type as part of the `ClosureArgs`.
|
||||||
//
|
//
|
||||||
// To get the signature of a closure, you should use the
|
// To get the signature of a closure, you should use the
|
||||||
// `sig` method on the `ClosureSubsts`:
|
// `sig` method on the `ClosureArgs`:
|
||||||
//
|
//
|
||||||
// substs.as_closure().sig(def_id, tcx)
|
// args.as_closure().sig(def_id, tcx)
|
||||||
bug!(
|
bug!("to get the signature of a closure, use `args.as_closure().sig()` not `fn_sig()`",);
|
||||||
"to get the signature of a closure, use `substs.as_closure().sig()` not `fn_sig()`",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
x => {
|
x => {
|
||||||
|
@ -1266,7 +1264,7 @@ fn suggest_impl_trait<'tcx>(
|
||||||
) -> Option<String> {
|
) -> Option<String> {
|
||||||
let format_as_assoc: fn(_, _, _, _, _) -> _ =
|
let format_as_assoc: fn(_, _, _, _, _) -> _ =
|
||||||
|tcx: TyCtxt<'tcx>,
|
|tcx: TyCtxt<'tcx>,
|
||||||
_: ty::SubstsRef<'tcx>,
|
_: ty::GenericArgsRef<'tcx>,
|
||||||
trait_def_id: DefId,
|
trait_def_id: DefId,
|
||||||
assoc_item_def_id: DefId,
|
assoc_item_def_id: DefId,
|
||||||
item_ty: Ty<'tcx>| {
|
item_ty: Ty<'tcx>| {
|
||||||
|
@ -1276,12 +1274,12 @@ fn suggest_impl_trait<'tcx>(
|
||||||
};
|
};
|
||||||
let format_as_parenthesized: fn(_, _, _, _, _) -> _ =
|
let format_as_parenthesized: fn(_, _, _, _, _) -> _ =
|
||||||
|tcx: TyCtxt<'tcx>,
|
|tcx: TyCtxt<'tcx>,
|
||||||
substs: ty::SubstsRef<'tcx>,
|
args: ty::GenericArgsRef<'tcx>,
|
||||||
trait_def_id: DefId,
|
trait_def_id: DefId,
|
||||||
_: DefId,
|
_: DefId,
|
||||||
item_ty: Ty<'tcx>| {
|
item_ty: Ty<'tcx>| {
|
||||||
let trait_name = tcx.item_name(trait_def_id);
|
let trait_name = tcx.item_name(trait_def_id);
|
||||||
let args_tuple = substs.type_at(1);
|
let args_tuple = args.type_at(1);
|
||||||
let ty::Tuple(types) = *args_tuple.kind() else {
|
let ty::Tuple(types) = *args_tuple.kind() else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
@ -1328,24 +1326,23 @@ fn suggest_impl_trait<'tcx>(
|
||||||
}
|
}
|
||||||
let param_env = tcx.param_env(def_id);
|
let param_env = tcx.param_env(def_id);
|
||||||
let infcx = tcx.infer_ctxt().build();
|
let infcx = tcx.infer_ctxt().build();
|
||||||
let substs = ty::InternalSubsts::for_item(tcx, trait_def_id, |param, _| {
|
let args = ty::GenericArgs::for_item(tcx, trait_def_id, |param, _| {
|
||||||
if param.index == 0 { ret_ty.into() } else { infcx.var_for_def(span, param) }
|
if param.index == 0 { ret_ty.into() } else { infcx.var_for_def(span, param) }
|
||||||
});
|
});
|
||||||
if !infcx.type_implements_trait(trait_def_id, substs, param_env).must_apply_modulo_regions()
|
if !infcx.type_implements_trait(trait_def_id, args, param_env).must_apply_modulo_regions() {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let ocx = ObligationCtxt::new(&infcx);
|
let ocx = ObligationCtxt::new(&infcx);
|
||||||
let item_ty = ocx.normalize(
|
let item_ty = ocx.normalize(
|
||||||
&ObligationCause::misc(span, def_id),
|
&ObligationCause::misc(span, def_id),
|
||||||
param_env,
|
param_env,
|
||||||
Ty::new_projection(tcx, assoc_item_def_id, substs),
|
Ty::new_projection(tcx, assoc_item_def_id, args),
|
||||||
);
|
);
|
||||||
// FIXME(compiler-errors): We may benefit from resolving regions here.
|
// FIXME(compiler-errors): We may benefit from resolving regions here.
|
||||||
if ocx.select_where_possible().is_empty()
|
if ocx.select_where_possible().is_empty()
|
||||||
&& let item_ty = infcx.resolve_vars_if_possible(item_ty)
|
&& let item_ty = infcx.resolve_vars_if_possible(item_ty)
|
||||||
&& let Some(item_ty) = item_ty.make_suggestable(tcx, false)
|
&& let Some(item_ty) = item_ty.make_suggestable(tcx, false)
|
||||||
&& let Some(sugg) = formatter(tcx, infcx.resolve_vars_if_possible(substs), trait_def_id, assoc_item_def_id, item_ty)
|
&& let Some(sugg) = formatter(tcx, infcx.resolve_vars_if_possible(args), trait_def_id, assoc_item_def_id, item_ty)
|
||||||
{
|
{
|
||||||
return Some(sugg);
|
return Some(sugg);
|
||||||
}
|
}
|
||||||
|
@ -1363,7 +1360,7 @@ fn impl_trait_ref(
|
||||||
.of_trait
|
.of_trait
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|ast_trait_ref| {
|
.map(|ast_trait_ref| {
|
||||||
let selfty = tcx.type_of(def_id).subst_identity();
|
let selfty = tcx.type_of(def_id).instantiate_identity();
|
||||||
icx.astconv().instantiate_mono_trait_ref(
|
icx.astconv().instantiate_mono_trait_ref(
|
||||||
ast_trait_ref,
|
ast_trait_ref,
|
||||||
selfty,
|
selfty,
|
||||||
|
|
|
@ -68,17 +68,17 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
||||||
// ^ parent_def_id
|
// ^ parent_def_id
|
||||||
//
|
//
|
||||||
// then we only want to return generics for params to the left of `N`. If we don't do that we
|
// then we only want to return generics for params to the left of `N`. If we don't do that we
|
||||||
// end up with that const looking like: `ty::ConstKind::Unevaluated(def_id, substs: [N#0])`.
|
// end up with that const looking like: `ty::ConstKind::Unevaluated(def_id, args: [N#0])`.
|
||||||
//
|
//
|
||||||
// This causes ICEs (#86580) when building the substs for Foo in `fn foo() -> Foo { .. }` as
|
// This causes ICEs (#86580) when building the args for Foo in `fn foo() -> Foo { .. }` as
|
||||||
// we substitute the defaults with the partially built substs when we build the substs. Subst'ing
|
// we substitute the defaults with the partially built args when we build the args. Subst'ing
|
||||||
// the `N#0` on the unevaluated const indexes into the empty substs we're in the process of building.
|
// the `N#0` on the unevaluated const indexes into the empty args we're in the process of building.
|
||||||
//
|
//
|
||||||
// We fix this by having this function return the parent's generics ourselves and truncating the
|
// We fix this by having this function return the parent's generics ourselves and truncating the
|
||||||
// generics to only include non-forward declared params (with the exception of the `Self` ty)
|
// generics to only include non-forward declared params (with the exception of the `Self` ty)
|
||||||
//
|
//
|
||||||
// For the above code example that means we want `substs: []`
|
// For the above code example that means we want `args: []`
|
||||||
// For the following struct def we want `substs: [N#0]` when generics_of is called on
|
// For the following struct def we want `args: [N#0]` when generics_of is called on
|
||||||
// the def id of the `{ N + 1 }` anon const
|
// the def id of the `{ N + 1 }` anon const
|
||||||
// struct Foo<const N: usize, const M: usize = { N + 1 }>;
|
// struct Foo<const N: usize, const M: usize = { N + 1 }>;
|
||||||
//
|
//
|
||||||
|
@ -93,7 +93,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
||||||
|
|
||||||
return ty::Generics {
|
return ty::Generics {
|
||||||
// we set the parent of these generics to be our parent's parent so that we
|
// we set the parent of these generics to be our parent's parent so that we
|
||||||
// dont end up with substs: [N, M, N] for the const default on a struct like this:
|
// dont end up with args: [N, M, N] for the const default on a struct like this:
|
||||||
// struct Foo<const N: usize, const M: usize = { ... }>;
|
// struct Foo<const N: usize, const M: usize = { ... }>;
|
||||||
parent: generics.parent,
|
parent: generics.parent,
|
||||||
parent_count: generics.parent_count,
|
parent_count: generics.parent_count,
|
||||||
|
|
|
@ -2,7 +2,7 @@ use super::ItemCtxt;
|
||||||
use crate::astconv::{AstConv, PredicateFilter};
|
use crate::astconv::{AstConv, PredicateFilter};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_infer::traits::util;
|
use rustc_infer::traits::util;
|
||||||
use rustc_middle::ty::subst::InternalSubsts;
|
use rustc_middle::ty::GenericArgs;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_span::def_id::{DefId, LocalDefId};
|
use rustc_span::def_id::{DefId, LocalDefId};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -10,7 +10,7 @@ use rustc_span::Span;
|
||||||
/// For associated types we include both bounds written on the type
|
/// For associated types we include both bounds written on the type
|
||||||
/// (`type X: Trait`) and predicates from the trait: `where Self::X: Trait`.
|
/// (`type X: Trait`) and predicates from the trait: `where Self::X: Trait`.
|
||||||
///
|
///
|
||||||
/// Note that this filtering is done with the items identity substs to
|
/// Note that this filtering is done with the items identity args to
|
||||||
/// simplify checking that these bounds are met in impls. This means that
|
/// simplify checking that these bounds are met in impls. This means that
|
||||||
/// a bound such as `for<'b> <Self as X<'b>>::U: Clone` can't be used, as in
|
/// a bound such as `for<'b> <Self as X<'b>>::U: Clone` can't be used, as in
|
||||||
/// `hr-associated-type-bound-1.rs`.
|
/// `hr-associated-type-bound-1.rs`.
|
||||||
|
@ -23,7 +23,7 @@ fn associated_type_bounds<'tcx>(
|
||||||
let item_ty = Ty::new_projection(
|
let item_ty = Ty::new_projection(
|
||||||
tcx,
|
tcx,
|
||||||
assoc_item_def_id.to_def_id(),
|
assoc_item_def_id.to_def_id(),
|
||||||
InternalSubsts::identity_for_item(tcx, assoc_item_def_id),
|
GenericArgs::identity_for_item(tcx, assoc_item_def_id),
|
||||||
);
|
);
|
||||||
|
|
||||||
let icx = ItemCtxt::new(tcx, assoc_item_def_id);
|
let icx = ItemCtxt::new(tcx, assoc_item_def_id);
|
||||||
|
@ -95,7 +95,7 @@ pub(super) fn explicit_item_bounds(
|
||||||
Ty::new_projection(
|
Ty::new_projection(
|
||||||
tcx,
|
tcx,
|
||||||
def_id.to_def_id(),
|
def_id.to_def_id(),
|
||||||
ty::InternalSubsts::identity_for_item(tcx, def_id),
|
ty::GenericArgs::identity_for_item(tcx, def_id),
|
||||||
),
|
),
|
||||||
item.span,
|
item.span,
|
||||||
));
|
));
|
||||||
|
@ -117,8 +117,8 @@ pub(super) fn explicit_item_bounds(
|
||||||
span,
|
span,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
let args = GenericArgs::identity_for_item(tcx, def_id);
|
||||||
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), substs);
|
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
|
||||||
opaque_type_bounds(tcx, def_id, bounds, item_ty, *span)
|
opaque_type_bounds(tcx, def_id, bounds, item_ty, *span)
|
||||||
}
|
}
|
||||||
hir::Node::Item(hir::Item { kind: hir::ItemKind::TyAlias(..), .. }) => &[],
|
hir::Node::Item(hir::Item { kind: hir::ItemKind::TyAlias(..), .. }) => &[],
|
||||||
|
|
|
@ -8,7 +8,6 @@ use rustc_hir as hir;
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_hir::intravisit::{self, Visitor};
|
use rustc_hir::intravisit::{self, Visitor};
|
||||||
use rustc_middle::ty::subst::InternalSubsts;
|
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_middle::ty::{GenericPredicates, Generics, ImplTraitInTraitData, ToPredicate};
|
use rustc_middle::ty::{GenericPredicates, Generics, ImplTraitInTraitData, ToPredicate};
|
||||||
use rustc_span::symbol::{sym, Ident};
|
use rustc_span::symbol::{sym, Ident};
|
||||||
|
@ -80,10 +79,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
||||||
// both to ensure that the RPITITs are only instantiated when the
|
// both to ensure that the RPITITs are only instantiated when the
|
||||||
// parent predicates would hold, and also so that the param-env
|
// parent predicates would hold, and also so that the param-env
|
||||||
// inherits these predicates as assumptions.
|
// inherits these predicates as assumptions.
|
||||||
let identity_substs = InternalSubsts::identity_for_item(tcx, def_id);
|
let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||||
predicates.extend(
|
predicates
|
||||||
tcx.explicit_predicates_of(fn_def_id).instantiate_own(tcx, identity_substs),
|
.extend(tcx.explicit_predicates_of(fn_def_id).instantiate_own(tcx, identity_args));
|
||||||
);
|
|
||||||
|
|
||||||
// We also install bidirectional outlives predicates for the RPITIT
|
// We also install bidirectional outlives predicates for the RPITIT
|
||||||
// to keep the duplicates lifetimes from opaque lowering in sync.
|
// to keep the duplicates lifetimes from opaque lowering in sync.
|
||||||
|
@ -108,15 +106,15 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
||||||
let trait_assoc_predicates =
|
let trait_assoc_predicates =
|
||||||
tcx.explicit_predicates_of(assoc_item.trait_item_def_id.unwrap());
|
tcx.explicit_predicates_of(assoc_item.trait_item_def_id.unwrap());
|
||||||
|
|
||||||
let impl_assoc_identity_substs = InternalSubsts::identity_for_item(tcx, def_id);
|
let impl_assoc_identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||||
let impl_def_id = tcx.parent(fn_def_id);
|
let impl_def_id = tcx.parent(fn_def_id);
|
||||||
let impl_trait_ref_substs =
|
let impl_trait_ref_args =
|
||||||
tcx.impl_trait_ref(impl_def_id).unwrap().subst_identity().substs;
|
tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity().args;
|
||||||
|
|
||||||
let impl_assoc_substs =
|
let impl_assoc_args =
|
||||||
impl_assoc_identity_substs.rebase_onto(tcx, impl_def_id, impl_trait_ref_substs);
|
impl_assoc_identity_args.rebase_onto(tcx, impl_def_id, impl_trait_ref_args);
|
||||||
|
|
||||||
let impl_predicates = trait_assoc_predicates.instantiate_own(tcx, impl_assoc_substs);
|
let impl_predicates = trait_assoc_predicates.instantiate_own(tcx, impl_assoc_args);
|
||||||
|
|
||||||
return ty::GenericPredicates {
|
return ty::GenericPredicates {
|
||||||
parent: Some(impl_def_id),
|
parent: Some(impl_def_id),
|
||||||
|
@ -150,8 +148,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
||||||
Node::Item(item) => match item.kind {
|
Node::Item(item) => match item.kind {
|
||||||
ItemKind::Impl(impl_) => {
|
ItemKind::Impl(impl_) => {
|
||||||
if impl_.defaultness.is_default() {
|
if impl_.defaultness.is_default() {
|
||||||
is_default_impl_trait =
|
is_default_impl_trait = tcx
|
||||||
tcx.impl_trait_ref(def_id).map(|t| ty::Binder::dummy(t.subst_identity()));
|
.impl_trait_ref(def_id)
|
||||||
|
.map(|t| ty::Binder::dummy(t.instantiate_identity()));
|
||||||
}
|
}
|
||||||
impl_.generics
|
impl_.generics
|
||||||
}
|
}
|
||||||
|
@ -337,8 +336,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
||||||
// in trait checking. See `setup_constraining_predicates`
|
// in trait checking. See `setup_constraining_predicates`
|
||||||
// for details.
|
// for details.
|
||||||
if let Node::Item(&Item { kind: ItemKind::Impl { .. }, .. }) = node {
|
if let Node::Item(&Item { kind: ItemKind::Impl { .. }, .. }) = node {
|
||||||
let self_ty = tcx.type_of(def_id).subst_identity();
|
let self_ty = tcx.type_of(def_id).instantiate_identity();
|
||||||
let trait_ref = tcx.impl_trait_ref(def_id).map(ty::EarlyBinder::subst_identity);
|
let trait_ref = tcx.impl_trait_ref(def_id).map(ty::EarlyBinder::instantiate_identity);
|
||||||
cgp::setup_constraining_predicates(
|
cgp::setup_constraining_predicates(
|
||||||
tcx,
|
tcx,
|
||||||
&mut predicates,
|
&mut predicates,
|
||||||
|
@ -397,7 +396,7 @@ fn compute_bidirectional_outlives_predicates<'tcx>(
|
||||||
let orig_region = icx.astconv().ast_region_to_region(&arg, None);
|
let orig_region = icx.astconv().ast_region_to_region(&arg, None);
|
||||||
if !matches!(orig_region.kind(), ty::ReEarlyBound(..)) {
|
if !matches!(orig_region.kind(), ty::ReEarlyBound(..)) {
|
||||||
// There is no late-bound lifetime to actually match up here, since the lifetime doesn't
|
// There is no late-bound lifetime to actually match up here, since the lifetime doesn't
|
||||||
// show up in the opaque's parent's substs.
|
// show up in the opaque's parent's args.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,20 +498,20 @@ pub(super) fn explicit_predicates_of<'tcx>(
|
||||||
// Remove bounds on associated types from the predicates, they will be
|
// Remove bounds on associated types from the predicates, they will be
|
||||||
// returned by `explicit_item_bounds`.
|
// returned by `explicit_item_bounds`.
|
||||||
let predicates_and_bounds = tcx.trait_explicit_predicates_and_bounds(def_id);
|
let predicates_and_bounds = tcx.trait_explicit_predicates_and_bounds(def_id);
|
||||||
let trait_identity_substs = InternalSubsts::identity_for_item(tcx, def_id);
|
let trait_identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||||
|
|
||||||
let is_assoc_item_ty = |ty: Ty<'tcx>| {
|
let is_assoc_item_ty = |ty: Ty<'tcx>| {
|
||||||
// For a predicate from a where clause to become a bound on an
|
// For a predicate from a where clause to become a bound on an
|
||||||
// associated type:
|
// associated type:
|
||||||
// * It must use the identity substs of the item.
|
// * It must use the identity args of the item.
|
||||||
// * We're in the scope of the trait, so we can't name any
|
// * We're in the scope of the trait, so we can't name any
|
||||||
// parameters of the GAT. That means that all we need to
|
// parameters of the GAT. That means that all we need to
|
||||||
// check are that the substs of the projection are the
|
// check are that the args of the projection are the
|
||||||
// identity substs of the trait.
|
// identity args of the trait.
|
||||||
// * It must be an associated type for this trait (*not* a
|
// * It must be an associated type for this trait (*not* a
|
||||||
// supertrait).
|
// supertrait).
|
||||||
if let ty::Alias(ty::Projection, projection) = ty.kind() {
|
if let ty::Alias(ty::Projection, projection) = ty.kind() {
|
||||||
projection.substs == trait_identity_substs
|
projection.args == trait_identity_args
|
||||||
// FIXME(return_type_notation): This check should be more robust
|
// FIXME(return_type_notation): This check should be more robust
|
||||||
&& !tcx.is_impl_trait_in_trait(projection.def_id)
|
&& !tcx.is_impl_trait_in_trait(projection.def_id)
|
||||||
&& tcx.associated_item(projection.def_id).container_id(tcx)
|
&& tcx.associated_item(projection.def_id).container_id(tcx)
|
||||||
|
|
|
@ -1721,7 +1721,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
bound_vars
|
bound_vars
|
||||||
.extend(self.tcx.fn_sig(assoc_fn.def_id).subst_identity().bound_vars());
|
.extend(self.tcx.fn_sig(assoc_fn.def_id).instantiate_identity().bound_vars());
|
||||||
bound_vars
|
bound_vars
|
||||||
} else {
|
} else {
|
||||||
self.tcx.sess.delay_span_bug(
|
self.tcx.sess.delay_span_bug(
|
||||||
|
@ -2038,12 +2038,12 @@ fn is_late_bound_map(
|
||||||
hir::Path { res: Res::Def(DefKind::TyAlias, alias_def), segments, span },
|
hir::Path { res: Res::Def(DefKind::TyAlias, alias_def), segments, span },
|
||||||
)) => {
|
)) => {
|
||||||
// See comments on `ConstrainedCollectorPostAstConv` for why this arm does not just consider
|
// See comments on `ConstrainedCollectorPostAstConv` for why this arm does not just consider
|
||||||
// substs to be unconstrained.
|
// args to be unconstrained.
|
||||||
let generics = self.tcx.generics_of(alias_def);
|
let generics = self.tcx.generics_of(alias_def);
|
||||||
let mut walker = ConstrainedCollectorPostAstConv {
|
let mut walker = ConstrainedCollectorPostAstConv {
|
||||||
arg_is_constrained: vec![false; generics.params.len()].into_boxed_slice(),
|
arg_is_constrained: vec![false; generics.params.len()].into_boxed_slice(),
|
||||||
};
|
};
|
||||||
walker.visit_ty(self.tcx.type_of(alias_def).subst_identity());
|
walker.visit_ty(self.tcx.type_of(alias_def).instantiate_identity());
|
||||||
|
|
||||||
match segments.last() {
|
match segments.last() {
|
||||||
Some(hir::PathSegment { args: Some(args), .. }) => {
|
Some(hir::PathSegment { args: Some(args), .. }) => {
|
||||||
|
|
|
@ -3,7 +3,6 @@ use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_hir::HirId;
|
use rustc_hir::HirId;
|
||||||
use rustc_middle::ty::print::with_forced_trimmed_paths;
|
use rustc_middle::ty::print::with_forced_trimmed_paths;
|
||||||
use rustc_middle::ty::subst::InternalSubsts;
|
|
||||||
use rustc_middle::ty::util::IntTypeExt;
|
use rustc_middle::ty::util::IntTypeExt;
|
||||||
use rustc_middle::ty::{self, ImplTraitInTraitData, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
|
use rustc_middle::ty::{self, ImplTraitInTraitData, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
|
||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::Ident;
|
||||||
|
@ -338,8 +337,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
||||||
let output = match tcx.hir().get(hir_id) {
|
let output = match tcx.hir().get(hir_id) {
|
||||||
Node::TraitItem(item) => match item.kind {
|
Node::TraitItem(item) => match item.kind {
|
||||||
TraitItemKind::Fn(..) => {
|
TraitItemKind::Fn(..) => {
|
||||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||||
Ty::new_fn_def(tcx, def_id.to_def_id(), substs)
|
Ty::new_fn_def(tcx, def_id.to_def_id(), args)
|
||||||
}
|
}
|
||||||
TraitItemKind::Const(ty, body_id) => body_id
|
TraitItemKind::Const(ty, body_id) => body_id
|
||||||
.and_then(|body_id| {
|
.and_then(|body_id| {
|
||||||
|
@ -363,8 +362,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
||||||
|
|
||||||
Node::ImplItem(item) => match item.kind {
|
Node::ImplItem(item) => match item.kind {
|
||||||
ImplItemKind::Fn(..) => {
|
ImplItemKind::Fn(..) => {
|
||||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||||
Ty::new_fn_def(tcx, def_id.to_def_id(), substs)
|
Ty::new_fn_def(tcx, def_id.to_def_id(), args)
|
||||||
}
|
}
|
||||||
ImplItemKind::Const(ty, body_id) => {
|
ImplItemKind::Const(ty, body_id) => {
|
||||||
if is_suggestable_infer_ty(ty) {
|
if is_suggestable_infer_ty(ty) {
|
||||||
|
@ -426,13 +425,13 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
||||||
_ => icx.to_ty(*self_ty),
|
_ => icx.to_ty(*self_ty),
|
||||||
},
|
},
|
||||||
ItemKind::Fn(..) => {
|
ItemKind::Fn(..) => {
|
||||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||||
Ty::new_fn_def(tcx, def_id.to_def_id(), substs)
|
Ty::new_fn_def(tcx, def_id.to_def_id(), args)
|
||||||
}
|
}
|
||||||
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => {
|
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => {
|
||||||
let def = tcx.adt_def(def_id);
|
let def = tcx.adt_def(def_id);
|
||||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||||
Ty::new_adt(tcx, def, substs)
|
Ty::new_adt(tcx, def, args)
|
||||||
}
|
}
|
||||||
ItemKind::OpaqueTy(OpaqueTy {
|
ItemKind::OpaqueTy(OpaqueTy {
|
||||||
origin: hir::OpaqueTyOrigin::TyAlias { .. },
|
origin: hir::OpaqueTyOrigin::TyAlias { .. },
|
||||||
|
@ -472,8 +471,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
||||||
|
|
||||||
Node::ForeignItem(foreign_item) => match foreign_item.kind {
|
Node::ForeignItem(foreign_item) => match foreign_item.kind {
|
||||||
ForeignItemKind::Fn(..) => {
|
ForeignItemKind::Fn(..) => {
|
||||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||||
Ty::new_fn_def(tcx, def_id.to_def_id(), substs)
|
Ty::new_fn_def(tcx, def_id.to_def_id(), args)
|
||||||
}
|
}
|
||||||
ForeignItemKind::Static(t, _) => icx.to_ty(t),
|
ForeignItemKind::Static(t, _) => icx.to_ty(t),
|
||||||
ForeignItemKind::Type => Ty::new_foreign(tcx, def_id.to_def_id()),
|
ForeignItemKind::Type => Ty::new_foreign(tcx, def_id.to_def_id()),
|
||||||
|
@ -481,11 +480,11 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
||||||
|
|
||||||
Node::Ctor(def) | Node::Variant(Variant { data: def, .. }) => match def {
|
Node::Ctor(def) | Node::Variant(Variant { data: def, .. }) => match def {
|
||||||
VariantData::Unit(..) | VariantData::Struct(..) => {
|
VariantData::Unit(..) | VariantData::Struct(..) => {
|
||||||
tcx.type_of(tcx.hir().get_parent_item(hir_id)).subst_identity()
|
tcx.type_of(tcx.hir().get_parent_item(hir_id)).instantiate_identity()
|
||||||
}
|
}
|
||||||
VariantData::Tuple(..) => {
|
VariantData::Tuple(..) => {
|
||||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||||
Ty::new_fn_def(tcx, def_id.to_def_id(), substs)
|
Ty::new_fn_def(tcx, def_id.to_def_id(), args)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -498,8 +497,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
||||||
Node::AnonConst(_) => anon_const_type_of(tcx, def_id),
|
Node::AnonConst(_) => anon_const_type_of(tcx, def_id),
|
||||||
|
|
||||||
Node::ConstBlock(_) => {
|
Node::ConstBlock(_) => {
|
||||||
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
|
let args = ty::GenericArgs::identity_for_item(tcx, def_id.to_def_id());
|
||||||
substs.as_inline_const().ty()
|
args.as_inline_const().ty()
|
||||||
}
|
}
|
||||||
|
|
||||||
Node::GenericParam(param) => match ¶m.kind {
|
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) {
|
fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) {
|
||||||
// Every lifetime used in an associated type must be constrained.
|
// Every lifetime used in an associated type must be constrained.
|
||||||
let impl_self_ty = tcx.type_of(impl_def_id).subst_identity();
|
let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity();
|
||||||
if impl_self_ty.references_error() {
|
if impl_self_ty.references_error() {
|
||||||
// Don't complain about unconstrained type params when self ty isn't known due to errors.
|
// Don't complain about unconstrained type params when self ty isn't known due to errors.
|
||||||
// (#36836)
|
// (#36836)
|
||||||
|
@ -85,7 +85,7 @@ fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId)
|
||||||
}
|
}
|
||||||
let impl_generics = tcx.generics_of(impl_def_id);
|
let impl_generics = tcx.generics_of(impl_def_id);
|
||||||
let impl_predicates = tcx.predicates_of(impl_def_id);
|
let impl_predicates = tcx.predicates_of(impl_def_id);
|
||||||
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).map(ty::EarlyBinder::subst_identity);
|
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).map(ty::EarlyBinder::instantiate_identity);
|
||||||
|
|
||||||
let mut input_parameters = cgp::parameters_for_impl(impl_self_ty, impl_trait_ref);
|
let mut input_parameters = cgp::parameters_for_impl(impl_self_ty, impl_trait_ref);
|
||||||
cgp::identify_constrained_generic_params(
|
cgp::identify_constrained_generic_params(
|
||||||
|
@ -104,7 +104,7 @@ fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId)
|
||||||
match item.kind {
|
match item.kind {
|
||||||
ty::AssocKind::Type => {
|
ty::AssocKind::Type => {
|
||||||
if item.defaultness(tcx).has_value() {
|
if item.defaultness(tcx).has_value() {
|
||||||
cgp::parameters_for(&tcx.type_of(def_id).subst_identity(), true)
|
cgp::parameters_for(&tcx.type_of(def_id).instantiate_identity(), true)
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,15 +14,15 @@
|
||||||
//! To enforce this requirement on specializations we take the following
|
//! To enforce this requirement on specializations we take the following
|
||||||
//! approach:
|
//! approach:
|
||||||
//!
|
//!
|
||||||
//! 1. Match up the substs for `impl2` so that the implemented trait and
|
//! 1. Match up the args for `impl2` so that the implemented trait and
|
||||||
//! self-type match those for `impl1`.
|
//! self-type match those for `impl1`.
|
||||||
//! 2. Check for any direct use of `'static` in the substs of `impl2`.
|
//! 2. Check for any direct use of `'static` in the args of `impl2`.
|
||||||
//! 3. Check that all of the generic parameters of `impl1` occur at most once
|
//! 3. Check that all of the generic parameters of `impl1` occur at most once
|
||||||
//! in the *unconstrained* substs for `impl2`. A parameter is constrained if
|
//! in the *unconstrained* args for `impl2`. A parameter is constrained if
|
||||||
//! its value is completely determined by an associated type projection
|
//! its value is completely determined by an associated type projection
|
||||||
//! predicate.
|
//! predicate.
|
||||||
//! 4. Check that all predicates on `impl1` either exist on `impl2` (after
|
//! 4. Check that all predicates on `impl1` either exist on `impl2` (after
|
||||||
//! matching substs), or are well-formed predicates for the trait's type
|
//! matching args), or are well-formed predicates for the trait's type
|
||||||
//! arguments.
|
//! arguments.
|
||||||
//!
|
//!
|
||||||
//! ## Example
|
//! ## Example
|
||||||
|
@ -74,13 +74,13 @@ use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||||
use rustc_infer::infer::TyCtxtInferExt;
|
use rustc_infer::infer::TyCtxtInferExt;
|
||||||
use rustc_infer::traits::specialization_graph::Node;
|
use rustc_infer::traits::specialization_graph::Node;
|
||||||
use rustc_middle::ty::subst::{GenericArg, InternalSubsts, SubstsRef};
|
|
||||||
use rustc_middle::ty::trait_def::TraitSpecializationKind;
|
use rustc_middle::ty::trait_def::TraitSpecializationKind;
|
||||||
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
|
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
|
||||||
|
use rustc_middle::ty::{GenericArg, GenericArgs, GenericArgsRef};
|
||||||
use rustc_span::{ErrorGuaranteed, Span};
|
use rustc_span::{ErrorGuaranteed, Span};
|
||||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
||||||
use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
|
use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
|
||||||
use rustc_trait_selection::traits::{self, translate_substs_with_cause, wf, ObligationCtxt};
|
use rustc_trait_selection::traits::{self, translate_args_with_cause, wf, ObligationCtxt};
|
||||||
|
|
||||||
pub(super) fn check_min_specialization(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) {
|
pub(super) fn check_min_specialization(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) {
|
||||||
if let Some(node) = parent_specialization_node(tcx, impl_def_id) {
|
if let Some(node) = parent_specialization_node(tcx, impl_def_id) {
|
||||||
|
@ -113,20 +113,20 @@ fn check_always_applicable(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node
|
||||||
let span = tcx.def_span(impl1_def_id);
|
let span = tcx.def_span(impl1_def_id);
|
||||||
check_has_items(tcx, impl1_def_id, impl2_node, span);
|
check_has_items(tcx, impl1_def_id, impl2_node, span);
|
||||||
|
|
||||||
if let Ok((impl1_substs, impl2_substs)) = get_impl_substs(tcx, impl1_def_id, impl2_node) {
|
if let Ok((impl1_args, impl2_args)) = get_impl_args(tcx, impl1_def_id, impl2_node) {
|
||||||
let impl2_def_id = impl2_node.def_id();
|
let impl2_def_id = impl2_node.def_id();
|
||||||
debug!(?impl2_def_id, ?impl2_substs);
|
debug!(?impl2_def_id, ?impl2_args);
|
||||||
|
|
||||||
let parent_substs = if impl2_node.is_from_trait() {
|
let parent_args = if impl2_node.is_from_trait() {
|
||||||
impl2_substs.to_vec()
|
impl2_args.to_vec()
|
||||||
} else {
|
} else {
|
||||||
unconstrained_parent_impl_substs(tcx, impl2_def_id, impl2_substs)
|
unconstrained_parent_impl_args(tcx, impl2_def_id, impl2_args)
|
||||||
};
|
};
|
||||||
|
|
||||||
check_constness(tcx, impl1_def_id, impl2_node, span);
|
check_constness(tcx, impl1_def_id, impl2_node, span);
|
||||||
check_static_lifetimes(tcx, &parent_substs, span);
|
check_static_lifetimes(tcx, &parent_args, span);
|
||||||
check_duplicate_params(tcx, impl1_substs, &parent_substs, span);
|
check_duplicate_params(tcx, impl1_args, &parent_args, span);
|
||||||
check_predicates(tcx, impl1_def_id, impl1_substs, impl2_node, impl2_substs, span);
|
check_predicates(tcx, impl1_def_id, impl1_args, impl2_node, impl2_args, span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,23 +167,23 @@ fn check_constness(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node,
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Would return `S1 = [C]` and `S2 = [Vec<C>, C]`.
|
/// Would return `S1 = [C]` and `S2 = [Vec<C>, C]`.
|
||||||
fn get_impl_substs(
|
fn get_impl_args(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
impl1_def_id: LocalDefId,
|
impl1_def_id: LocalDefId,
|
||||||
impl2_node: Node,
|
impl2_node: Node,
|
||||||
) -> Result<(SubstsRef<'_>, SubstsRef<'_>), ErrorGuaranteed> {
|
) -> Result<(GenericArgsRef<'_>, GenericArgsRef<'_>), ErrorGuaranteed> {
|
||||||
let infcx = &tcx.infer_ctxt().build();
|
let infcx = &tcx.infer_ctxt().build();
|
||||||
let ocx = ObligationCtxt::new(infcx);
|
let ocx = ObligationCtxt::new(infcx);
|
||||||
let param_env = tcx.param_env(impl1_def_id);
|
let param_env = tcx.param_env(impl1_def_id);
|
||||||
let impl1_span = tcx.def_span(impl1_def_id);
|
let impl1_span = tcx.def_span(impl1_def_id);
|
||||||
let assumed_wf_types = ocx.assumed_wf_types_and_report_errors(param_env, impl1_def_id)?;
|
let assumed_wf_types = ocx.assumed_wf_types_and_report_errors(param_env, impl1_def_id)?;
|
||||||
|
|
||||||
let impl1_substs = InternalSubsts::identity_for_item(tcx, impl1_def_id);
|
let impl1_args = GenericArgs::identity_for_item(tcx, impl1_def_id);
|
||||||
let impl2_substs = translate_substs_with_cause(
|
let impl2_args = translate_args_with_cause(
|
||||||
infcx,
|
infcx,
|
||||||
param_env,
|
param_env,
|
||||||
impl1_def_id.to_def_id(),
|
impl1_def_id.to_def_id(),
|
||||||
impl1_substs,
|
impl1_args,
|
||||||
impl2_node,
|
impl2_node,
|
||||||
|_, span| {
|
|_, span| {
|
||||||
traits::ObligationCause::new(
|
traits::ObligationCause::new(
|
||||||
|
@ -203,12 +203,12 @@ fn get_impl_substs(
|
||||||
let implied_bounds = infcx.implied_bounds_tys(param_env, impl1_def_id, assumed_wf_types);
|
let implied_bounds = infcx.implied_bounds_tys(param_env, impl1_def_id, assumed_wf_types);
|
||||||
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
|
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
|
||||||
let _ = ocx.resolve_regions_and_report_errors(impl1_def_id, &outlives_env);
|
let _ = ocx.resolve_regions_and_report_errors(impl1_def_id, &outlives_env);
|
||||||
let Ok(impl2_substs) = infcx.fully_resolve(impl2_substs) else {
|
let Ok(impl2_args) = infcx.fully_resolve(impl2_args) else {
|
||||||
let span = tcx.def_span(impl1_def_id);
|
let span = tcx.def_span(impl1_def_id);
|
||||||
let guar = tcx.sess.emit_err(SubstsOnOverriddenImpl { span });
|
let guar = tcx.sess.emit_err(SubstsOnOverriddenImpl { span });
|
||||||
return Err(guar);
|
return Err(guar);
|
||||||
};
|
};
|
||||||
Ok((impl1_substs, impl2_substs))
|
Ok((impl1_args, impl2_args))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a list of all of the unconstrained subst of the given impl.
|
/// Returns a list of all of the unconstrained subst of the given impl.
|
||||||
|
@ -217,17 +217,17 @@ fn get_impl_substs(
|
||||||
///
|
///
|
||||||
/// impl<'a, T, I> ... where &'a I: IntoIterator<Item=&'a T>
|
/// impl<'a, T, I> ... where &'a I: IntoIterator<Item=&'a T>
|
||||||
///
|
///
|
||||||
/// This would return the substs corresponding to `['a, I]`, because knowing
|
/// This would return the args corresponding to `['a, I]`, because knowing
|
||||||
/// `'a` and `I` determines the value of `T`.
|
/// `'a` and `I` determines the value of `T`.
|
||||||
fn unconstrained_parent_impl_substs<'tcx>(
|
fn unconstrained_parent_impl_args<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
impl_def_id: DefId,
|
impl_def_id: DefId,
|
||||||
impl_substs: SubstsRef<'tcx>,
|
impl_args: GenericArgsRef<'tcx>,
|
||||||
) -> Vec<GenericArg<'tcx>> {
|
) -> Vec<GenericArg<'tcx>> {
|
||||||
let impl_generic_predicates = tcx.predicates_of(impl_def_id);
|
let impl_generic_predicates = tcx.predicates_of(impl_def_id);
|
||||||
let mut unconstrained_parameters = FxHashSet::default();
|
let mut unconstrained_parameters = FxHashSet::default();
|
||||||
let mut constrained_params = FxHashSet::default();
|
let mut constrained_params = FxHashSet::default();
|
||||||
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).map(ty::EarlyBinder::subst_identity);
|
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).map(ty::EarlyBinder::instantiate_identity);
|
||||||
|
|
||||||
// Unfortunately the functions in `constrained_generic_parameters` don't do
|
// Unfortunately the functions in `constrained_generic_parameters` don't do
|
||||||
// what we want here. We want only a list of constrained parameters while
|
// what we want here. We want only a list of constrained parameters while
|
||||||
|
@ -255,7 +255,7 @@ fn unconstrained_parent_impl_substs<'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_substs
|
impl_args
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|&(idx, _)| !constrained_params.contains(&(idx as u32)))
|
.filter(|&(idx, _)| !constrained_params.contains(&(idx as u32)))
|
||||||
|
@ -264,7 +264,7 @@ fn unconstrained_parent_impl_substs<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check that parameters of the derived impl don't occur more than once in the
|
/// Check that parameters of the derived impl don't occur more than once in the
|
||||||
/// equated substs of the base impl.
|
/// equated args of the base impl.
|
||||||
///
|
///
|
||||||
/// For example forbid the following:
|
/// For example forbid the following:
|
||||||
///
|
///
|
||||||
|
@ -280,19 +280,19 @@ fn unconstrained_parent_impl_substs<'tcx>(
|
||||||
/// impl<T> Tr<T> for Vec<T> { }
|
/// impl<T> Tr<T> for Vec<T> { }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// The substs for the parent impl here are `[T, Vec<T>]`, which repeats `T`,
|
/// The args for the parent impl here are `[T, Vec<T>]`, which repeats `T`,
|
||||||
/// but `S` is constrained in the parent impl, so `parent_substs` is only
|
/// but `S` is constrained in the parent impl, so `parent_args` is only
|
||||||
/// `[Vec<T>]`. This means we allow this impl.
|
/// `[Vec<T>]`. This means we allow this impl.
|
||||||
fn check_duplicate_params<'tcx>(
|
fn check_duplicate_params<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
impl1_substs: SubstsRef<'tcx>,
|
impl1_args: GenericArgsRef<'tcx>,
|
||||||
parent_substs: &Vec<GenericArg<'tcx>>,
|
parent_args: &Vec<GenericArg<'tcx>>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) {
|
) {
|
||||||
let mut base_params = cgp::parameters_for(parent_substs, true);
|
let mut base_params = cgp::parameters_for(parent_args, true);
|
||||||
base_params.sort_by_key(|param| param.0);
|
base_params.sort_by_key(|param| param.0);
|
||||||
if let (_, [duplicate, ..]) = base_params.partition_dedup() {
|
if let (_, [duplicate, ..]) = base_params.partition_dedup() {
|
||||||
let param = impl1_substs[duplicate.0 as usize];
|
let param = impl1_args[duplicate.0 as usize];
|
||||||
tcx.sess
|
tcx.sess
|
||||||
.struct_span_err(span, format!("specializing impl repeats parameter `{}`", param))
|
.struct_span_err(span, format!("specializing impl repeats parameter `{}`", param))
|
||||||
.emit();
|
.emit();
|
||||||
|
@ -309,10 +309,10 @@ fn check_duplicate_params<'tcx>(
|
||||||
/// ```
|
/// ```
|
||||||
fn check_static_lifetimes<'tcx>(
|
fn check_static_lifetimes<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
parent_substs: &Vec<GenericArg<'tcx>>,
|
parent_args: &Vec<GenericArg<'tcx>>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) {
|
) {
|
||||||
if tcx.any_free_region_meets(parent_substs, |r| r.is_static()) {
|
if tcx.any_free_region_meets(parent_args, |r| r.is_static()) {
|
||||||
tcx.sess.emit_err(errors::StaticSpecialize { span });
|
tcx.sess.emit_err(errors::StaticSpecialize { span });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -331,14 +331,14 @@ fn check_static_lifetimes<'tcx>(
|
||||||
fn check_predicates<'tcx>(
|
fn check_predicates<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
impl1_def_id: LocalDefId,
|
impl1_def_id: LocalDefId,
|
||||||
impl1_substs: SubstsRef<'tcx>,
|
impl1_args: GenericArgsRef<'tcx>,
|
||||||
impl2_node: Node,
|
impl2_node: Node,
|
||||||
impl2_substs: SubstsRef<'tcx>,
|
impl2_args: GenericArgsRef<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) {
|
) {
|
||||||
let impl1_predicates: Vec<_> = traits::elaborate(
|
let impl1_predicates: Vec<_> = traits::elaborate(
|
||||||
tcx,
|
tcx,
|
||||||
tcx.predicates_of(impl1_def_id).instantiate(tcx, impl1_substs).into_iter(),
|
tcx.predicates_of(impl1_def_id).instantiate(tcx, impl1_args).into_iter(),
|
||||||
)
|
)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@ -350,7 +350,7 @@ fn check_predicates<'tcx>(
|
||||||
traits::elaborate(
|
traits::elaborate(
|
||||||
tcx,
|
tcx,
|
||||||
tcx.predicates_of(impl2_node.def_id())
|
tcx.predicates_of(impl2_node.def_id())
|
||||||
.instantiate(tcx, impl2_substs)
|
.instantiate(tcx, impl2_args)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(c, _s)| c.as_predicate()),
|
.map(|(c, _s)| c.as_predicate()),
|
||||||
)
|
)
|
||||||
|
@ -385,7 +385,7 @@ fn check_predicates<'tcx>(
|
||||||
.map(|(c, _span)| c.as_predicate());
|
.map(|(c, _span)| c.as_predicate());
|
||||||
|
|
||||||
// Include the well-formed predicates of the type parameters of the impl.
|
// Include the well-formed predicates of the type parameters of the impl.
|
||||||
for arg in tcx.impl_trait_ref(impl1_def_id).unwrap().subst_identity().substs {
|
for arg in tcx.impl_trait_ref(impl1_def_id).unwrap().instantiate_identity().args {
|
||||||
let infcx = &tcx.infer_ctxt().build();
|
let infcx = &tcx.infer_ctxt().build();
|
||||||
let obligations =
|
let obligations =
|
||||||
wf::obligations(infcx, tcx.param_env(impl1_def_id), impl1_def_id, 0, arg, span)
|
wf::obligations(infcx, tcx.param_env(impl1_def_id), impl1_def_id, 0, arg, span)
|
||||||
|
|
|
@ -178,12 +178,12 @@ fn require_same_types<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
||||||
let main_fnsig = tcx.fn_sig(main_def_id).subst_identity();
|
let main_fnsig = tcx.fn_sig(main_def_id).instantiate_identity();
|
||||||
let main_span = tcx.def_span(main_def_id);
|
let main_span = tcx.def_span(main_def_id);
|
||||||
|
|
||||||
fn main_fn_diagnostics_def_id(tcx: TyCtxt<'_>, def_id: DefId, sp: Span) -> LocalDefId {
|
fn main_fn_diagnostics_def_id(tcx: TyCtxt<'_>, def_id: DefId, sp: Span) -> LocalDefId {
|
||||||
if let Some(local_def_id) = def_id.as_local() {
|
if let Some(local_def_id) = def_id.as_local() {
|
||||||
let hir_type = tcx.type_of(local_def_id).subst_identity();
|
let hir_type = tcx.type_of(local_def_id).instantiate_identity();
|
||||||
if !matches!(hir_type.kind(), ty::FnDef(..)) {
|
if !matches!(hir_type.kind(), ty::FnDef(..)) {
|
||||||
span_bug!(sp, "main has a non-function type: found `{}`", hir_type);
|
span_bug!(sp, "main has a non-function type: found `{}`", hir_type);
|
||||||
}
|
}
|
||||||
|
@ -350,7 +350,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
|
||||||
let start_def_id = start_def_id.expect_local();
|
let start_def_id = start_def_id.expect_local();
|
||||||
let start_id = tcx.hir().local_def_id_to_hir_id(start_def_id);
|
let start_id = tcx.hir().local_def_id_to_hir_id(start_def_id);
|
||||||
let start_span = tcx.def_span(start_def_id);
|
let start_span = tcx.def_span(start_def_id);
|
||||||
let start_t = tcx.type_of(start_def_id).subst_identity();
|
let start_t = tcx.type_of(start_def_id).instantiate_identity();
|
||||||
match start_t.kind() {
|
match start_t.kind() {
|
||||||
ty::FnDef(..) => {
|
ty::FnDef(..) => {
|
||||||
if let Some(Node::Item(it)) = tcx.hir().find(start_id) {
|
if let Some(Node::Item(it)) = tcx.hir().find(start_id) {
|
||||||
|
@ -421,7 +421,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
|
||||||
),
|
),
|
||||||
ty::ParamEnv::empty(), // start should not have any where bounds.
|
ty::ParamEnv::empty(), // start should not have any where bounds.
|
||||||
se_ty,
|
se_ty,
|
||||||
Ty::new_fn_ptr(tcx, tcx.fn_sig(start_def_id).subst_identity()),
|
Ty::new_fn_ptr(tcx, tcx.fn_sig(start_def_id).instantiate_identity()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|
|
@ -46,7 +46,7 @@ pub(super) fn infer_predicates(
|
||||||
// For field of type &'a T (reference) or Adt
|
// For field of type &'a T (reference) or Adt
|
||||||
// (struct/enum/union) there will be outlive
|
// (struct/enum/union) there will be outlive
|
||||||
// requirements for adt_def.
|
// requirements for adt_def.
|
||||||
let field_ty = tcx.type_of(field_def.did).subst_identity();
|
let field_ty = tcx.type_of(field_def.did).instantiate_identity();
|
||||||
let field_span = tcx.def_span(field_def.did);
|
let field_span = tcx.def_span(field_def.did);
|
||||||
insert_required_predicates_to_be_wf(
|
insert_required_predicates_to_be_wf(
|
||||||
tcx,
|
tcx,
|
||||||
|
@ -117,7 +117,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
|
||||||
// can load the current set of inferred and explicit
|
// can load the current set of inferred and explicit
|
||||||
// predicates from `global_inferred_outlives` and filter the
|
// predicates from `global_inferred_outlives` and filter the
|
||||||
// ones that are TypeOutlives.
|
// ones that are TypeOutlives.
|
||||||
ty::Adt(def, substs) => {
|
ty::Adt(def, args) => {
|
||||||
// First check the inferred predicates
|
// First check the inferred predicates
|
||||||
//
|
//
|
||||||
// Example 1:
|
// Example 1:
|
||||||
|
@ -146,7 +146,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
|
||||||
// get `T: 'a` (or `predicate`):
|
// get `T: 'a` (or `predicate`):
|
||||||
let predicate = unsubstituted_predicates
|
let predicate = unsubstituted_predicates
|
||||||
.rebind(*unsubstituted_predicate)
|
.rebind(*unsubstituted_predicate)
|
||||||
.subst(tcx, substs);
|
.instantiate(tcx, args);
|
||||||
insert_outlives_predicate(
|
insert_outlives_predicate(
|
||||||
tcx,
|
tcx,
|
||||||
predicate.0,
|
predicate.0,
|
||||||
|
@ -159,11 +159,11 @@ fn insert_required_predicates_to_be_wf<'tcx>(
|
||||||
|
|
||||||
// Check if the type has any explicit predicates that need
|
// Check if the type has any explicit predicates that need
|
||||||
// to be added to `required_predicates`
|
// to be added to `required_predicates`
|
||||||
// let _: () = substs.region_at(0);
|
// let _: () = args.region_at(0);
|
||||||
check_explicit_predicates(
|
check_explicit_predicates(
|
||||||
tcx,
|
tcx,
|
||||||
def.did(),
|
def.did(),
|
||||||
substs,
|
args,
|
||||||
required_predicates,
|
required_predicates,
|
||||||
explicit_map,
|
explicit_map,
|
||||||
None,
|
None,
|
||||||
|
@ -186,12 +186,11 @@ fn insert_required_predicates_to_be_wf<'tcx>(
|
||||||
// predicates in `check_explicit_predicates` we
|
// predicates in `check_explicit_predicates` we
|
||||||
// need to ignore checking the explicit_map for
|
// need to ignore checking the explicit_map for
|
||||||
// Self type.
|
// Self type.
|
||||||
let substs =
|
let args = ex_trait_ref.with_self_ty(tcx, tcx.types.usize).skip_binder().args;
|
||||||
ex_trait_ref.with_self_ty(tcx, tcx.types.usize).skip_binder().substs;
|
|
||||||
check_explicit_predicates(
|
check_explicit_predicates(
|
||||||
tcx,
|
tcx,
|
||||||
ex_trait_ref.skip_binder().def_id,
|
ex_trait_ref.skip_binder().def_id,
|
||||||
substs,
|
args,
|
||||||
required_predicates,
|
required_predicates,
|
||||||
explicit_map,
|
explicit_map,
|
||||||
Some(tcx.types.self_param),
|
Some(tcx.types.self_param),
|
||||||
|
@ -206,7 +205,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
|
||||||
check_explicit_predicates(
|
check_explicit_predicates(
|
||||||
tcx,
|
tcx,
|
||||||
tcx.parent(obj.def_id),
|
tcx.parent(obj.def_id),
|
||||||
obj.substs,
|
obj.args,
|
||||||
required_predicates,
|
required_predicates,
|
||||||
explicit_map,
|
explicit_map,
|
||||||
None,
|
None,
|
||||||
|
@ -239,18 +238,18 @@ fn insert_required_predicates_to_be_wf<'tcx>(
|
||||||
fn check_explicit_predicates<'tcx>(
|
fn check_explicit_predicates<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
substs: &[GenericArg<'tcx>],
|
args: &[GenericArg<'tcx>],
|
||||||
required_predicates: &mut RequiredPredicates<'tcx>,
|
required_predicates: &mut RequiredPredicates<'tcx>,
|
||||||
explicit_map: &mut ExplicitPredicatesMap<'tcx>,
|
explicit_map: &mut ExplicitPredicatesMap<'tcx>,
|
||||||
ignored_self_ty: Option<Ty<'tcx>>,
|
ignored_self_ty: Option<Ty<'tcx>>,
|
||||||
) {
|
) {
|
||||||
debug!(
|
debug!(
|
||||||
"check_explicit_predicates(def_id={:?}, \
|
"check_explicit_predicates(def_id={:?}, \
|
||||||
substs={:?}, \
|
args={:?}, \
|
||||||
explicit_map={:?}, \
|
explicit_map={:?}, \
|
||||||
required_predicates={:?}, \
|
required_predicates={:?}, \
|
||||||
ignored_self_ty={:?})",
|
ignored_self_ty={:?})",
|
||||||
def_id, substs, explicit_map, required_predicates, ignored_self_ty,
|
def_id, args, explicit_map, required_predicates, ignored_self_ty,
|
||||||
);
|
);
|
||||||
let explicit_predicates = explicit_map.explicit_predicates_of(tcx, def_id);
|
let explicit_predicates = explicit_map.explicit_predicates_of(tcx, def_id);
|
||||||
|
|
||||||
|
@ -278,10 +277,10 @@ fn check_explicit_predicates<'tcx>(
|
||||||
// that is represented by the `dyn Trait`, not to the `X` type parameter
|
// that is represented by the `dyn Trait`, not to the `X` type parameter
|
||||||
// (or any other generic parameter) declared on `MyStruct`.
|
// (or any other generic parameter) declared on `MyStruct`.
|
||||||
//
|
//
|
||||||
// Note that we do this check for self **before** applying `substs`. In the
|
// Note that we do this check for self **before** applying `args`. In the
|
||||||
// case that `substs` come from a `dyn Trait` type, our caller will have
|
// case that `args` come from a `dyn Trait` type, our caller will have
|
||||||
// included `Self = usize` as the value for `Self`. If we were
|
// included `Self = usize` as the value for `Self`. If we were
|
||||||
// to apply the substs, and not filter this predicate, we might then falsely
|
// to apply the args, and not filter this predicate, we might then falsely
|
||||||
// conclude that e.g., `X: 'x` was a reasonable inferred requirement.
|
// conclude that e.g., `X: 'x` was a reasonable inferred requirement.
|
||||||
//
|
//
|
||||||
// Another similar case is where we have an inferred
|
// Another similar case is where we have an inferred
|
||||||
|
@ -299,7 +298,7 @@ fn check_explicit_predicates<'tcx>(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let predicate = explicit_predicates.rebind(*outlives_predicate).subst(tcx, substs);
|
let predicate = explicit_predicates.rebind(*outlives_predicate).instantiate(tcx, args);
|
||||||
debug!("predicate = {:?}", &predicate);
|
debug!("predicate = {:?}", &predicate);
|
||||||
insert_outlives_predicate(tcx, predicate.0, predicate.1, span, required_predicates);
|
insert_outlives_predicate(tcx, predicate.0, predicate.1, span, required_predicates);
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue