Skip to content

Commit b41b169

Browse files
authored
Rollup merge of rust-lang#119476 - fmease:pp-always-const-trait-preds, r=compiler-errors
Pretty-print always-const trait predicates correctly Follow-up to rust-lang#119099. r? fee1-dead
2 parents 699a70b + 01ac44a commit b41b169

File tree

5 files changed

+94
-15
lines changed

5 files changed

+94
-15
lines changed

compiler/rustc_middle/src/ty/print/pretty.rs

+21-12
Original file line numberDiff line numberDiff line change
@@ -1697,6 +1697,25 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
16971697
})
16981698
}
16991699

1700+
fn pretty_print_bound_constness(
1701+
&mut self,
1702+
trait_ref: ty::TraitRef<'tcx>,
1703+
) -> Result<(), PrintError> {
1704+
define_scoped_cx!(self);
1705+
1706+
let Some(idx) = self.tcx().generics_of(trait_ref.def_id).host_effect_index else {
1707+
return Ok(());
1708+
};
1709+
let arg = trait_ref.args.const_at(idx);
1710+
1711+
if arg == self.tcx().consts.false_ {
1712+
p!("const ");
1713+
} else if arg != self.tcx().consts.true_ && !arg.has_infer() {
1714+
p!("~const ");
1715+
}
1716+
Ok(())
1717+
}
1718+
17001719
fn should_print_verbose(&self) -> bool {
17011720
self.tcx().sess.verbose_internals()
17021721
}
@@ -2866,13 +2885,7 @@ define_print_and_forward_display! {
28662885
}
28672886

28682887
TraitPredPrintModifiersAndPath<'tcx> {
2869-
if let Some(idx) = cx.tcx().generics_of(self.0.trait_ref.def_id).host_effect_index
2870-
{
2871-
let arg = self.0.trait_ref.args.const_at(idx);
2872-
if arg != cx.tcx().consts.true_ && !arg.has_infer() {
2873-
p!("~const ");
2874-
}
2875-
}
2888+
p!(pretty_print_bound_constness(self.0.trait_ref));
28762889
if let ty::ImplPolarity::Negative = self.0.polarity {
28772890
p!("!")
28782891
}
@@ -2905,11 +2918,7 @@ define_print_and_forward_display! {
29052918

29062919
ty::TraitPredicate<'tcx> {
29072920
p!(print(self.trait_ref.self_ty()), ": ");
2908-
if let Some(idx) = cx.tcx().generics_of(self.trait_ref.def_id).host_effect_index {
2909-
if self.trait_ref.args.const_at(idx) != cx.tcx().consts.true_ {
2910-
p!("~const ");
2911-
}
2912-
}
2921+
p!(pretty_print_bound_constness(self.trait_ref));
29132922
if let ty::ImplPolarity::Negative = self.polarity {
29142923
p!("!");
29152924
}

tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ const fn equals_self<T: ~const Foo>(t: &T) -> bool {
2121
// it not using the impl.
2222

2323
pub const EQ: bool = equals_self(&S);
24-
//~^ ERROR: the trait bound `S: ~const Foo` is not satisfied
24+
//~^ ERROR: the trait bound `S: const Foo` is not satisfied
2525

2626
fn main() {}

tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0277]: the trait bound `S: ~const Foo` is not satisfied
1+
error[E0277]: the trait bound `S: const Foo` is not satisfied
22
--> $DIR/call-generic-method-nonconst.rs:23:34
33
|
44
LL | pub const EQ: bool = equals_self(&S);
5-
| ----------- ^^ the trait `~const Foo` is not implemented for `S`
5+
| ----------- ^^ the trait `const Foo` is not implemented for `S`
66
| |
77
| required by a bound introduced by this call
88
|
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Ensure that we print unsatisfied always-const trait bounds as `const Trait` in diagnostics.
2+
3+
#![feature(const_trait_impl, effects, generic_const_exprs)]
4+
#![allow(incomplete_features)]
5+
6+
fn require<T: const Trait>() {}
7+
8+
#[const_trait]
9+
trait Trait {
10+
fn make() -> u32;
11+
}
12+
13+
struct Ty;
14+
15+
impl Trait for Ty {
16+
fn make() -> u32 { 0 }
17+
}
18+
19+
fn main() {
20+
require::<Ty>(); //~ ERROR the trait bound `Ty: const Trait` is not satisfied
21+
}
22+
23+
struct Container<const N: u32>;
24+
25+
// FIXME(effects): Somehow emit `the trait bound `T: const Trait` is not satisfied` here instead
26+
// and suggest changing `Trait` to `const Trait`.
27+
fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
28+
//~^ ERROR mismatched types
29+
30+
// FIXME(effects): Instead of suggesting `+ const Trait`, suggest
31+
// changing `~const Trait` to `const Trait`.
32+
const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
33+
//~^ ERROR the trait bound `T: const Trait` is not satisfied
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/unsatisfied-const-trait-bound.rs:27:37
3+
|
4+
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
5+
| ^^^^^^^^^ expected `false`, found `true`
6+
|
7+
= note: expected constant `false`
8+
found constant `true`
9+
10+
error[E0277]: the trait bound `T: const Trait` is not satisfied
11+
--> $DIR/unsatisfied-const-trait-bound.rs:32:50
12+
|
13+
LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
14+
| ^ the trait `const Trait` is not implemented for `T`
15+
|
16+
help: consider further restricting this bound
17+
|
18+
LL | const fn accept1<T: ~const Trait + const Trait>(_: Container<{ T::make() }>) {}
19+
| +++++++++++++
20+
21+
error[E0277]: the trait bound `Ty: const Trait` is not satisfied
22+
--> $DIR/unsatisfied-const-trait-bound.rs:20:15
23+
|
24+
LL | require::<Ty>();
25+
| ^^ the trait `const Trait` is not implemented for `Ty`
26+
|
27+
= help: the trait `Trait` is implemented for `Ty`
28+
note: required by a bound in `require`
29+
--> $DIR/unsatisfied-const-trait-bound.rs:6:15
30+
|
31+
LL | fn require<T: const Trait>() {}
32+
| ^^^^^^^^^^^ required by this bound in `require`
33+
34+
error: aborting due to 3 previous errors
35+
36+
Some errors have detailed explanations: E0277, E0308.
37+
For more information about an error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)