Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -882,55 +882,46 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
let trait_name = self.tcx.item_name(trait_did);

if self.tcx.is_const_trait(trait_did) && !self.tcx.is_const_trait_impl(impl_did) {
if let Some(impl_did) = impl_did.as_local()
&& let item = self.tcx.hir_expect_item(impl_did)
&& let hir::ItemKind::Impl(item) = item.kind
&& let Some(of_trait) = item.of_trait
{
// trait is const, impl is local and not const
diag.span_suggestion_verbose(
of_trait.trait_ref.path.span.shrink_to_lo(),
format!("make the `impl` of trait `{trait_name}` `const`"),
"const ".to_string(),
Applicability::MaybeIncorrect,
);
} else {
if !impl_did.is_local() {
diag.span_note(
impl_span,
format!("trait `{trait_name}` is implemented but not `const`"),
);
}

let (condition_options, format_args) = self.on_unimplemented_components(
if let Some(command) =
find_attr!(self.tcx, impl_did, OnConst {directive, ..} => directive.as_deref())
.flatten()
{
let (_, format_args) = self.on_unimplemented_components(
trait_ref,
main_obligation,
diag.long_ty_path(),
);
let CustomDiagnostic { message, label, notes, parent_label: _ } =
command.eval(None, &format_args);

if let Some(command) = find_attr!(self.tcx, impl_did, OnConst {directive, ..} => directive.as_deref()).flatten(){
let note = command.eval(
Some(&condition_options),
&format_args,
);
let CustomDiagnostic {
message,
label,
notes,
parent_label,
} = note;

if let Some(message) = message {
diag.primary_message(message);
}
if let Some(label) = label {
diag.span_label(impl_span, label);
}
for note in notes {
diag.note(note);
}
if let Some(parent_label) = parent_label {
diag.span_label(impl_span, parent_label);
}
if let Some(message) = message {
diag.primary_message(message);
}
if let Some(label) = label {
diag.span_label(span, label);
}
for note in notes {
diag.note(note);
}
} else if let Some(impl_did) = impl_did.as_local()
&& let item = self.tcx.hir_expect_item(impl_did)
&& let hir::ItemKind::Impl(item) = item.kind
&& let Some(of_trait) = item.of_trait
{
// trait is const, impl is local and not const
diag.span_suggestion_verbose(
of_trait.trait_ref.path.span.shrink_to_lo(),
format!("make the `impl` of trait `{trait_name}` `const`"),
"const ".to_string(),
Applicability::MaybeIncorrect,
);
}
}
}
Expand Down
10 changes: 0 additions & 10 deletions tests/ui/diagnostic_namespace/on_const/auxiliary/const_trait.rs

This file was deleted.

15 changes: 15 additions & 0 deletions tests/ui/diagnostic_namespace/on_const/auxiliary/non_const_impl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#![feature(diagnostic_on_const)]

pub struct X;

#[diagnostic::on_const(
message = "their message",
label = "their label",
note = "their note",
note = "their other note"
)]
impl PartialEq for X {
fn eq(&self, _other: &X) -> bool {
true
}
}
16 changes: 16 additions & 0 deletions tests/ui/diagnostic_namespace/on_const/it_works_foreign.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//@ aux-build: non_const_impl.rs
#![crate_type = "lib"]

extern crate non_const_impl;

use non_const_impl::X;

const _: () = {
let x = X;
x == x;
//~^ ERROR: their message
//~| NOTE: their label
//~| NOTE: trait `PartialEq` is implemented but not `const`
//~| NOTE: their note
//~| NOTE: their other note
};
17 changes: 17 additions & 0 deletions tests/ui/diagnostic_namespace/on_const/it_works_foreign.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error[E0277]: their message
--> $DIR/it_works_foreign.rs:10:5
|
LL | x == x;
| ^^^^^^ their label
|
note: trait `PartialEq` is implemented but not `const`
--> $DIR/auxiliary/non_const_impl.rs:11:1
|
LL | impl PartialEq for X {
| ^^^^^^^^^^^^^^^^^^^^
= note: their note
= note: their other note

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.
25 changes: 25 additions & 0 deletions tests/ui/diagnostic_namespace/on_const/it_works_local.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#![crate_type = "lib"]
#![feature(diagnostic_on_const)]

pub struct X;

#[diagnostic::on_const(
message = "my message",
label = "my label",
note = "my note",
note = "my other note"
)]
impl PartialEq for X {
fn eq(&self, _other: &X) -> bool {
true
}
}

const _: () = {
let x = X;
x == x;
//~^ ERROR: my message
//~| NOTE: my label
//~| NOTE: my note
//~| NOTE: my other note
};
12 changes: 12 additions & 0 deletions tests/ui/diagnostic_namespace/on_const/it_works_local.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0277]: my message
--> $DIR/it_works_local.rs:20:5
|
LL | x == x;
| ^^^^^^ my label
|
= note: my note
= note: my other note

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.
Loading