Skip to content

Commit

Permalink
Rollup merge of #116689 - lcnr:auto-trait-hidden-ty-leak, r=compiler-…
Browse files Browse the repository at this point in the history
…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 e06f348 + 1bc6ae4 commit b8571ab
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 b8571ab

Please sign in to comment.