Skip to content

Commit

Permalink
Rollup merge of rust-lang#119476 - fmease:pp-always-const-trait-preds…
Browse files Browse the repository at this point in the history
…, r=compiler-errors

Pretty-print always-const trait predicates correctly

Follow-up to rust-lang#119099.

r? fee1-dead
  • Loading branch information
fmease authored Jan 3, 2024
2 parents f281ad9 + 01ac44a commit e8e5a7e
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 15 deletions.
33 changes: 21 additions & 12 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down Expand Up @@ -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!("!")
}
Expand Down Expand Up @@ -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!("!");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
Original file line number Diff line number Diff line change
@@ -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
|
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit e8e5a7e

Please sign in to comment.