Skip to content

Commit 45bcef3

Browse files
authored
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 rust-lang/trait-system-refactor-initiative#65 r? ``@compiler-errors``
2 parents 30b2cc0 + 1bc6ae4 commit 45bcef3

File tree

5 files changed

+38
-17
lines changed

5 files changed

+38
-17
lines changed

compiler/rustc_trait_selection/src/solve/trait_goals.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
136136
// `assemble_candidates_after_normalizing_self_ty`, and we'd
137137
// just be registering an identical candidate here.
138138
//
139-
// Returning `Err(NoSolution)` here is ok in `SolverMode::Coherence`
140-
// since we'll always be registering an ambiguous candidate in
139+
// We always return `Err(NoSolution)` here in `SolverMode::Coherence`
140+
// since we'll always register an ambiguous candidate in
141141
// `assemble_candidates_after_normalizing_self_ty` due to normalizing
142142
// the TAIT.
143143
if let ty::Alias(ty::Opaque, opaque_ty) = goal.predicate.self_ty().kind() {
144144
if matches!(goal.param_env.reveal(), Reveal::All)
145+
|| matches!(ecx.solver_mode(), SolverMode::Coherence)
145146
|| opaque_ty
146147
.def_id
147148
.as_local()

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

+19-14
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
492492
// this trait and type.
493493
}
494494
ty::Param(..)
495-
| ty::Alias(ty::Projection | ty::Inherent, ..)
495+
| ty::Alias(ty::Projection | ty::Inherent | ty::Weak, ..)
496496
| ty::Placeholder(..)
497497
| ty::Bound(..) => {
498498
// In these cases, we don't know what the actual
@@ -536,20 +536,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
536536
);
537537
}
538538

539-
ty::Alias(_, _)
540-
if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(..))) =>
541-
{
542-
// We do not generate an auto impl candidate for `impl Trait`s which already
543-
// reference our auto trait.
544-
//
545-
// For example during candidate assembly for `impl Send: Send`, we don't have
546-
// to look at the constituent types for this opaque types to figure out that this
547-
// trivially holds.
548-
//
549-
// Note that this is only sound as projection candidates of opaque types
550-
// are always applicable for auto traits.
539+
ty::Alias(ty::Opaque, _) => {
540+
if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(..))) {
541+
// We do not generate an auto impl candidate for `impl Trait`s which already
542+
// reference our auto trait.
543+
//
544+
// For example during candidate assembly for `impl Send: Send`, we don't have
545+
// to look at the constituent types for this opaque types to figure out that this
546+
// trivially holds.
547+
//
548+
// Note that this is only sound as projection candidates of opaque types
549+
// are always applicable for auto traits.
550+
} else if self.infcx.intercrate {
551+
// We do not emit auto trait candidates for opaque types in coherence.
552+
// Doing so can result in weird dependency cycles.
553+
candidates.ambiguous = true;
554+
} else {
555+
candidates.vec.push(AutoImplCandidate)
556+
}
551557
}
552-
ty::Alias(_, _) => candidates.vec.push(AutoImplCandidate),
553558

554559
ty::Bool
555560
| ty::Char

tests/ui/impl-trait/auto-trait.stderr renamed to tests/ui/impl-trait/auto-trait-coherence.next.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
2-
--> $DIR/auto-trait.rs:21:1
2+
--> $DIR/auto-trait-coherence.rs:24:1
33
|
44
LL | impl<T: Send> AnotherTrait for T {}
55
| -------------------------------- first implementation here
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
2+
--> $DIR/auto-trait-coherence.rs:24:1
3+
|
4+
LL | impl<T: Send> AnotherTrait for T {}
5+
| -------------------------------- first implementation here
6+
...
7+
LL | impl AnotherTrait for D<OpaqueType> {
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0119`.

tests/ui/impl-trait/auto-trait.rs renamed to tests/ui/impl-trait/auto-trait-coherence.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// revisions: old next
2+
//[next] compile-flags: -Ztrait-solver=next
3+
14
// Tests that type alias impls traits do not leak auto-traits for
25
// the purposes of coherence checking
36
#![feature(type_alias_impl_trait)]

0 commit comments

Comments
 (0)