Skip to content

Commit b38f7ad

Browse files
authored
Rollup merge of #131152 - fee1-dead-contrib:fxdiag, r=compiler-errors
Improve const traits diagnostics for new desugaring r? project-const-traits
2 parents 06d5218 + 7f6150b commit b38f7ad

24 files changed

+224
-168
lines changed

compiler/rustc_middle/src/macros.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ macro_rules! TrivialLiftImpls {
6767
};
6868
}
6969

70-
/// Used for types that are `Copy` and which **do not care arena
70+
/// Used for types that are `Copy` and which **do not care about arena
7171
/// allocated data** (i.e., don't need to be folded).
7272
#[macro_export]
7373
macro_rules! TrivialTypeTraversalImpls {

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

+34-12
Original file line numberDiff line numberDiff line change
@@ -1951,19 +1951,18 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
19511951

19521952
fn pretty_print_bound_constness(
19531953
&mut self,
1954-
trait_ref: ty::TraitRef<'tcx>,
1954+
constness: ty::BoundConstness,
19551955
) -> Result<(), PrintError> {
19561956
define_scoped_cx!(self);
19571957

1958-
let Some(idx) = self.tcx().generics_of(trait_ref.def_id).host_effect_index else {
1959-
return Ok(());
1960-
};
1961-
let arg = trait_ref.args.const_at(idx);
1962-
1963-
if arg == self.tcx().consts.false_ {
1964-
p!("const ");
1965-
} else if arg != self.tcx().consts.true_ && !arg.has_infer() {
1966-
p!("~const ");
1958+
match constness {
1959+
ty::BoundConstness::NotConst => {}
1960+
ty::BoundConstness::Const => {
1961+
p!("const ");
1962+
}
1963+
ty::BoundConstness::ConstIfConst => {
1964+
p!("~const ");
1965+
}
19671966
}
19681967
Ok(())
19691968
}
@@ -2948,13 +2947,29 @@ impl<'tcx> ty::TraitPredicate<'tcx> {
29482947
}
29492948
}
29502949

2950+
#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift)]
2951+
pub struct TraitPredPrintWithBoundConstness<'tcx>(ty::TraitPredicate<'tcx>, ty::BoundConstness);
2952+
2953+
impl<'tcx> fmt::Debug for TraitPredPrintWithBoundConstness<'tcx> {
2954+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2955+
fmt::Display::fmt(self, f)
2956+
}
2957+
}
2958+
29512959
#[extension(pub trait PrintPolyTraitPredicateExt<'tcx>)]
29522960
impl<'tcx> ty::PolyTraitPredicate<'tcx> {
29532961
fn print_modifiers_and_trait_path(
29542962
self,
29552963
) -> ty::Binder<'tcx, TraitPredPrintModifiersAndPath<'tcx>> {
29562964
self.map_bound(TraitPredPrintModifiersAndPath)
29572965
}
2966+
2967+
fn print_with_bound_constness(
2968+
self,
2969+
constness: ty::BoundConstness,
2970+
) -> ty::Binder<'tcx, TraitPredPrintWithBoundConstness<'tcx>> {
2971+
self.map_bound(|trait_pred| TraitPredPrintWithBoundConstness(trait_pred, constness))
2972+
}
29582973
}
29592974

29602975
#[derive(Debug, Copy, Clone, Lift)]
@@ -3052,7 +3067,6 @@ define_print! {
30523067

30533068
ty::TraitPredicate<'tcx> {
30543069
p!(print(self.trait_ref.self_ty()), ": ");
3055-
p!(pretty_print_bound_constness(self.trait_ref));
30563070
if let ty::PredicatePolarity::Negative = self.polarity {
30573071
p!("!");
30583072
}
@@ -3184,13 +3198,21 @@ define_print_and_forward_display! {
31843198
}
31853199

31863200
TraitPredPrintModifiersAndPath<'tcx> {
3187-
p!(pretty_print_bound_constness(self.0.trait_ref));
31883201
if let ty::PredicatePolarity::Negative = self.0.polarity {
31893202
p!("!")
31903203
}
31913204
p!(print(self.0.trait_ref.print_trait_sugared()));
31923205
}
31933206

3207+
TraitPredPrintWithBoundConstness<'tcx> {
3208+
p!(print(self.0.trait_ref.self_ty()), ": ");
3209+
p!(pretty_print_bound_constness(self.1));
3210+
if let ty::PredicatePolarity::Negative = self.0.polarity {
3211+
p!("!");
3212+
}
3213+
p!(print(self.0.trait_ref.print_trait_sugared()))
3214+
}
3215+
31943216
PrintClosureAsImpl<'tcx> {
31953217
p!(pretty_closure_as_impl(self.closure))
31963218
}

compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

+68-18
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ use rustc_middle::ty::abstract_const::NotConstEvaluatable;
1919
use rustc_middle::ty::error::{ExpectedFound, TypeError};
2020
use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
2121
use rustc_middle::ty::print::{
22-
FmtPrinter, Print, PrintTraitPredicateExt as _, PrintTraitRefExt as _,
23-
with_forced_trimmed_paths,
22+
FmtPrinter, Print, PrintPolyTraitPredicateExt, PrintTraitPredicateExt as _,
23+
PrintTraitRefExt as _, with_forced_trimmed_paths,
2424
};
2525
use rustc_middle::ty::{
2626
self, ToPolyTraitRef, TraitRef, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, Upcast,
@@ -154,6 +154,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
154154
} else {
155155
(leaf_trait_predicate, &obligation)
156156
};
157+
158+
let (main_trait_predicate, leaf_trait_predicate, predicate_constness) = self.get_effects_trait_pred_override(main_trait_predicate, leaf_trait_predicate, span);
159+
157160
let main_trait_ref = main_trait_predicate.to_poly_trait_ref();
158161
let leaf_trait_ref = leaf_trait_predicate.to_poly_trait_ref();
159162

@@ -164,9 +167,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
164167
return guar;
165168
}
166169

167-
// FIXME(effects)
168-
let predicate_is_const = false;
169-
170170
if let Err(guar) = leaf_trait_predicate.error_reported()
171171
{
172172
return guar;
@@ -227,7 +227,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
227227
let err_msg = self.get_standard_error_message(
228228
main_trait_predicate,
229229
message,
230-
predicate_is_const,
230+
predicate_constness,
231231
append_const_msg,
232232
post_message,
233233
);
@@ -286,7 +286,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
286286
}
287287

288288
if tcx.is_lang_item(leaf_trait_ref.def_id(), LangItem::Drop)
289-
&& predicate_is_const
289+
&& matches!(predicate_constness, ty::BoundConstness::ConstIfConst | ty::BoundConstness::Const)
290290
{
291291
err.note("`~const Drop` was renamed to `~const Destruct`");
292292
err.note("See <https://github.com/rust-lang/rust/pull/94901> for more details");
@@ -2187,29 +2187,34 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
21872187
&self,
21882188
trait_predicate: ty::PolyTraitPredicate<'tcx>,
21892189
message: Option<String>,
2190-
predicate_is_const: bool,
2190+
predicate_constness: ty::BoundConstness,
21912191
append_const_msg: Option<AppendConstMessage>,
21922192
post_message: String,
21932193
) -> String {
21942194
message
21952195
.and_then(|cannot_do_this| {
2196-
match (predicate_is_const, append_const_msg) {
2196+
match (predicate_constness, append_const_msg) {
21972197
// do nothing if predicate is not const
2198-
(false, _) => Some(cannot_do_this),
2198+
(ty::BoundConstness::NotConst, _) => Some(cannot_do_this),
21992199
// suggested using default post message
2200-
(true, Some(AppendConstMessage::Default)) => {
2201-
Some(format!("{cannot_do_this} in const contexts"))
2202-
}
2200+
(
2201+
ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst,
2202+
Some(AppendConstMessage::Default),
2203+
) => Some(format!("{cannot_do_this} in const contexts")),
22032204
// overridden post message
2204-
(true, Some(AppendConstMessage::Custom(custom_msg, _))) => {
2205-
Some(format!("{cannot_do_this}{custom_msg}"))
2206-
}
2205+
(
2206+
ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst,
2207+
Some(AppendConstMessage::Custom(custom_msg, _)),
2208+
) => Some(format!("{cannot_do_this}{custom_msg}")),
22072209
// fallback to generic message
2208-
(true, None) => None,
2210+
(ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst, None) => None,
22092211
}
22102212
})
22112213
.unwrap_or_else(|| {
2212-
format!("the trait bound `{trait_predicate}` is not satisfied{post_message}")
2214+
format!(
2215+
"the trait bound `{}` is not satisfied{post_message}",
2216+
trait_predicate.print_with_bound_constness(predicate_constness)
2217+
)
22132218
})
22142219
}
22152220

@@ -2333,6 +2338,51 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
23332338
}
23342339
}
23352340

2341+
/// For effects predicates such as `<u32 as Add>::Effects: Compat<host>`, pretend that the
2342+
/// predicate that failed was `u32: Add`. Return the constness of such predicate to later
2343+
/// print as `u32: ~const Add`.
2344+
fn get_effects_trait_pred_override(
2345+
&self,
2346+
p: ty::PolyTraitPredicate<'tcx>,
2347+
leaf: ty::PolyTraitPredicate<'tcx>,
2348+
span: Span,
2349+
) -> (ty::PolyTraitPredicate<'tcx>, ty::PolyTraitPredicate<'tcx>, ty::BoundConstness) {
2350+
let trait_ref = p.to_poly_trait_ref();
2351+
if !self.tcx.is_lang_item(trait_ref.def_id(), LangItem::EffectsCompat) {
2352+
return (p, leaf, ty::BoundConstness::NotConst);
2353+
}
2354+
2355+
let Some(ty::Alias(ty::AliasTyKind::Projection, projection)) =
2356+
trait_ref.self_ty().no_bound_vars().map(Ty::kind)
2357+
else {
2358+
return (p, leaf, ty::BoundConstness::NotConst);
2359+
};
2360+
2361+
let constness = trait_ref.skip_binder().args.const_at(1);
2362+
2363+
let constness = if constness == self.tcx.consts.true_ || constness.is_ct_infer() {
2364+
ty::BoundConstness::NotConst
2365+
} else if constness == self.tcx.consts.false_ {
2366+
ty::BoundConstness::Const
2367+
} else if matches!(constness.kind(), ty::ConstKind::Param(_)) {
2368+
ty::BoundConstness::ConstIfConst
2369+
} else {
2370+
self.dcx().span_bug(span, format!("Unknown constness argument: {constness:?}"));
2371+
};
2372+
2373+
let new_pred = p.map_bound(|mut trait_pred| {
2374+
trait_pred.trait_ref = projection.trait_ref(self.tcx);
2375+
trait_pred
2376+
});
2377+
2378+
let new_leaf = leaf.map_bound(|mut trait_pred| {
2379+
trait_pred.trait_ref = projection.trait_ref(self.tcx);
2380+
trait_pred
2381+
});
2382+
2383+
(new_pred, new_leaf, constness)
2384+
}
2385+
23362386
fn add_tuple_trait_message(
23372387
&self,
23382388
obligation_cause_code: &ObligationCauseCode<'tcx>,

compiler/rustc_type_ir/src/predicate.rs

+7
Original file line numberDiff line numberDiff line change
@@ -755,3 +755,10 @@ impl fmt::Display for BoundConstness {
755755
}
756756
}
757757
}
758+
759+
impl<I> Lift<I> for BoundConstness {
760+
type Lifted = BoundConstness;
761+
fn lift_to_interner(self, _: I) -> Option<Self::Lifted> {
762+
Some(self)
763+
}
764+
}

tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr

+12-4
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ error: using `#![feature(effects)]` without enabling next trait solver globally
33
= note: the next trait solver must be enabled globally for the effects feature to work correctly
44
= help: use `-Znext-solver` to enable
55

6-
error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied
6+
error[E0277]: the trait bound `<T as Trait>::Assoc: Trait` is not satisfied
77
--> $DIR/assoc-type-const-bound-usage-0.rs:13:5
88
|
99
LL | T::Assoc::func()
10-
| ^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}`
10+
| ^^^^^^^^ the trait `Trait` is not implemented for `<T as Trait>::Assoc`
1111
|
1212
note: required by a bound in `Trait::func`
1313
--> $DIR/assoc-type-const-bound-usage-0.rs:6:1
@@ -17,12 +17,16 @@ LL | #[const_trait]
1717
...
1818
LL | fn func() -> i32;
1919
| ---- required by a bound in this associated function
20+
help: consider further restricting the associated type
21+
|
22+
LL | const fn unqualified<T: ~const Trait>() -> i32 where <T as Trait>::Assoc: Trait {
23+
| ++++++++++++++++++++++++++++++++
2024

21-
error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied
25+
error[E0277]: the trait bound `<T as Trait>::Assoc: Trait` is not satisfied
2226
--> $DIR/assoc-type-const-bound-usage-0.rs:17:5
2327
|
2428
LL | <T as Trait>::Assoc::func()
25-
| ^^^^^^^^^^^^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}`
29+
| ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `<T as Trait>::Assoc`
2630
|
2731
note: required by a bound in `Trait::func`
2832
--> $DIR/assoc-type-const-bound-usage-0.rs:6:1
@@ -32,6 +36,10 @@ LL | #[const_trait]
3236
...
3337
LL | fn func() -> i32;
3438
| ---- required by a bound in this associated function
39+
help: consider further restricting the associated type
40+
|
41+
LL | const fn qualified<T: ~const Trait>() -> i32 where <T as Trait>::Assoc: Trait {
42+
| ++++++++++++++++++++++++++++++++
3543

3644
error: aborting due to 3 previous errors
3745

tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr

+12-4
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ error: using `#![feature(effects)]` without enabling next trait solver globally
33
= note: the next trait solver must be enabled globally for the effects feature to work correctly
44
= help: use `-Znext-solver` to enable
55

6-
error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied
6+
error[E0277]: the trait bound `<T as Trait>::Assoc: Trait` is not satisfied
77
--> $DIR/assoc-type-const-bound-usage-1.rs:15:44
88
|
99
LL | fn unqualified<T: const Trait>() -> Type<{ T::Assoc::func() }> {
10-
| ^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}`
10+
| ^^^^^^^^ the trait `Trait` is not implemented for `<T as Trait>::Assoc`
1111
|
1212
note: required by a bound in `Trait::func`
1313
--> $DIR/assoc-type-const-bound-usage-1.rs:7:1
@@ -17,12 +17,16 @@ LL | #[const_trait]
1717
...
1818
LL | fn func() -> i32;
1919
| ---- required by a bound in this associated function
20+
help: consider further restricting the associated type
21+
|
22+
LL | fn unqualified<T: const Trait>() -> Type<{ T::Assoc::func() }> where <T as Trait>::Assoc: Trait {
23+
| ++++++++++++++++++++++++++++++++
2024

21-
error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied
25+
error[E0277]: the trait bound `<T as Trait>::Assoc: Trait` is not satisfied
2226
--> $DIR/assoc-type-const-bound-usage-1.rs:19:42
2327
|
2428
LL | fn qualified<T: const Trait>() -> Type<{ <T as Trait>::Assoc::func() }> {
25-
| ^^^^^^^^^^^^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}`
29+
| ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `<T as Trait>::Assoc`
2630
|
2731
note: required by a bound in `Trait::func`
2832
--> $DIR/assoc-type-const-bound-usage-1.rs:7:1
@@ -32,6 +36,10 @@ LL | #[const_trait]
3236
...
3337
LL | fn func() -> i32;
3438
| ---- required by a bound in this associated function
39+
help: consider further restricting the associated type
40+
|
41+
LL | fn qualified<T: const Trait>() -> Type<{ <T as Trait>::Assoc::func() }> where <T as Trait>::Assoc: Trait {
42+
| ++++++++++++++++++++++++++++++++
3543

3644
error: aborting due to 3 previous errors
3745

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete
1+
//@ compile-flags: -Znext-solver
2+
#![allow(incomplete_features)]
3+
#![feature(const_trait_impl, effects)]
24

35
#[const_trait]
46
pub trait Plus {
@@ -23,7 +25,7 @@ pub const fn add_i32(a: i32, b: i32) -> i32 {
2325

2426
pub const fn add_u32(a: u32, b: u32) -> u32 {
2527
a.plus(b)
26-
//~^ ERROR the trait bound
28+
//~^ ERROR the trait bound `u32: ~const Plus`
2729
}
2830

2931
fn main() {}

0 commit comments

Comments
 (0)