Rollup merge of #109410 - fmease:iat-alias-kind-inherent, r=compiler-errors
Introduce `AliasKind::Inherent` for inherent associated types Allows us to check (possibly generic) inherent associated types for well-formedness. Type inference now also works properly. Follow-up to #105961. Supersedes #108430. Fixes #106722. Fixes #108957. Fixes #109768. Fixes #109789. Fixes #109790. ~Not to be merged before #108860 (`AliasKind::Weak`).~ CC `@jackh726` r? `@compiler-errors` `@rustbot` label T-types F-inherent_associated_types
This commit is contained in:
commit
29ac429c9b
96 changed files with 1365 additions and 229 deletions
|
@ -89,3 +89,11 @@ impl IntoDiagnostic<'_> for NegativePositiveConflict<'_> {
|
|||
diag
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(trait_selection_inherent_projection_normalization_overflow)]
|
||||
pub struct InherentProjectionNormalizationOverflow {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub ty: String,
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
|
|||
ty::Dynamic(..)
|
||||
| ty::Param(..)
|
||||
| ty::Foreign(..)
|
||||
| ty::Alias(ty::Projection, ..)
|
||||
| ty::Alias(ty::Projection | ty::Inherent, ..)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Bound(..)
|
||||
| ty::Infer(_) => {
|
||||
|
|
|
@ -655,7 +655,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
ty::Dynamic(..)
|
||||
| ty::Param(..)
|
||||
| ty::Foreign(..)
|
||||
| ty::Alias(ty::Projection, ..)
|
||||
| ty::Alias(ty::Projection | ty::Inherent, ..)
|
||||
| ty::Placeholder(..) => Some(Err(NoSolution)),
|
||||
|
||||
ty::Infer(_) | ty::Bound(_, _) => bug!("unexpected type `{self_ty}`"),
|
||||
|
|
|
@ -673,7 +673,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OrphanChecker<'tcx> {
|
|||
| ty::RawPtr(..)
|
||||
| ty::Never
|
||||
| ty::Tuple(..)
|
||||
| ty::Alias(ty::Projection, ..) => self.found_non_local_ty(ty),
|
||||
| ty::Alias(ty::Projection | ty::Inherent, ..) => self.found_non_local_ty(ty),
|
||||
|
||||
ty::Param(..) => self.found_param_ty(ty),
|
||||
|
||||
|
|
|
@ -1687,13 +1687,14 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
ty::Tuple(..) => Some(10),
|
||||
ty::Param(..) => Some(11),
|
||||
ty::Alias(ty::Projection, ..) => Some(12),
|
||||
ty::Alias(ty::Opaque, ..) => Some(13),
|
||||
ty::Never => Some(14),
|
||||
ty::Adt(..) => Some(15),
|
||||
ty::Generator(..) => Some(16),
|
||||
ty::Foreign(..) => Some(17),
|
||||
ty::GeneratorWitness(..) => Some(18),
|
||||
ty::GeneratorWitnessMIR(..) => Some(19),
|
||||
ty::Alias(ty::Inherent, ..) => Some(13),
|
||||
ty::Alias(ty::Opaque, ..) => Some(14),
|
||||
ty::Never => Some(15),
|
||||
ty::Adt(..) => Some(16),
|
||||
ty::Generator(..) => Some(17),
|
||||
ty::Foreign(..) => Some(18),
|
||||
ty::GeneratorWitness(..) => Some(19),
|
||||
ty::GeneratorWitnessMIR(..) => Some(20),
|
||||
ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error(_) => None,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,7 +49,8 @@ pub use self::object_safety::astconv_object_safety_violations;
|
|||
pub use self::object_safety::is_vtable_safe_method;
|
||||
pub use self::object_safety::MethodViolationCode;
|
||||
pub use self::object_safety::ObjectSafetyViolation;
|
||||
pub use self::project::{normalize_projection_type, NormalizeExt};
|
||||
pub use self::project::NormalizeExt;
|
||||
pub use self::project::{normalize_inherent_projection, normalize_projection_type};
|
||||
pub use self::select::{EvaluationCache, SelectionCache, SelectionContext};
|
||||
pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError};
|
||||
pub use self::specialize::specialization_graph::FutureCompatOverlapError;
|
||||
|
|
|
@ -16,6 +16,7 @@ use super::{
|
|||
};
|
||||
use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey};
|
||||
|
||||
use crate::errors::InherentProjectionNormalizationOverflow;
|
||||
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
|
||||
use crate::traits::error_reporting::TypeErrCtxtExt as _;
|
||||
|
@ -370,10 +371,14 @@ pub(crate) fn needs_normalization<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
|
|||
reveal: Reveal,
|
||||
) -> bool {
|
||||
match reveal {
|
||||
Reveal::UserFacing => value
|
||||
.has_type_flags(ty::TypeFlags::HAS_TY_PROJECTION | ty::TypeFlags::HAS_CT_PROJECTION),
|
||||
Reveal::UserFacing => value.has_type_flags(
|
||||
ty::TypeFlags::HAS_TY_PROJECTION
|
||||
| ty::TypeFlags::HAS_TY_INHERENT
|
||||
| ty::TypeFlags::HAS_CT_PROJECTION,
|
||||
),
|
||||
Reveal::All => value.has_type_flags(
|
||||
ty::TypeFlags::HAS_TY_PROJECTION
|
||||
| ty::TypeFlags::HAS_TY_INHERENT
|
||||
| ty::TypeFlags::HAS_TY_OPAQUE
|
||||
| ty::TypeFlags::HAS_CT_PROJECTION,
|
||||
),
|
||||
|
@ -616,6 +621,51 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
|
|||
);
|
||||
normalized_ty
|
||||
}
|
||||
|
||||
ty::Inherent if !data.has_escaping_bound_vars() => {
|
||||
// This branch is *mostly* just an optimization: when we don't
|
||||
// have escaping bound vars, we don't need to replace them with
|
||||
// placeholders (see branch below). *Also*, we know that we can
|
||||
// register an obligation to *later* project, since we know
|
||||
// there won't be bound vars there.
|
||||
|
||||
let data = data.fold_with(self);
|
||||
|
||||
// FIXME(inherent_associated_types): Do we need to honor `self.eager_inference_replacement`
|
||||
// here like `ty::Projection`?
|
||||
normalize_inherent_projection(
|
||||
self.selcx,
|
||||
self.param_env,
|
||||
data,
|
||||
self.cause.clone(),
|
||||
self.depth,
|
||||
&mut self.obligations,
|
||||
)
|
||||
}
|
||||
|
||||
ty::Inherent => {
|
||||
let infcx = self.selcx.infcx;
|
||||
let (data, mapped_regions, mapped_types, mapped_consts) =
|
||||
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data);
|
||||
let data = data.fold_with(self);
|
||||
let ty = normalize_inherent_projection(
|
||||
self.selcx,
|
||||
self.param_env,
|
||||
data,
|
||||
self.cause.clone(),
|
||||
self.depth,
|
||||
&mut self.obligations,
|
||||
);
|
||||
|
||||
PlaceholderReplacer::replace_placeholders(
|
||||
infcx,
|
||||
mapped_regions,
|
||||
mapped_types,
|
||||
mapped_consts,
|
||||
&self.universes,
|
||||
ty,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1204,6 +1254,115 @@ fn normalize_to_error<'a, 'tcx>(
|
|||
Normalized { value: new_value, obligations: vec![trait_obligation] }
|
||||
}
|
||||
|
||||
/// Confirm and normalize the given inherent projection.
|
||||
#[instrument(level = "debug", skip(selcx, param_env, cause, obligations))]
|
||||
pub fn normalize_inherent_projection<'a, 'b, 'tcx>(
|
||||
selcx: &'a mut SelectionContext<'b, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
alias_ty: ty::AliasTy<'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
depth: usize,
|
||||
obligations: &mut Vec<PredicateObligation<'tcx>>,
|
||||
) -> Ty<'tcx> {
|
||||
let tcx = selcx.tcx();
|
||||
|
||||
if !tcx.recursion_limit().value_within_limit(depth) {
|
||||
// Halt compilation because it is important that overflows never be masked.
|
||||
tcx.sess.emit_fatal(InherentProjectionNormalizationOverflow {
|
||||
span: cause.span,
|
||||
ty: alias_ty.to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
let substs = compute_inherent_assoc_ty_substs(
|
||||
selcx,
|
||||
param_env,
|
||||
alias_ty,
|
||||
cause.clone(),
|
||||
depth,
|
||||
obligations,
|
||||
);
|
||||
|
||||
// Register the obligations arising from the impl and from the associated type itself.
|
||||
let predicates = tcx.predicates_of(alias_ty.def_id).instantiate(tcx, substs);
|
||||
for (predicate, span) in predicates {
|
||||
let predicate = normalize_with_depth_to(
|
||||
selcx,
|
||||
param_env,
|
||||
cause.clone(),
|
||||
depth + 1,
|
||||
predicate,
|
||||
obligations,
|
||||
);
|
||||
|
||||
let nested_cause = ObligationCause::new(
|
||||
cause.span,
|
||||
cause.body_id,
|
||||
// FIXME(inherent_associated_types): Since we can't pass along the self type to the
|
||||
// cause code, inherent projections will be printed with identity substitutions in
|
||||
// diagnostics which is not ideal.
|
||||
// Consider creating separate cause codes for this specific situation.
|
||||
if span.is_dummy() {
|
||||
super::ItemObligation(alias_ty.def_id)
|
||||
} else {
|
||||
super::BindingObligation(alias_ty.def_id, span)
|
||||
},
|
||||
);
|
||||
|
||||
obligations.push(Obligation::with_depth(
|
||||
tcx,
|
||||
nested_cause,
|
||||
depth + 1,
|
||||
param_env,
|
||||
predicate,
|
||||
));
|
||||
}
|
||||
|
||||
let ty = tcx.type_of(alias_ty.def_id).subst(tcx, substs);
|
||||
|
||||
let mut ty = selcx.infcx.resolve_vars_if_possible(ty);
|
||||
if ty.has_projections() {
|
||||
ty = normalize_with_depth_to(selcx, param_env, cause.clone(), depth + 1, ty, obligations);
|
||||
}
|
||||
|
||||
ty
|
||||
}
|
||||
|
||||
pub fn compute_inherent_assoc_ty_substs<'a, 'b, 'tcx>(
|
||||
selcx: &'a mut SelectionContext<'b, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
alias_ty: ty::AliasTy<'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
depth: usize,
|
||||
obligations: &mut Vec<PredicateObligation<'tcx>>,
|
||||
) -> ty::SubstsRef<'tcx> {
|
||||
let tcx = selcx.tcx();
|
||||
|
||||
let impl_def_id = tcx.parent(alias_ty.def_id);
|
||||
let impl_substs = selcx.infcx.fresh_substs_for_item(cause.span, impl_def_id);
|
||||
|
||||
let impl_ty = tcx.type_of(impl_def_id).subst(tcx, impl_substs);
|
||||
let impl_ty =
|
||||
normalize_with_depth_to(selcx, param_env, cause.clone(), depth + 1, impl_ty, obligations);
|
||||
|
||||
// Infer the generic parameters of the impl by unifying the
|
||||
// impl type with the self type of the projection.
|
||||
let self_ty = alias_ty.self_ty();
|
||||
match selcx.infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, impl_ty, self_ty) {
|
||||
Ok(mut ok) => obligations.append(&mut ok.obligations),
|
||||
Err(_) => {
|
||||
tcx.sess.delay_span_bug(
|
||||
cause.span,
|
||||
format!(
|
||||
"{self_ty:?} was a subtype of {impl_ty:?} during selection but now it is not"
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
alias_ty.rebase_substs_onto_impl(impl_substs, tcx)
|
||||
}
|
||||
|
||||
enum Projected<'tcx> {
|
||||
Progress(Progress<'tcx>),
|
||||
NoProgress(ty::Term<'tcx>),
|
||||
|
|
|
@ -257,11 +257,11 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
|
|||
|
||||
ty::Opaque => ty.try_super_fold_with(self)?,
|
||||
|
||||
ty::Projection => {
|
||||
ty::Projection | ty::Inherent => {
|
||||
// See note in `rustc_trait_selection::traits::project`
|
||||
|
||||
let tcx = self.infcx.tcx;
|
||||
let infcx = self.infcx;
|
||||
let tcx = infcx.tcx;
|
||||
// Just an optimization: When we don't have escaping bound vars,
|
||||
// we don't need to replace them with placeholders.
|
||||
let (data, maps) = if data.has_escaping_bound_vars() {
|
||||
|
@ -276,12 +276,15 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
|
|||
let mut orig_values = OriginalQueryValues::default();
|
||||
// HACK(matthewjasper) `'static` is special-cased in selection,
|
||||
// so we cannot canonicalize it.
|
||||
let c_data = self
|
||||
.infcx
|
||||
let c_data = infcx
|
||||
.canonicalize_query_keep_static(self.param_env.and(data), &mut orig_values);
|
||||
debug!("QueryNormalizer: c_data = {:#?}", c_data);
|
||||
debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
|
||||
let result = tcx.normalize_projection_ty(c_data)?;
|
||||
let result = match kind {
|
||||
ty::Projection => tcx.normalize_projection_ty(c_data),
|
||||
ty::Inherent => tcx.normalize_inherent_projection_ty(c_data),
|
||||
_ => unreachable!(),
|
||||
}?;
|
||||
// We don't expect ambiguity.
|
||||
if result.is_ambiguous() {
|
||||
// Rustdoc normalizes possibly not well-formed types, so only
|
||||
|
@ -294,8 +297,8 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
|
|||
}
|
||||
return Err(NoSolution);
|
||||
}
|
||||
let InferOk { value: result, obligations } =
|
||||
self.infcx.instantiate_query_response_and_region_obligations(
|
||||
let InferOk { value: result, obligations } = infcx
|
||||
.instantiate_query_response_and_region_obligations(
|
||||
self.cause,
|
||||
self.param_env,
|
||||
&orig_values,
|
||||
|
|
|
@ -498,7 +498,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
// this trait and type.
|
||||
}
|
||||
ty::Param(..)
|
||||
| ty::Alias(ty::Projection, ..)
|
||||
| ty::Alias(ty::Projection | ty::Inherent, ..)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Bound(..) => {
|
||||
// In these cases, we don't know what the actual
|
||||
|
|
|
@ -1268,7 +1268,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
|
||||
// If we have a projection type, make sure to normalize it so we replace it
|
||||
// with a fresh infer variable
|
||||
ty::Alias(ty::Projection, ..) => {
|
||||
ty::Alias(ty::Projection | ty::Inherent, ..) => {
|
||||
let predicate = normalize_with_depth_to(
|
||||
self,
|
||||
obligation.param_env,
|
||||
|
|
|
@ -2315,7 +2315,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
|||
| ty::Dynamic(..)
|
||||
| ty::Param(..)
|
||||
| ty::Foreign(..)
|
||||
| ty::Alias(ty::Projection, ..)
|
||||
| ty::Alias(ty::Projection | ty::Inherent, ..)
|
||||
| ty::Bound(..)
|
||||
| ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
|
||||
bug!("asked to assemble constituent types of unexpected type: {:?}", t);
|
||||
|
|
|
@ -58,15 +58,8 @@ pub fn obligations<'tcx>(
|
|||
GenericArgKind::Lifetime(..) => return Some(Vec::new()),
|
||||
};
|
||||
|
||||
let mut wf = WfPredicates {
|
||||
tcx: infcx.tcx,
|
||||
param_env,
|
||||
body_id,
|
||||
span,
|
||||
out: vec![],
|
||||
recursion_depth,
|
||||
item: None,
|
||||
};
|
||||
let mut wf =
|
||||
WfPredicates { infcx, param_env, body_id, span, out: vec![], recursion_depth, item: None };
|
||||
wf.compute(arg);
|
||||
debug!("wf::obligations({:?}, body_id={:?}) = {:?}", arg, body_id, wf.out);
|
||||
|
||||
|
@ -91,7 +84,7 @@ pub fn unnormalized_obligations<'tcx>(
|
|||
debug_assert_eq!(arg, infcx.resolve_vars_if_possible(arg));
|
||||
|
||||
let mut wf = WfPredicates {
|
||||
tcx: infcx.tcx,
|
||||
infcx,
|
||||
param_env,
|
||||
body_id: CRATE_DEF_ID,
|
||||
span: DUMMY_SP,
|
||||
|
@ -116,7 +109,7 @@ pub fn trait_obligations<'tcx>(
|
|||
item: &'tcx hir::Item<'tcx>,
|
||||
) -> Vec<traits::PredicateObligation<'tcx>> {
|
||||
let mut wf = WfPredicates {
|
||||
tcx: infcx.tcx,
|
||||
infcx,
|
||||
param_env,
|
||||
body_id,
|
||||
span,
|
||||
|
@ -138,7 +131,7 @@ pub fn predicate_obligations<'tcx>(
|
|||
span: Span,
|
||||
) -> Vec<traits::PredicateObligation<'tcx>> {
|
||||
let mut wf = WfPredicates {
|
||||
tcx: infcx.tcx,
|
||||
infcx,
|
||||
param_env,
|
||||
body_id,
|
||||
span,
|
||||
|
@ -190,8 +183,8 @@ pub fn predicate_obligations<'tcx>(
|
|||
wf.normalize(infcx)
|
||||
}
|
||||
|
||||
struct WfPredicates<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
struct WfPredicates<'a, 'tcx> {
|
||||
infcx: &'a InferCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
body_id: LocalDefId,
|
||||
span: Span,
|
||||
|
@ -290,9 +283,9 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> WfPredicates<'tcx> {
|
||||
impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn cause(&self, code: traits::ObligationCauseCode<'tcx>) -> traits::ObligationCause<'tcx> {
|
||||
|
@ -325,7 +318,7 @@ impl<'tcx> WfPredicates<'tcx> {
|
|||
|
||||
/// Pushes the obligations required for `trait_ref` to be WF into `self.out`.
|
||||
fn compute_trait_pred(&mut self, trait_pred: &ty::TraitPredicate<'tcx>, elaborate: Elaborate) {
|
||||
let tcx = self.tcx;
|
||||
let tcx = self.tcx();
|
||||
let trait_ref = &trait_pred.trait_ref;
|
||||
|
||||
// Negative trait predicates don't require supertraits to hold, just
|
||||
|
@ -369,7 +362,6 @@ impl<'tcx> WfPredicates<'tcx> {
|
|||
self.out.extend(obligations);
|
||||
}
|
||||
|
||||
let tcx = self.tcx();
|
||||
self.out.extend(
|
||||
trait_ref
|
||||
.substs
|
||||
|
@ -436,13 +428,45 @@ impl<'tcx> WfPredicates<'tcx> {
|
|||
let obligations = self.nominal_obligations_without_const(data.def_id, data.substs);
|
||||
self.out.extend(obligations);
|
||||
|
||||
self.compute_projection_substs(data.substs);
|
||||
}
|
||||
|
||||
fn compute_inherent_projection(&mut self, data: ty::AliasTy<'tcx>) {
|
||||
// An inherent projection is well-formed if
|
||||
//
|
||||
// (a) its predicates hold (*)
|
||||
// (b) its substs are wf
|
||||
//
|
||||
// (*) The predicates of an inherent associated type include the
|
||||
// predicates of the impl that it's contained in.
|
||||
|
||||
if !data.self_ty().has_escaping_bound_vars() {
|
||||
// FIXME(inherent_associated_types): Should this happen inside of a snapshot?
|
||||
// FIXME(inherent_associated_types): This is incompatible with the new solver and lazy norm!
|
||||
let substs = traits::project::compute_inherent_assoc_ty_substs(
|
||||
&mut traits::SelectionContext::new(self.infcx),
|
||||
self.param_env,
|
||||
data,
|
||||
self.cause(traits::WellFormed(None)),
|
||||
self.recursion_depth,
|
||||
&mut self.out,
|
||||
);
|
||||
// Inherent projection types do not require const predicates.
|
||||
let obligations = self.nominal_obligations_without_const(data.def_id, substs);
|
||||
self.out.extend(obligations);
|
||||
}
|
||||
|
||||
self.compute_projection_substs(data.substs);
|
||||
}
|
||||
|
||||
fn compute_projection_substs(&mut self, substs: SubstsRef<'tcx>) {
|
||||
let tcx = self.tcx();
|
||||
let cause = self.cause(traits::WellFormed(None));
|
||||
let param_env = self.param_env;
|
||||
let depth = self.recursion_depth;
|
||||
|
||||
self.out.extend(
|
||||
data.substs
|
||||
substs
|
||||
.iter()
|
||||
.filter(|arg| {
|
||||
matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..))
|
||||
|
@ -464,9 +488,9 @@ impl<'tcx> WfPredicates<'tcx> {
|
|||
if !subty.has_escaping_bound_vars() {
|
||||
let cause = self.cause(cause);
|
||||
let trait_ref =
|
||||
ty::TraitRef::from_lang_item(self.tcx, LangItem::Sized, cause.span, [subty]);
|
||||
ty::TraitRef::from_lang_item(self.tcx(), LangItem::Sized, cause.span, [subty]);
|
||||
self.out.push(traits::Obligation::with_depth(
|
||||
self.tcx,
|
||||
self.tcx(),
|
||||
cause,
|
||||
self.recursion_depth,
|
||||
self.param_env,
|
||||
|
@ -605,6 +629,10 @@ impl<'tcx> WfPredicates<'tcx> {
|
|||
walker.skip_current_subtree(); // Subtree handled by compute_projection.
|
||||
self.compute_projection(data);
|
||||
}
|
||||
ty::Alias(ty::Inherent, data) => {
|
||||
walker.skip_current_subtree(); // Subtree handled by compute_inherent_projection.
|
||||
self.compute_inherent_projection(data);
|
||||
}
|
||||
|
||||
ty::Adt(def, substs) => {
|
||||
// WfNominalType
|
||||
|
@ -697,7 +725,7 @@ impl<'tcx> WfPredicates<'tcx> {
|
|||
// All of the requirements on type parameters
|
||||
// have already been checked for `impl Trait` in
|
||||
// return position. We do need to check type-alias-impl-trait though.
|
||||
if self.tcx.is_type_alias_impl_trait(def_id) {
|
||||
if self.tcx().is_type_alias_impl_trait(def_id) {
|
||||
let obligations = self.nominal_obligations(def_id, substs);
|
||||
self.out.extend(obligations);
|
||||
}
|
||||
|
@ -767,15 +795,15 @@ impl<'tcx> WfPredicates<'tcx> {
|
|||
substs: SubstsRef<'tcx>,
|
||||
remap_constness: bool,
|
||||
) -> Vec<traits::PredicateObligation<'tcx>> {
|
||||
let predicates = self.tcx.predicates_of(def_id);
|
||||
let predicates = self.tcx().predicates_of(def_id);
|
||||
let mut origins = vec![def_id; predicates.predicates.len()];
|
||||
let mut head = predicates;
|
||||
while let Some(parent) = head.parent {
|
||||
head = self.tcx.predicates_of(parent);
|
||||
head = self.tcx().predicates_of(parent);
|
||||
origins.extend(iter::repeat(parent).take(head.predicates.len()));
|
||||
}
|
||||
|
||||
let predicates = predicates.instantiate(self.tcx, substs);
|
||||
let predicates = predicates.instantiate(self.tcx(), substs);
|
||||
trace!("{:#?}", predicates);
|
||||
debug_assert_eq!(predicates.predicates.len(), origins.len());
|
||||
|
||||
|
@ -788,10 +816,10 @@ impl<'tcx> WfPredicates<'tcx> {
|
|||
};
|
||||
let cause = self.cause(code);
|
||||
if remap_constness {
|
||||
pred = pred.without_const(self.tcx);
|
||||
pred = pred.without_const(self.tcx());
|
||||
}
|
||||
traits::Obligation::with_depth(
|
||||
self.tcx,
|
||||
self.tcx(),
|
||||
cause,
|
||||
self.recursion_depth,
|
||||
self.param_env,
|
||||
|
@ -856,7 +884,7 @@ impl<'tcx> WfPredicates<'tcx> {
|
|||
// Note: in fact we only permit builtin traits, not `Bar<'d>`, I
|
||||
// am looking forward to the future here.
|
||||
if !data.has_escaping_bound_vars() && !region.has_escaping_bound_vars() {
|
||||
let implicit_bounds = object_region_bounds(self.tcx, data);
|
||||
let implicit_bounds = object_region_bounds(self.tcx(), data);
|
||||
|
||||
let explicit_bound = region;
|
||||
|
||||
|
@ -866,7 +894,7 @@ impl<'tcx> WfPredicates<'tcx> {
|
|||
let outlives =
|
||||
ty::Binder::dummy(ty::OutlivesPredicate(explicit_bound, implicit_bound));
|
||||
self.out.push(traits::Obligation::with_depth(
|
||||
self.tcx,
|
||||
self.tcx(),
|
||||
cause,
|
||||
self.recursion_depth,
|
||||
self.param_env,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue