Skip to content

Commit 949baf3

Browse files
authored
Unrolled build for #144194
Rollup merge of #144194 - estebank:const-traits, r=davidtwco Provide additional context to errors involving const traits When encountering an unmet `Ty: [const] Trait` bound, if `Trait` is `#[const_trait]` and there's an `impl Trait for Ty` point at it. If local, suggest `impl const Trait for Ty`, otherwise just point at it. ``` error[E0277]: the trait bound `NonConstAdd: [const] Add` is not satisfied --> $DIR/assoc-type.rs:37:16 | LL | type Bar = NonConstAdd; | ^^^^^^^^^^^ | note: required by a bound in `Foo::Bar` --> $DIR/assoc-type.rs:33:15 | LL | type Bar: [const] Add; | ^^^^^^^^^^^ required by this bound in `Foo::Bar` help: make the `impl` of trait `Add` `const` | LL | impl const Add for NonConstAdd { | +++++ ``` ``` error[E0277]: the trait bound `T: [const] PartialEq` is not satisfied --> tests/ui/traits/const-traits/call-generic-method-fail.rs:5:5 | 5 | *t == *t | ^^^^^^^^ | note: trait `PartialEq` is implemented but not `const` --> /home/gh-estebank/rust/library/core/src/ptr/const_ptr.rs:1590:1 | 1590 | impl<T: PointeeSized> PartialEq for *const T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: trait `PartialEq` is implemented but not `const` --> /home/gh-estebank/rust/library/core/src/ptr/mut_ptr.rs:2011:1 | 2011 | impl<T: PointeeSized> PartialEq for *mut T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ```
2 parents c5dabe8 + 74b7592 commit 949baf3

File tree

54 files changed

+475
-12
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+475
-12
lines changed

compiler/rustc_const_eval/src/check_consts/ops.rs

Lines changed: 65 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! Concrete error types for all operations which may be invalid in a certain const context.
22
33
use hir::{ConstContext, LangItem};
4-
use rustc_errors::Diag;
54
use rustc_errors::codes::*;
5+
use rustc_errors::{Applicability, Diag, MultiSpan};
66
use rustc_hir as hir;
77
use rustc_hir::def_id::DefId;
88
use rustc_infer::infer::TyCtxtInferExt;
@@ -11,8 +11,8 @@ use rustc_middle::mir::CallSource;
1111
use rustc_middle::span_bug;
1212
use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths};
1313
use rustc_middle::ty::{
14-
self, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, TraitRef, Ty,
15-
suggest_constraining_type_param,
14+
self, AssocContainer, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, TraitRef,
15+
Ty, suggest_constraining_type_param,
1616
};
1717
use rustc_session::parse::add_feature_diagnostics;
1818
use rustc_span::{BytePos, Pos, Span, Symbol, sym};
@@ -352,18 +352,71 @@ fn build_error_for_const_call<'tcx>(
352352
non_or_conditionally,
353353
})
354354
}
355-
_ => ccx.dcx().create_err(errors::NonConstFnCall {
356-
span,
357-
def_descr: ccx.tcx.def_descr(callee),
358-
def_path_str: ccx.tcx.def_path_str_with_args(callee, args),
359-
kind: ccx.const_kind(),
360-
non_or_conditionally,
361-
}),
355+
_ => {
356+
let def_descr = ccx.tcx.def_descr(callee);
357+
let mut err = ccx.dcx().create_err(errors::NonConstFnCall {
358+
span,
359+
def_descr,
360+
def_path_str: ccx.tcx.def_path_str_with_args(callee, args),
361+
kind: ccx.const_kind(),
362+
non_or_conditionally,
363+
});
364+
if let Some(item) = ccx.tcx.opt_associated_item(callee) {
365+
if let AssocContainer::Trait = item.container
366+
&& let parent = item.container_id(ccx.tcx)
367+
&& !ccx.tcx.is_const_trait(parent)
368+
{
369+
let assoc_span = ccx.tcx.def_span(callee);
370+
let assoc_name = ccx.tcx.item_name(callee);
371+
let mut span: MultiSpan = ccx.tcx.def_span(parent).into();
372+
span.push_span_label(assoc_span, format!("this {def_descr} is not const"));
373+
let trait_descr = ccx.tcx.def_descr(parent);
374+
let trait_span = ccx.tcx.def_span(parent);
375+
let trait_name = ccx.tcx.item_name(parent);
376+
span.push_span_label(trait_span, format!("this {trait_descr} is not const"));
377+
err.span_note(
378+
span,
379+
format!(
380+
"{def_descr} `{assoc_name}` is not const because {trait_descr} \
381+
`{trait_name}` is not const",
382+
),
383+
);
384+
if parent.is_local() && ccx.tcx.sess.is_nightly_build() {
385+
if !ccx.tcx.features().const_trait_impl() {
386+
err.help(
387+
"add `#![feature(const_trait_impl)]` to the crate attributes to \
388+
enable `#[const_trait]`",
389+
);
390+
}
391+
let indentation = ccx
392+
.tcx
393+
.sess
394+
.source_map()
395+
.indentation_before(trait_span)
396+
.unwrap_or_default();
397+
err.span_suggestion_verbose(
398+
trait_span.shrink_to_lo(),
399+
format!("consider making trait `{trait_name}` const"),
400+
format!("#[const_trait]\n{indentation}"),
401+
Applicability::MaybeIncorrect,
402+
);
403+
} else if !ccx.tcx.sess.is_nightly_build() {
404+
err.help("const traits are not yet supported on stable Rust");
405+
}
406+
}
407+
} else if ccx.tcx.constness(callee) != hir::Constness::Const {
408+
let name = ccx.tcx.item_name(callee);
409+
err.span_note(
410+
ccx.tcx.def_span(callee),
411+
format!("{def_descr} `{name}` is not const"),
412+
);
413+
}
414+
err
415+
}
362416
};
363417

364418
err.note(format!(
365-
"calls in {}s are limited to constant functions, \
366-
tuple structs and tuple variants",
419+
"calls in {}s are limited to constant functions, tuple structs and tuple variants",
367420
ccx.const_kind(),
368421
));
369422

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,34 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
839839
)) {
840840
diag.downgrade_to_delayed_bug();
841841
}
842+
for candidate in self.find_similar_impl_candidates(trait_ref) {
843+
let CandidateSimilarity::Exact { .. } = candidate.similarity else { continue };
844+
let impl_did = candidate.impl_def_id;
845+
let trait_did = candidate.trait_ref.def_id;
846+
let impl_span = self.tcx.def_span(impl_did);
847+
let trait_name = self.tcx.item_name(trait_did);
848+
849+
if self.tcx.is_const_trait(trait_did) && !self.tcx.is_const_trait_impl(impl_did) {
850+
if let Some(impl_did) = impl_did.as_local()
851+
&& let item = self.tcx.hir_expect_item(impl_did)
852+
&& let hir::ItemKind::Impl(item) = item.kind
853+
&& let Some(of_trait) = item.of_trait
854+
{
855+
// trait is const, impl is local and not const
856+
diag.span_suggestion_verbose(
857+
of_trait.trait_ref.path.span.shrink_to_lo(),
858+
format!("make the `impl` of trait `{trait_name}` `const`"),
859+
"const ".to_string(),
860+
Applicability::MaybeIncorrect,
861+
);
862+
} else {
863+
diag.span_note(
864+
impl_span,
865+
format!("trait `{trait_name}` is implemented but not `const`"),
866+
);
867+
}
868+
}
869+
}
842870
diag
843871
}
844872

tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-disabled.stderr

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,20 @@ error[E0015]: cannot call non-const method `<T as Foo>::a` in constant functions
5858
LL | x.a();
5959
| ^^^
6060
|
61+
note: method `a` is not const because trait `Foo` is not const
62+
--> const-super-trait.rs:3:1
63+
|
64+
LL | trait Foo {
65+
| ^^^^^^^^^ this trait is not const
66+
LL | fn a(&self);
67+
| ------------ this method is not const
68+
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable `#[const_trait]`
6169
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
70+
help: consider making trait `Foo` const
71+
|
72+
LL + #[const_trait]
73+
LL | trait Foo {
74+
|
6275

6376
error: aborting due to 6 previous errors
6477

tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-enabled.stderr

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,19 @@ error[E0015]: cannot call non-const method `<T as Foo>::a` in constant functions
3838
LL | x.a();
3939
| ^^^
4040
|
41+
note: method `a` is not const because trait `Foo` is not const
42+
--> const-super-trait.rs:3:1
43+
|
44+
LL | trait Foo {
45+
| ^^^^^^^^^ this trait is not const
46+
LL | fn a(&self);
47+
| ------------ this method is not const
4148
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
49+
help: consider making trait `Foo` const
50+
|
51+
LL + #[const_trait]
52+
LL | trait Foo {
53+
|
4254

4355
error: aborting due to 4 previous errors
4456

tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-disabled.stderr

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ error[E0015]: cannot call non-const method `<T as Foo>::a` in constant functions
5656
10 | x.a();
5757
| ^^^
5858
|
59+
note: method `a` is not const because trait `Foo` is not const
60+
--> const-super-trait.rs:3:1
61+
|
62+
3 | trait Foo {
63+
| ^^^^^^^^^ this trait is not const
64+
4 | fn a(&self);
65+
| ------------ this method is not const
66+
= help: const traits are not yet supported on stable Rust
5967
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
6068

6169
error: aborting due to 6 previous errors

tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-enabled.stderr

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ error[E0015]: cannot call non-const method `<T as Foo>::a` in constant functions
4646
10 | x.a();
4747
| ^^^
4848
|
49+
note: method `a` is not const because trait `Foo` is not const
50+
--> const-super-trait.rs:3:1
51+
|
52+
3 | trait Foo {
53+
| ^^^^^^^^^ this trait is not const
54+
4 | fn a(&self);
55+
| ------------ this method is not const
56+
= help: const traits are not yet supported on stable Rust
4957
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
5058

5159
error: aborting due to 5 previous errors

tests/ui/asm/non-const.stderr

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ error[E0015]: cannot call non-const function `non_const_fn` in constants
44
LL | global_asm!("/* {} */", const non_const_fn(0));
55
| ^^^^^^^^^^^^^^^
66
|
7+
note: function `non_const_fn` is not const
8+
--> $DIR/non-const.rs:8:1
9+
|
10+
LL | fn non_const_fn(x: i32) -> i32 { x }
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
712
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
813

914
error: aborting due to 1 previous error

tests/ui/borrowck/issue-64453.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ error[E0015]: cannot call non-const function `format` in statics
44
LL | static settings_dir: String = format!("");
55
| ^^^^^^^^^^^
66
|
7+
note: function `format` is not const
8+
--> $SRC_DIR/alloc/src/fmt.rs:LL:COL
79
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
810
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
911
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)

tests/ui/consts/const-call.stderr

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ error[E0015]: cannot call non-const function `f` in constants
44
LL | let _ = [0; f(2)];
55
| ^^^^
66
|
7+
note: function `f` is not const
8+
--> $DIR/const-call.rs:1:1
9+
|
10+
LL | fn f(x: usize) -> usize {
11+
| ^^^^^^^^^^^^^^^^^^^^^^^
712
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
813

914
error: aborting due to 1 previous error

tests/ui/consts/const-eval/format.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ error[E0015]: cannot call non-const function `_print` in constant functions
2121
LL | println!("{:?}", 0);
2222
| ^^^^^^^^^^^^^^^^^^^
2323
|
24+
note: function `_print` is not const
25+
--> $SRC_DIR/std/src/io/stdio.rs:LL:COL
2426
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
2527
= note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
2628

0 commit comments

Comments
 (0)