Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

explicitly handle auto trait leakage in coherence #116689

Merged
merged 1 commit into from
Oct 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading