about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeón Orell Valerian Liehr <me@fmease.dev>2023-12-31 18:23:23 +0100
committerLeón Orell Valerian Liehr <me@fmease.dev>2024-01-01 14:02:42 +0100
commit01ac44a664f575f209d2f507b38b6497162bc6e2 (patch)
treeb89221ce10211e6b7de7277ac50e18c9b5e77247
parentfcfe05aa7538fbb18fc3baff9aabdf9a1cd14b1e (diff)
downloadrust-01ac44a664f575f209d2f507b38b6497162bc6e2.tar.gz
rust-01ac44a664f575f209d2f507b38b6497162bc6e2.zip
Pretty-print always-const trait predicates correctly
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs33
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr4
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs33
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr37
5 files changed, 94 insertions, 15 deletions
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 99384e34222..ebbd02e01bf 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 76bc738123d..8d6176a5bac 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: ~const Foo>(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 aea9a39b261..3581b1fcd7d 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 00000000000..62a7b312378
--- /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<T: const Trait>() {}
+
+#[const_trait]
+trait Trait {
+    fn make() -> u32;
+}
+
+struct Ty;
+
+impl Trait for Ty {
+    fn make() -> u32 { 0 }
+}
+
+fn main() {
+    require::<Ty>(); //~ ERROR the trait bound `Ty: const Trait` is not satisfied
+}
+
+struct Container<const N: u32>;
+
+// FIXME(effects): Somehow emit `the trait bound `T: const Trait` is not satisfied` here instead
+//                 and suggest changing `Trait` to `const Trait`.
+fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
+//~^ ERROR mismatched types
+
+// FIXME(effects): Instead of suggesting `+ const Trait`, suggest
+//                 changing `~const Trait` to `const Trait`.
+const fn accept1<T: ~const Trait>(_: 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 00000000000..2fb4fc1aa2b
--- /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<T: Trait>(_: 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<T: ~const Trait>(_: Container<{ T::make() }>) {}
+   |                                                  ^ the trait `const Trait` is not implemented for `T`
+   |
+help: consider further restricting this bound
+   |
+LL | const fn accept1<T: ~const Trait + const Trait>(_: Container<{ T::make() }>) {}
+   |                                  +++++++++++++
+
+error[E0277]: the trait bound `Ty: const Trait` is not satisfied
+  --> $DIR/unsatisfied-const-trait-bound.rs:20:15
+   |
+LL |     require::<Ty>();
+   |               ^^ 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<T: const Trait>() {}
+   |               ^^^^^^^^^^^ 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`.