diff options
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/project.rs | 7 | ||||
| -rw-r--r-- | src/test/ui/associated-types/associated-types-projection-bound-ambiguity.rs | 16 |
2 files changed, 23 insertions, 0 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 8f7513cf27c..c33c8a67aa8 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -977,6 +977,13 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>( if is_match { candidate_set.push_candidate(ctor(data)); + + if potentially_unnormalized_candidates && !obligation.predicate.needs_infer() { + // HACK: Pick the first trait def candidate for a fully + // inferred predicate. This is to allow duplicates that + // differ only in normalization. + return; + } } } } diff --git a/src/test/ui/associated-types/associated-types-projection-bound-ambiguity.rs b/src/test/ui/associated-types/associated-types-projection-bound-ambiguity.rs new file mode 100644 index 00000000000..353f82e7c6e --- /dev/null +++ b/src/test/ui/associated-types/associated-types-projection-bound-ambiguity.rs @@ -0,0 +1,16 @@ +// Check that if we have multiple applicable projection bounds we pick one (for +// backwards compatibility reasons). + +// check-pass +use std::ops::Mul; + +trait A { + type V; + type U: Mul<Self::V, Output = ()> + Mul<(), Output = ()>; +} + +fn g<T: A<V = ()>>() { + let y: <T::U as Mul<()>>::Output = (); +} + +fn main() {} |
