Skip to content

Commit

Permalink
Rollup merge of rust-lang#116689 - lcnr:auto-trait-hidden-ty-leak, r=…
Browse files Browse the repository at this point in the history
…compiler-errors

explicitly handle auto trait leakage in coherence

does not impact behavior but may avoid weird bugs in the future, cc rust-lang/trait-system-refactor-initiative#65

r? ``@compiler-errors``
  • Loading branch information
matthiaskrgr authored Oct 14, 2023
2 parents 30b2cc0 + 1bc6ae4 commit 45bcef3
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 17 deletions.
5 changes: 3 additions & 2 deletions compiler/rustc_trait_selection/src/solve/trait_goals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down
12 changes: 12 additions & 0 deletions tests/ui/impl-trait/auto-trait-coherence.old.stderr
Original file line number Diff line number Diff line change
@@ -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`.
Original file line number Diff line number Diff line change
@@ -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)]
Expand Down

0 comments on commit 45bcef3

Please sign in to comment.