From f4a4a3147955ceb359204d85a74e15ee9d98046b Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 17 Feb 2023 21:01:22 +0000 Subject: [PATCH 1/3] Don't ICE on bound types in sized conditions --- .../src/traits/select/mod.rs | 9 +++--- .../non_lifetime_binders/bad-sized-cond.rs | 13 +++++++++ .../bad-sized-cond.stderr | 28 +++++++++++++++++++ 3 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 tests/ui/traits/non_lifetime_binders/bad-sized-cond.rs create mode 100644 tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr 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..1612de7fc45 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/bad-sized-cond.rs @@ -0,0 +1,13 @@ +#![feature(non_lifetime_binders)] +//~^ WARN is incomplete and may not be safe + +pub fn foo() +where + for V: Sized, +{ +} + +fn main() { + foo(); + //~^ ERROR the size for values of type `V` cannot be known at compilation time +} 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..eeb3baf010f --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr @@ -0,0 +1,28 @@ +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 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:11: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: Sized, + | ^^^^^ required by this bound in `foo` + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0277`. From ec40b1a3938ea0f7ae27b4bffe62bd41dc8015af Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 17 Feb 2023 21:15:18 +0000 Subject: [PATCH 2/3] Collapse placeholders to root universe in canonicalizer if not preserving universes --- .../src/infer/canonical/canonicalizer.rs | 13 +++++-- .../non_lifetime_binders/bad-sized-cond.rs | 8 ++++ .../bad-sized-cond.stderr | 38 ++++++++++++++++++- 3 files changed, 53 insertions(+), 6 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> 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/tests/ui/traits/non_lifetime_binders/bad-sized-cond.rs b/tests/ui/traits/non_lifetime_binders/bad-sized-cond.rs index 1612de7fc45..3128e0f3138 100644 --- a/tests/ui/traits/non_lifetime_binders/bad-sized-cond.rs +++ b/tests/ui/traits/non_lifetime_binders/bad-sized-cond.rs @@ -7,7 +7,15 @@ where { } +pub fn bar() +where + for V: IntoIterator, +{ +} + fn main() { foo(); //~^ ERROR the size for values of type `V` cannot be known at compilation time + + bar(); } diff --git a/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr b/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr index eeb3baf010f..3af115d897d 100644 --- a/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr +++ b/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr @@ -8,7 +8,7 @@ LL | #![feature(non_lifetime_binders)] = 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:11:5 + --> $DIR/bad-sized-cond.rs:17:5 | LL | foo(); | ^^^ doesn't have a size known at compile-time @@ -23,6 +23,40 @@ LL | where LL | for V: Sized, | ^^^^^ required by this bound in `foo` -error: aborting due to previous error; 1 warning emitted +error[E0277]: the size for values of type `Placeholder(Placeholder { universe: U3, name: Param(DefId(0:6 ~ bad_sized_cond[9450]::bar::V), "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 `Placeholder(Placeholder { universe: U3, name: Param(DefId(0:6 ~ bad_sized_cond[9450]::bar::V), "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: IntoIterator, + | ^^^^^^^^^^^^ required by this bound in `bar` + +error[E0277]: `Placeholder(Placeholder { universe: U3, name: Param(DefId(0:6 ~ bad_sized_cond[9450]::bar::V), "V") })` is not an iterator + --> $DIR/bad-sized-cond.rs:20:5 + | +LL | bar(); + | ^^^ `Placeholder(Placeholder { universe: U3, name: Param(DefId(0:6 ~ bad_sized_cond[9450]::bar::V), "V") })` is not an iterator + | + = help: the trait `Iterator` is not implemented for `Placeholder(Placeholder { universe: U3, name: Param(DefId(0:6 ~ bad_sized_cond[9450]::bar::V), "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: 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`. From 6f3706ea71a89a431acf7f84573b87c2ac98b0c7 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 17 Feb 2023 21:21:27 +0000 Subject: [PATCH 3/3] Pretty placeholders using their names --- compiler/rustc_middle/src/ty/print/pretty.rs | 5 ++++- tests/ui/traits/non_lifetime_binders/bad-sized-cond.rs | 2 ++ .../traits/non_lifetime_binders/bad-sized-cond.stderr | 10 +++++----- 3 files changed, 11 insertions(+), 6 deletions(-) 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/tests/ui/traits/non_lifetime_binders/bad-sized-cond.rs b/tests/ui/traits/non_lifetime_binders/bad-sized-cond.rs index 3128e0f3138..dfc800c8e7e 100644 --- a/tests/ui/traits/non_lifetime_binders/bad-sized-cond.rs +++ b/tests/ui/traits/non_lifetime_binders/bad-sized-cond.rs @@ -18,4 +18,6 @@ fn main() { //~^ 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 index 3af115d897d..6480e490e8b 100644 --- a/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr +++ b/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr @@ -23,13 +23,13 @@ LL | where LL | for V: Sized, | ^^^^^ required by this bound in `foo` -error[E0277]: the size for values of type `Placeholder(Placeholder { universe: U3, name: Param(DefId(0:6 ~ bad_sized_cond[9450]::bar::V), "V") })` cannot be known at compilation time +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 `Placeholder(Placeholder { universe: U3, name: Param(DefId(0:6 ~ bad_sized_cond[9450]::bar::V), "V") })` + = 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 @@ -40,13 +40,13 @@ LL | where LL | for V: IntoIterator, | ^^^^^^^^^^^^ required by this bound in `bar` -error[E0277]: `Placeholder(Placeholder { universe: U3, name: Param(DefId(0:6 ~ bad_sized_cond[9450]::bar::V), "V") })` is not an iterator +error[E0277]: `V` is not an iterator --> $DIR/bad-sized-cond.rs:20:5 | LL | bar(); - | ^^^ `Placeholder(Placeholder { universe: U3, name: Param(DefId(0:6 ~ bad_sized_cond[9450]::bar::V), "V") })` is not an iterator + | ^^^ `V` is not an iterator | - = help: the trait `Iterator` is not implemented for `Placeholder(Placeholder { universe: U3, name: Param(DefId(0:6 ~ bad_sized_cond[9450]::bar::V), "V") })` + = 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