about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_mir_build/src/lints.rs4
-rw-r--r--tests/ui/traits/normalize-conflicting-impls.rs49
-rw-r--r--tests/ui/traits/normalize-conflicting-impls.stderr21
3 files changed, 73 insertions, 1 deletions
diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs
index 508936be29d..3f2b7c482a6 100644
--- a/compiler/rustc_mir_build/src/lints.rs
+++ b/compiler/rustc_mir_build/src/lints.rs
@@ -137,7 +137,9 @@ impl<'tcx> TerminatorClassifier<'tcx> for CallRecursion<'tcx> {
 
         let func_ty = func.ty(body, tcx);
         if let ty::FnDef(callee, args) = *func_ty.kind() {
-            let normalized_args = tcx.normalize_erasing_regions(param_env, args);
+            let Ok(normalized_args) = tcx.try_normalize_erasing_regions(param_env, args) else {
+                return false;
+            };
             let (callee, call_args) = if let Ok(Some(instance)) =
                 Instance::resolve(tcx, param_env, callee, normalized_args)
             {
diff --git a/tests/ui/traits/normalize-conflicting-impls.rs b/tests/ui/traits/normalize-conflicting-impls.rs
new file mode 100644
index 00000000000..454b2fd0153
--- /dev/null
+++ b/tests/ui/traits/normalize-conflicting-impls.rs
@@ -0,0 +1,49 @@
+fn problematic_function<Space>(material_surface_element: ())
+where
+    DefaultAllocator: FiniteElementAllocator<(), Space>,
+{
+    let _: Point2<f64> = material_surface_element.map_reference_coords().into();
+}
+
+impl<N, R> Allocator<N, R> for DefaultAllocator
+where
+    R::Value: DimName, //~ ERROR: `Value` not found for `R`
+{
+    type Buffer = ();
+}
+impl<N> Allocator<N, ()> for DefaultAllocator {}
+//~^ ERROR: conflicting implementations
+impl DimName for () {}
+impl DimName for u32 {}
+impl<N, D: DimName> From<VectorN<N, D>> for Point<N, D> {
+    fn from(_: VectorN<N, D>) -> Self {
+        todo!()
+    }
+}
+
+impl FiniteElement<u32> for () {}
+
+type VectorN<N, D> = Matrix<<DefaultAllocator as Allocator<N, D>>::Buffer>;
+
+type Point2<N> = Point<N, u32>;
+
+struct DefaultAllocator;
+struct Matrix<S>(S);
+struct Point<N, D>(N, D);
+
+trait Allocator<Scalar, R> {
+    type Buffer;
+}
+trait DimName {}
+trait FiniteElementAllocator<GeometryDim, NodalDim>:
+    Allocator<f64, ()> + Allocator<f64, NodalDim>
+{
+}
+
+trait FiniteElement<GeometryDim> {
+    fn map_reference_coords(&self) -> VectorN<f64, GeometryDim> {
+        todo!()
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/normalize-conflicting-impls.stderr b/tests/ui/traits/normalize-conflicting-impls.stderr
new file mode 100644
index 00000000000..9a66fe00c3f
--- /dev/null
+++ b/tests/ui/traits/normalize-conflicting-impls.stderr
@@ -0,0 +1,21 @@
+error[E0220]: associated type `Value` not found for `R`
+  --> $DIR/normalize-conflicting-impls.rs:10:8
+   |
+LL |     R::Value: DimName,
+   |        ^^^^^ associated type `Value` not found
+
+error[E0119]: conflicting implementations of trait `Allocator<_, ()>` for type `DefaultAllocator`
+  --> $DIR/normalize-conflicting-impls.rs:14:1
+   |
+LL | / impl<N, R> Allocator<N, R> for DefaultAllocator
+LL | | where
+LL | |     R::Value: DimName,
+   | |______________________- first implementation here
+...
+LL |   impl<N> Allocator<N, ()> for DefaultAllocator {}
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `DefaultAllocator`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0119, E0220.
+For more information about an error, try `rustc --explain E0119`.