Skip to content

Commit c72c6e0

Browse files
committed
Merge the ~const and impl const checks and add some explanatory notes
1 parent 33bcea8 commit c72c6e0

File tree

4 files changed

+34
-45
lines changed

4 files changed

+34
-45
lines changed

compiler/rustc_passes/src/check_const.rs

-26
Original file line numberDiff line numberDiff line change
@@ -191,32 +191,6 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> {
191191
self.tcx.hir()
192192
}
193193

194-
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
195-
let tcx = self.tcx;
196-
if let hir::ItemKind::Impl(hir::Impl {
197-
constness: hir::Constness::Const,
198-
of_trait: Some(trait_ref),
199-
..
200-
}) = item.kind
201-
&& let Some(def_id) = trait_ref.trait_def_id()
202-
{
203-
let source_map = tcx.sess.source_map();
204-
if !tcx.has_attr(def_id, sym::const_trait) {
205-
tcx.sess
206-
.struct_span_err(
207-
source_map.guess_head_span(item.span),
208-
"const `impl`s must be for traits marked with `#[const_trait]`",
209-
)
210-
.span_note(
211-
source_map.guess_head_span(tcx.def_span(def_id)),
212-
"this trait must be annotated with `#[const_trait]`",
213-
)
214-
.emit();
215-
}
216-
}
217-
intravisit::walk_item(self, item);
218-
}
219-
220194
fn visit_anon_const(&mut self, anon: &'tcx hir::AnonConst) {
221195
let kind = Some(hir::ConstContext::Const);
222196
self.recurse_into(kind, None, |this| intravisit::walk_anon_const(this, anon));

compiler/rustc_trait_selection/src/traits/wf.rs

+24-2
Original file line numberDiff line numberDiff line change
@@ -309,8 +309,30 @@ impl<'tcx> WfPredicates<'tcx> {
309309
self.nominal_obligations_without_const(trait_ref.def_id, trait_ref.substs)
310310
} else {
311311
if !tcx.has_attr(trait_ref.def_id, rustc_span::sym::const_trait) {
312-
tcx.sess
313-
.span_err(self.span, "~const can only be applied to `#[const_trait]` traits");
312+
if let Some(item) = self.item &&
313+
let hir::ItemKind::Impl(impl_) = item.kind &&
314+
let Some(trait_) = &impl_.of_trait &&
315+
let Some(def_id) = trait_.trait_def_id() &&
316+
def_id == trait_ref.def_id
317+
{
318+
let trait_name = tcx.item_name(def_id);
319+
let mut err = tcx.sess.struct_span_err(
320+
self.span,
321+
&format!("const `impl` for trait `{trait_name}` which is not marked with `#[const_trait]`"),
322+
);
323+
if def_id.is_local() {
324+
let sp = tcx.def_span(def_id).shrink_to_lo();
325+
err.span_suggestion(sp, &format!("mark `{trait_name}` as const"), "#[const_trait]", rustc_errors::Applicability::MachineApplicable);
326+
}
327+
err.note("marking a trait with `#[const_trait]` ensures all default method bodies are `const`");
328+
err.note("adding a non-const method body in the future would be a breaking change");
329+
err.emit();
330+
} else {
331+
tcx.sess.span_err(
332+
self.span,
333+
"~const can only be applied to `#[const_trait]` traits",
334+
);
335+
}
314336
}
315337
self.nominal_obligations(trait_ref.def_id, trait_ref.substs)
316338
};
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
#![feature(const_trait_impl)]
22

33
pub trait A {}
4-
//~^ NOTE: this trait must be annotated with `#[const_trait]`
4+
//~^ HELP: mark `A` as const
55

66
impl const A for () {}
7-
//~^ ERROR: const `impl`s must be for traits marked with `#[const_trait]`
8-
//~| ERROR: ~const can only be applied to `#[const_trait]` traits
7+
//~^ ERROR: const `impl` for trait `A` which is not marked with `#[const_trait]`
98

109
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
1-
error: const `impl`s must be for traits marked with `#[const_trait]`
2-
--> $DIR/const-impl-requires-const-trait.rs:6:1
3-
|
4-
LL | impl const A for () {}
5-
| ^^^^^^^^^^^^^^^^^^^
6-
|
7-
note: this trait must be annotated with `#[const_trait]`
8-
--> $DIR/const-impl-requires-const-trait.rs:3:1
9-
|
10-
LL | pub trait A {}
11-
| ^^^^^^^^^^^
12-
13-
error: ~const can only be applied to `#[const_trait]` traits
1+
error: const `impl` for trait `A` which is not marked with `#[const_trait]`
142
--> $DIR/const-impl-requires-const-trait.rs:6:12
153
|
4+
LL | pub trait A {}
5+
| - help: mark `A` as const: `#[const_trait]`
6+
...
167
LL | impl const A for () {}
178
| ^
9+
|
10+
= note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
11+
= note: adding a non-const method body in the future would be a breaking change
1812

19-
error: aborting due to 2 previous errors
13+
error: aborting due to previous error
2014

0 commit comments

Comments
 (0)