mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Rollup merge of #116689 - lcnr:auto-trait-hidden-ty-leak, r=compiler-errors
explicitly handle auto trait leakage in coherence does not impact behavior but may avoid weird bugs in the future, cc https://github.com/rust-lang/trait-system-refactor-initiative/issues/65 r? ``@compiler-errors``
This commit is contained in:
commit
45bcef3cd5
@ -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
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
|
||||
--> $DIR/auto-trait.rs:21:1
|
||||
--> $DIR/auto-trait-coherence.rs:24:1
|
||||
|
|
||||
LL | impl<T: Send> AnotherTrait for T {}
|
||||
| -------------------------------- first implementation here
|
12
tests/ui/impl-trait/auto-trait-coherence.old.stderr
Normal file
12
tests/ui/impl-trait/auto-trait-coherence.old.stderr
Normal file
@ -0,0 +1,12 @@
|
||||
error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
|
||||
--> $DIR/auto-trait-coherence.rs:24:1
|
||||
|
|
||||
LL | impl<T: Send> AnotherTrait for T {}
|
||||
| -------------------------------- first implementation here
|
||||
...
|
||||
LL | impl AnotherTrait for D<OpaqueType> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0119`.
|
@ -1,3 +1,6 @@
|
||||
// revisions: old next
|
||||
//[next] compile-flags: -Ztrait-solver=next
|
||||
|
||||
// Tests that type alias impls traits do not leak auto-traits for
|
||||
// the purposes of coherence checking
|
||||
#![feature(type_alias_impl_trait)]
|
Loading…
Reference in New Issue
Block a user