Assume we can normalize trait default method RPITITs in param-env instead
This commit is contained in:
parent
be55ad53a1
commit
d42a3fbd69
3 changed files with 81 additions and 4 deletions
|
@ -1599,7 +1599,7 @@ fn check_return_position_impl_trait_in_trait_bounds<'tcx>(
|
||||||
{
|
{
|
||||||
for arg in fn_output.walk() {
|
for arg in fn_output.walk() {
|
||||||
if let ty::GenericArgKind::Type(ty) = arg.unpack()
|
if let ty::GenericArgKind::Type(ty) = arg.unpack()
|
||||||
&& let ty::Alias(ty::Projection, proj) = ty.kind()
|
&& let ty::Alias(ty::Opaque, proj) = ty.kind()
|
||||||
&& tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder
|
&& tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder
|
||||||
&& tcx.impl_trait_in_trait_parent(proj.def_id) == fn_def_id.to_def_id()
|
&& tcx.impl_trait_in_trait_parent(proj.def_id) == fn_def_id.to_def_id()
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||||
use crate::mir;
|
use crate::mir;
|
||||||
use crate::ty::layout::IntegerExt;
|
use crate::ty::layout::IntegerExt;
|
||||||
use crate::ty::{
|
use crate::ty::{
|
||||||
self, ir::TypeFolder, DefIdTree, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable,
|
self, ir::TypeFolder, DefIdTree, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable,
|
||||||
TypeSuperFoldable,
|
TypeSuperFoldable,
|
||||||
};
|
};
|
||||||
use crate::ty::{GenericArgKind, SubstsRef};
|
use crate::ty::{GenericArgKind, SubstsRef};
|
||||||
|
@ -865,6 +865,26 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for OpaqueTypeExpander<'tcx> {
|
||||||
}
|
}
|
||||||
t
|
t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
|
||||||
|
if let ty::PredicateKind::Clause(clause) = p.kind().skip_binder()
|
||||||
|
&& let ty::Clause::Projection(projection_pred) = clause
|
||||||
|
{
|
||||||
|
p.kind()
|
||||||
|
.rebind(ty::ProjectionPredicate {
|
||||||
|
projection_ty: projection_pred.projection_ty.fold_with(self),
|
||||||
|
// Don't fold the term on the RHS of the projection predicate.
|
||||||
|
// This is because for default trait methods with RPITITs, we
|
||||||
|
// install a `NormalizesTo(Projection(RPITIT) -> Opaque(RPITIT))`
|
||||||
|
// predicate, which would trivially cause a cycle when we do
|
||||||
|
// anything that requires `ParamEnv::with_reveal_all_normalized`.
|
||||||
|
term: projection_pred.term,
|
||||||
|
})
|
||||||
|
.to_predicate(self.tcx)
|
||||||
|
} else {
|
||||||
|
p.super_fold_with(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Ty<'tcx> {
|
impl<'tcx> Ty<'tcx> {
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
use rustc_data_structures::fx::FxIndexSet;
|
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_index::bit_set::BitSet;
|
use rustc_index::bit_set::BitSet;
|
||||||
|
#[cfg(not(bootstrap))]
|
||||||
|
use rustc_middle::ty::ir::TypeVisitable;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, Binder, EarlyBinder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt,
|
self, ir::TypeVisitor, Binder, EarlyBinder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt,
|
||||||
|
TypeSuperVisitable,
|
||||||
};
|
};
|
||||||
use rustc_session::config::TraitSolver;
|
use rustc_session::config::TraitSolver;
|
||||||
use rustc_span::def_id::{DefId, CRATE_DEF_ID};
|
use rustc_span::def_id::{DefId, CRATE_DEF_ID};
|
||||||
|
@ -136,6 +140,19 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
||||||
predicates.extend(environment);
|
predicates.extend(environment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tcx.def_kind(def_id) == DefKind::AssocFn
|
||||||
|
&& tcx.associated_item(def_id).container == ty::AssocItemContainer::TraitContainer
|
||||||
|
{
|
||||||
|
let sig = tcx.fn_sig(def_id).subst_identity();
|
||||||
|
sig.visit_with(&mut ImplTraitInTraitFinder {
|
||||||
|
tcx,
|
||||||
|
fn_def_id: def_id,
|
||||||
|
bound_vars: sig.bound_vars(),
|
||||||
|
predicates: &mut predicates,
|
||||||
|
seen: FxHashSet::default(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let local_did = def_id.as_local();
|
let local_did = def_id.as_local();
|
||||||
let hir_id = local_did.map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id));
|
let hir_id = local_did.map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id));
|
||||||
|
|
||||||
|
@ -222,6 +239,46 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
||||||
traits::normalize_param_env_or_error(tcx, unnormalized_env, cause)
|
traits::normalize_param_env_or_error(tcx, unnormalized_env, cause)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Walk through a function type, gathering all RPITITs and installing a
|
||||||
|
/// `NormalizesTo(Projection(RPITIT) -> Opaque(RPITIT))` predicate into the
|
||||||
|
/// predicates list. This allows us to observe that an RPITIT projects to
|
||||||
|
/// its corresponding opaque within the body of a default-body trait method.
|
||||||
|
struct ImplTraitInTraitFinder<'a, 'tcx> {
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
predicates: &'a mut Vec<Predicate<'tcx>>,
|
||||||
|
fn_def_id: DefId,
|
||||||
|
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
|
||||||
|
seen: FxHashSet<DefId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
|
||||||
|
fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow<Self::BreakTy> {
|
||||||
|
if let ty::Alias(ty::Projection, alias_ty) = *ty.kind()
|
||||||
|
&& self.tcx.def_kind(alias_ty.def_id) == DefKind::ImplTraitPlaceholder
|
||||||
|
&& self.tcx.impl_trait_in_trait_parent(alias_ty.def_id) == self.fn_def_id
|
||||||
|
&& self.seen.insert(alias_ty.def_id)
|
||||||
|
{
|
||||||
|
self.predicates.push(
|
||||||
|
ty::Binder::bind_with_vars(
|
||||||
|
ty::ProjectionPredicate {
|
||||||
|
projection_ty: alias_ty,
|
||||||
|
term: self.tcx.mk_alias(ty::Opaque, alias_ty).into(),
|
||||||
|
},
|
||||||
|
self.bound_vars,
|
||||||
|
)
|
||||||
|
.to_predicate(self.tcx),
|
||||||
|
);
|
||||||
|
|
||||||
|
for bound in self.tcx.item_bounds(alias_ty.def_id).subst_iter(self.tcx, alias_ty.substs)
|
||||||
|
{
|
||||||
|
bound.visit_with(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ty.super_visit_with(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Elaborate the environment.
|
/// Elaborate the environment.
|
||||||
///
|
///
|
||||||
/// Collect a list of `Predicate`'s used for building the `ParamEnv`. Adds `TypeWellFormedFromEnv`'s
|
/// Collect a list of `Predicate`'s used for building the `ParamEnv`. Adds `TypeWellFormedFromEnv`'s
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue