From 01ac44a664f575f209d2f507b38b6497162bc6e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Sun, 31 Dec 2023 18:23:23 +0100 Subject: [PATCH] Pretty-print always-const trait predicates correctly --- compiler/rustc_middle/src/ty/print/pretty.rs | 33 +++++++++++------ .../call-generic-method-nonconst.rs | 2 +- .../call-generic-method-nonconst.stderr | 4 +- .../unsatisfied-const-trait-bound.rs | 33 +++++++++++++++++ .../unsatisfied-const-trait-bound.stderr | 37 +++++++++++++++++++ 5 files changed, 94 insertions(+), 15 deletions(-) create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 99384e34222d9..ebbd02e01bf33 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1697,6 +1697,25 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { }) } + fn pretty_print_bound_constness( + &mut self, + trait_ref: ty::TraitRef<'tcx>, + ) -> Result<(), PrintError> { + define_scoped_cx!(self); + + let Some(idx) = self.tcx().generics_of(trait_ref.def_id).host_effect_index else { + return Ok(()); + }; + let arg = trait_ref.args.const_at(idx); + + if arg == self.tcx().consts.false_ { + p!("const "); + } else if arg != self.tcx().consts.true_ && !arg.has_infer() { + p!("~const "); + } + Ok(()) + } + fn should_print_verbose(&self) -> bool { self.tcx().sess.verbose_internals() } @@ -2866,13 +2885,7 @@ define_print_and_forward_display! { } TraitPredPrintModifiersAndPath<'tcx> { - if let Some(idx) = cx.tcx().generics_of(self.0.trait_ref.def_id).host_effect_index - { - let arg = self.0.trait_ref.args.const_at(idx); - if arg != cx.tcx().consts.true_ && !arg.has_infer() { - p!("~const "); - } - } + p!(pretty_print_bound_constness(self.0.trait_ref)); if let ty::ImplPolarity::Negative = self.0.polarity { p!("!") } @@ -2905,11 +2918,7 @@ define_print_and_forward_display! { ty::TraitPredicate<'tcx> { p!(print(self.trait_ref.self_ty()), ": "); - if let Some(idx) = cx.tcx().generics_of(self.trait_ref.def_id).host_effect_index { - if self.trait_ref.args.const_at(idx) != cx.tcx().consts.true_ { - p!("~const "); - } - } + p!(pretty_print_bound_constness(self.trait_ref)); if let ty::ImplPolarity::Negative = self.polarity { p!("!"); } diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs index 76bc738123d39..8d6176a5bace4 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs @@ -21,6 +21,6 @@ const fn equals_self(t: &T) -> bool { // it not using the impl. pub const EQ: bool = equals_self(&S); -//~^ ERROR: the trait bound `S: ~const Foo` is not satisfied +//~^ ERROR: the trait bound `S: const Foo` is not satisfied fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr index aea9a39b26107..3581b1fcd7dfb 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `S: ~const Foo` is not satisfied +error[E0277]: the trait bound `S: const Foo` is not satisfied --> $DIR/call-generic-method-nonconst.rs:23:34 | LL | pub const EQ: bool = equals_self(&S); - | ----------- ^^ the trait `~const Foo` is not implemented for `S` + | ----------- ^^ the trait `const Foo` is not implemented for `S` | | | required by a bound introduced by this call | diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs new file mode 100644 index 0000000000000..62a7b31237842 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs @@ -0,0 +1,33 @@ +// Ensure that we print unsatisfied always-const trait bounds as `const Trait` in diagnostics. + +#![feature(const_trait_impl, effects, generic_const_exprs)] +#![allow(incomplete_features)] + +fn require() {} + +#[const_trait] +trait Trait { + fn make() -> u32; +} + +struct Ty; + +impl Trait for Ty { + fn make() -> u32 { 0 } +} + +fn main() { + require::(); //~ ERROR the trait bound `Ty: const Trait` is not satisfied +} + +struct Container; + +// FIXME(effects): Somehow emit `the trait bound `T: const Trait` is not satisfied` here instead +// and suggest changing `Trait` to `const Trait`. +fn accept0(_: Container<{ T::make() }>) {} +//~^ ERROR mismatched types + +// FIXME(effects): Instead of suggesting `+ const Trait`, suggest +// changing `~const Trait` to `const Trait`. +const fn accept1(_: Container<{ T::make() }>) {} +//~^ ERROR the trait bound `T: const Trait` is not satisfied diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr new file mode 100644 index 0000000000000..2fb4fc1aa2b8e --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr @@ -0,0 +1,37 @@ +error[E0308]: mismatched types + --> $DIR/unsatisfied-const-trait-bound.rs:27:37 + | +LL | fn accept0(_: Container<{ T::make() }>) {} + | ^^^^^^^^^ expected `false`, found `true` + | + = note: expected constant `false` + found constant `true` + +error[E0277]: the trait bound `T: const Trait` is not satisfied + --> $DIR/unsatisfied-const-trait-bound.rs:32:50 + | +LL | const fn accept1(_: Container<{ T::make() }>) {} + | ^ the trait `const Trait` is not implemented for `T` + | +help: consider further restricting this bound + | +LL | const fn accept1(_: Container<{ T::make() }>) {} + | +++++++++++++ + +error[E0277]: the trait bound `Ty: const Trait` is not satisfied + --> $DIR/unsatisfied-const-trait-bound.rs:20:15 + | +LL | require::(); + | ^^ the trait `const Trait` is not implemented for `Ty` + | + = help: the trait `Trait` is implemented for `Ty` +note: required by a bound in `require` + --> $DIR/unsatisfied-const-trait-bound.rs:6:15 + | +LL | fn require() {} + | ^^^^^^^^^^^ required by this bound in `require` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`.