about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs13
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs9
-rw-r--r--tests/ui/traits/non_lifetime_binders/bad-sized-cond.rs23
-rw-r--r--tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr62
5 files changed, 103 insertions, 9 deletions
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index 2b33d31994f..b736a416e4a 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -418,10 +418,15 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
                 bug!("encountered a fresh type during canonicalization")
             }
 
-            ty::Placeholder(placeholder) => self.canonicalize_ty_var(
-                CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderTy(placeholder) },
-                t,
-            ),
+            ty::Placeholder(mut placeholder) => {
+                if !self.canonicalize_mode.preserve_universes() {
+                    placeholder.universe = ty::UniverseIndex::ROOT;
+                }
+                self.canonicalize_ty_var(
+                    CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderTy(placeholder) },
+                    t,
+                )
+            }
 
             ty::Bound(debruijn, _) => {
                 if debruijn >= self.binder_index {
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 1e59983583b..a101127104d 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -735,7 +735,10 @@ pub trait PrettyPrinter<'tcx>:
                     p!(print(data))
                 }
             }
-            ty::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)),
+            ty::Placeholder(placeholder) => match placeholder.name {
+                ty::BoundTyKind::Anon(_) => p!(write("Placeholder({:?})", placeholder)),
+                ty::BoundTyKind::Param(_, name) => p!(write("{}", name)),
+            },
             ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
                 // We use verbose printing in 'NO_QUERIES' mode, to
                 // avoid needing to call `predicates_of`. This should
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index e6fc9bb9239..4b15dd408b3 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -2148,12 +2148,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 }))
             }
 
-            ty::Alias(..) | ty::Param(_) => None,
+            ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => None,
             ty::Infer(ty::TyVar(_)) => Ambiguous,
 
-            ty::Placeholder(..)
-            | ty::Bound(..)
-            | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
+            // We can make this an ICE if/once we actually instantiate the trait obligation.
+            ty::Bound(..) => None,
+
+            ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
                 bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty);
             }
         }
diff --git a/tests/ui/traits/non_lifetime_binders/bad-sized-cond.rs b/tests/ui/traits/non_lifetime_binders/bad-sized-cond.rs
new file mode 100644
index 00000000000..dfc800c8e7e
--- /dev/null
+++ b/tests/ui/traits/non_lifetime_binders/bad-sized-cond.rs
@@ -0,0 +1,23 @@
+#![feature(non_lifetime_binders)]
+//~^ WARN is incomplete and may not be safe
+
+pub fn foo()
+where
+    for<V> V: Sized,
+{
+}
+
+pub fn bar()
+where
+    for<V> V: IntoIterator,
+{
+}
+
+fn main() {
+    foo();
+    //~^ ERROR the size for values of type `V` cannot be known at compilation time
+
+    bar();
+    //~^ ERROR the size for values of type `V` cannot be known at compilation time
+    //~| ERROR `V` is not an iterator
+}
diff --git a/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr b/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr
new file mode 100644
index 00000000000..6480e490e8b
--- /dev/null
+++ b/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr
@@ -0,0 +1,62 @@
+warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/bad-sized-cond.rs:1:12
+   |
+LL | #![feature(non_lifetime_binders)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: the size for values of type `V` cannot be known at compilation time
+  --> $DIR/bad-sized-cond.rs:17:5
+   |
+LL |     foo();
+   |     ^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `V`
+note: required by a bound in `foo`
+  --> $DIR/bad-sized-cond.rs:6:15
+   |
+LL | pub fn foo()
+   |        --- required by a bound in this
+LL | where
+LL |     for<V> V: Sized,
+   |               ^^^^^ required by this bound in `foo`
+
+error[E0277]: the size for values of type `V` cannot be known at compilation time
+  --> $DIR/bad-sized-cond.rs:20:5
+   |
+LL |     bar();
+   |     ^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `V`
+   = note: required for `V` to implement `IntoIterator`
+note: required by a bound in `bar`
+  --> $DIR/bad-sized-cond.rs:12:15
+   |
+LL | pub fn bar()
+   |        --- required by a bound in this
+LL | where
+LL |     for<V> V: IntoIterator,
+   |               ^^^^^^^^^^^^ required by this bound in `bar`
+
+error[E0277]: `V` is not an iterator
+  --> $DIR/bad-sized-cond.rs:20:5
+   |
+LL |     bar();
+   |     ^^^ `V` is not an iterator
+   |
+   = help: the trait `Iterator` is not implemented for `V`
+   = note: required for `V` to implement `IntoIterator`
+note: required by a bound in `bar`
+  --> $DIR/bad-sized-cond.rs:12:15
+   |
+LL | pub fn bar()
+   |        --- required by a bound in this
+LL | where
+LL |     for<V> V: IntoIterator,
+   |               ^^^^^^^^^^^^ required by this bound in `bar`
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.