about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustc_typeck/check/mod.rs10
-rw-r--r--src/test/ui/type-alias-impl-trait/assoc-type-const.rs36
-rw-r--r--src/test/ui/type-alias-impl-trait/assoc-type-const.stderr8
-rw-r--r--src/test/ui/type-alias-impl-trait/assoc-type-lifetime.rs28
4 files changed, 81 insertions, 1 deletions
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index a6dc4fc851f..a1f1ac3f2d3 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -907,7 +907,15 @@ fn fixup_opaque_types<'tcx, T>(tcx: TyCtxt<'tcx>, val: &T) -> T where T: TypeFol
                                 },
                                 GenericArgKind::Const(old_const) => {
                                     if let ConstValue::Infer(_) = old_const.val {
-                                        self.tcx.mk_param_from_def(param)
+                        // This should never happen - we currently do not support
+                        // 'const projections', e.g.:
+                        // `impl<T: SomeTrait> MyTrait for T where <T as SomeTrait>::MyConst == 25`
+                        // which should be the only way for us to end up with a const inference
+                        // variable after projection. If Rust ever gains support for this kind
+                        // of projection, this should *probably* be changed to
+                        // `self.tcx.mk_param_from_def(param)`
+                                        bug!("Found infer const: `{:?}` in opaque type: {:?}",
+                                             old_const, ty);
                                     } else {
                                         old_param.fold_with(self)
                                     }
diff --git a/src/test/ui/type-alias-impl-trait/assoc-type-const.rs b/src/test/ui/type-alias-impl-trait/assoc-type-const.rs
new file mode 100644
index 00000000000..5db677d82e2
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/assoc-type-const.rs
@@ -0,0 +1,36 @@
+// Tests that we properly detect defining usages when using
+// const generics in an associated opaque type
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+trait UnwrapItemsExt<const C: usize> {
+    type Iter;
+    fn unwrap_items(self) -> Self::Iter;
+}
+
+struct MyStruct<const C: usize> {}
+
+trait MyTrait<'a, const C: usize> {
+    type MyItem;
+    const MY_CONST: usize;
+}
+
+impl<'a, const C: usize> MyTrait<'a, {C}> for MyStruct<{C}> {
+    type MyItem = u8;
+    const MY_CONST: usize = C;
+}
+
+impl<'a, I, const C: usize> UnwrapItemsExt<{C}> for I
+where
+{
+    type Iter = impl MyTrait<'a, {C}>;
+
+    fn unwrap_items(self) -> Self::Iter {
+        MyStruct::<{C}> {}
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/assoc-type-const.stderr b/src/test/ui/type-alias-impl-trait/assoc-type-const.stderr
new file mode 100644
index 00000000000..0adbee2f244
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/assoc-type-const.stderr
@@ -0,0 +1,8 @@
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+  --> $DIR/assoc-type-const.rs:6:12
+   |
+LL | #![feature(const_generics)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
diff --git a/src/test/ui/type-alias-impl-trait/assoc-type-lifetime.rs b/src/test/ui/type-alias-impl-trait/assoc-type-lifetime.rs
new file mode 100644
index 00000000000..cff1d24494e
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/assoc-type-lifetime.rs
@@ -0,0 +1,28 @@
+// Tests that we still detect defining usages when
+// lifetimes are used in an associated opaque type
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+trait UnwrapItemsExt {
+    type Iter;
+    fn unwrap_items(self) -> Self::Iter;
+}
+
+struct MyStruct {}
+
+trait MyTrait<'a> {}
+
+impl<'a> MyTrait<'a> for MyStruct {}
+
+impl<'a, I> UnwrapItemsExt for I
+where
+{
+    type Iter = impl MyTrait<'a>;
+
+    fn unwrap_items(self) -> Self::Iter {
+        MyStruct {}
+    }
+}
+
+fn main() {}