explicitly handle auto trait leakage in coherence
This commit is contained in:
parent
2763ca50da
commit
1bc6ae4401
5 changed files with 38 additions and 17 deletions
|
@ -136,12 +136,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
|||
// `assemble_candidates_after_normalizing_self_ty`, and we'd
|
||||
// just be registering an identical candidate here.
|
||||
//
|
||||
// Returning `Err(NoSolution)` here is ok in `SolverMode::Coherence`
|
||||
// since we'll always be registering an ambiguous candidate in
|
||||
// We always return `Err(NoSolution)` here in `SolverMode::Coherence`
|
||||
// since we'll always register an ambiguous candidate in
|
||||
// `assemble_candidates_after_normalizing_self_ty` due to normalizing
|
||||
// the TAIT.
|
||||
if let ty::Alias(ty::Opaque, opaque_ty) = goal.predicate.self_ty().kind() {
|
||||
if matches!(goal.param_env.reveal(), Reveal::All)
|
||||
|| matches!(ecx.solver_mode(), SolverMode::Coherence)
|
||||
|| opaque_ty
|
||||
.def_id
|
||||
.as_local()
|
||||
|
|
|
@ -492,7 +492,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
// this trait and type.
|
||||
}
|
||||
ty::Param(..)
|
||||
| ty::Alias(ty::Projection | ty::Inherent, ..)
|
||||
| ty::Alias(ty::Projection | ty::Inherent | ty::Weak, ..)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Bound(..) => {
|
||||
// In these cases, we don't know what the actual
|
||||
|
@ -536,20 +536,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
);
|
||||
}
|
||||
|
||||
ty::Alias(_, _)
|
||||
if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(..))) =>
|
||||
{
|
||||
// We do not generate an auto impl candidate for `impl Trait`s which already
|
||||
// reference our auto trait.
|
||||
//
|
||||
// For example during candidate assembly for `impl Send: Send`, we don't have
|
||||
// to look at the constituent types for this opaque types to figure out that this
|
||||
// trivially holds.
|
||||
//
|
||||
// Note that this is only sound as projection candidates of opaque types
|
||||
// are always applicable for auto traits.
|
||||
ty::Alias(ty::Opaque, _) => {
|
||||
if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(..))) {
|
||||
// We do not generate an auto impl candidate for `impl Trait`s which already
|
||||
// reference our auto trait.
|
||||
//
|
||||
// For example during candidate assembly for `impl Send: Send`, we don't have
|
||||
// to look at the constituent types for this opaque types to figure out that this
|
||||
// trivially holds.
|
||||
//
|
||||
// Note that this is only sound as projection candidates of opaque types
|
||||
// are always applicable for auto traits.
|
||||
} else if self.infcx.intercrate {
|
||||
// We do not emit auto trait candidates for opaque types in coherence.
|
||||
// Doing so can result in weird dependency cycles.
|
||||
candidates.ambiguous = true;
|
||||
} else {
|
||||
candidates.vec.push(AutoImplCandidate)
|
||||
}
|
||||
}
|
||||
ty::Alias(_, _) => candidates.vec.push(AutoImplCandidate),
|
||||
|
||||
ty::Bool
|
||||
| ty::Char
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue