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
38 changes: 21 additions & 17 deletions compiler/rustc_trait_selection/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ pub enum RegionOriginNote<'a> {

impl Subdiagnostic for RegionOriginNote<'_> {
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
let mut label_or_note = |span, msg: DiagMessage| {
let label_or_note = |diag: &mut Diag<'_, G>, span, msg: DiagMessage| {
let sub_count = diag.children.iter().filter(|d| d.span.is_dummy()).count();
let expanded_sub_count = diag.children.iter().filter(|d| !d.span.is_dummy()).count();
let span_is_primary = diag.span.primary_spans().iter().all(|&sp| sp == span);
Expand All @@ -491,22 +491,26 @@ impl Subdiagnostic for RegionOriginNote<'_> {
};
match self {
RegionOriginNote::Plain { span, msg } => {
label_or_note(span, msg);
label_or_note(diag, span, msg);
}
RegionOriginNote::WithName { span, msg, name, continues } => {
label_or_note(span, msg);
diag.arg("name", name);
diag.arg("continues", continues);
label_or_note(diag, span, msg);
}
RegionOriginNote::WithRequirement {
span,
requirement,
expected_found: Some((expected, found)),
} => {
label_or_note(
span,
msg!(
"...so that the {$requirement ->
// `RegionOriginNote` can appear multiple times on one diagnostic with different
// `requirement` values. Scope args per-note and eagerly translate to avoid
// cross-note arg collisions.
// See https://github.com/rust-lang/rust/issues/143872 for details.
diag.store_args();
diag.arg("requirement", requirement);
let msg = diag.eagerly_translate(msg!(
"...so that the {$requirement ->
[method_compat] method type is compatible with trait
[type_compat] associated type is compatible with trait
[const_compat] const is compatible with trait
Expand All @@ -519,20 +523,20 @@ impl Subdiagnostic for RegionOriginNote<'_> {
[method_correct_type] method receiver has the correct type
*[other] types are compatible
}"
),
);
diag.arg("requirement", requirement);
));
diag.restore_args();
label_or_note(diag, span, msg);

diag.note_expected_found("", expected, "", found);
}
RegionOriginNote::WithRequirement { span, requirement, expected_found: None } => {
// FIXME: this really should be handled at some earlier stage. Our
// handling of region checking when type errors are present is
// *terrible*.
label_or_note(
span,
msg!(
"...so that {$requirement ->
diag.store_args();
diag.arg("requirement", requirement);
let msg = diag.eagerly_translate(msg!(
"...so that {$requirement ->
[method_compat] method type is compatible with trait
[type_compat] associated type is compatible with trait
[const_compat] const is compatible with trait
Expand All @@ -545,9 +549,9 @@ impl Subdiagnostic for RegionOriginNote<'_> {
[method_correct_type] method receiver has the correct type
*[other] types are compatible
}"
),
);
diag.arg("requirement", requirement);
));
diag.restore_args();
label_or_note(diag, span, msg);
}
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//@ compile-flags: --crate-type=lib
// Regression test for https://github.com/rust-lang/rust/issues/143872

trait Project {
type Ty;
}

impl Project for &'_ &'static () {
type Ty = ();
}

trait Trait {
fn get<'s>(s: &'s str, _: ()) -> &'_ str;
}

impl Trait for () {
fn get<'s>(s: &'s str, _: <&&'s () as Project>::Ty) -> &'static str {
//~^ ERROR cannot infer an appropriate lifetime for lifetime parameter 's in generic type due to conflicting requirements
//~| ERROR mismatched types
//~| ERROR lifetime may not live long enough
s
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
error[E0803]: cannot infer an appropriate lifetime for lifetime parameter 's in generic type due to conflicting requirements
--> $DIR/compare-impl-item-conflicting-lifetime-requirements.rs:17:5
|
LL | fn get<'s>(s: &'s str, _: <&&'s () as Project>::Ty) -> &'static str {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'s` as defined here...
--> $DIR/compare-impl-item-conflicting-lifetime-requirements.rs:13:12
|
LL | fn get<'s>(s: &'s str, _: ()) -> &'_ str;
| ^^
note: ...so that the method type is compatible with trait
--> $DIR/compare-impl-item-conflicting-lifetime-requirements.rs:17:5
|
LL | fn get<'s>(s: &'s str, _: <&&'s () as Project>::Ty) -> &'static str {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: expected `fn(&'s _, ()) -> &'s _`
found `fn(&_, ()) -> &'static _`
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the types are compatible
--> $DIR/compare-impl-item-conflicting-lifetime-requirements.rs:17:5
|
LL | fn get<'s>(s: &'s str, _: <&&'s () as Project>::Ty) -> &'static str {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: expected `<&&() as Project>`
found `<&&'static () as Project>`

error[E0308]: mismatched types
--> $DIR/compare-impl-item-conflicting-lifetime-requirements.rs:17:31
|
LL | fn get<'s>(s: &'s str, _: <&&'s () as Project>::Ty) -> &'static str {
| ^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
= note: expected trait `<&&'s () as Project>`
found trait `<&&'static () as Project>`
note: the lifetime `'s` as defined here...
--> $DIR/compare-impl-item-conflicting-lifetime-requirements.rs:17:12
|
LL | fn get<'s>(s: &'s str, _: <&&'s () as Project>::Ty) -> &'static str {
| ^^
= note: ...does not necessarily outlive the static lifetime

error: lifetime may not live long enough
--> $DIR/compare-impl-item-conflicting-lifetime-requirements.rs:17:5
|
LL | fn get<'s>(s: &'s str, _: <&&'s () as Project>::Ty) -> &'static str {
| ^^^^^^^--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | lifetime `'s` defined here
| requires that `'s` must outlive `'static`

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0308, E0803.
For more information about an error, try `rustc --explain E0308`.
Loading