-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #65068 - estebank:trait-impl-lt-mismatch, r=nikomatsakis
Custom lifetime error for `impl` item doesn't conform to `trait` Partly addresses #42706, #41343, fix #40900.
- Loading branch information
Showing
10 changed files
with
115 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 changes: 59 additions & 0 deletions
59
src/librustc/infer/error_reporting/nice_region_error/trait_impl_difference.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
//! Error Reporting for `impl` items that do not match the obligations from their `trait`. | ||
|
||
use syntax_pos::Span; | ||
use crate::ty::Ty; | ||
use crate::infer::{ValuePairs, Subtype}; | ||
use crate::infer::error_reporting::nice_region_error::NiceRegionError; | ||
use crate::infer::lexical_region_resolve::RegionResolutionError; | ||
use crate::util::common::ErrorReported; | ||
use crate::traits::ObligationCauseCode::CompareImplMethodObligation; | ||
|
||
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { | ||
/// Print the error message for lifetime errors when the `impl` doesn't conform to the `trait`. | ||
pub(super) fn try_report_impl_not_conforming_to_trait(&self) -> Option<ErrorReported> { | ||
if let Some(ref error) = self.error { | ||
debug!("try_report_impl_not_conforming_to_trait {:?}", error); | ||
if let RegionResolutionError::SubSupConflict( | ||
_, | ||
var_origin, | ||
sub_origin, | ||
_sub, | ||
sup_origin, | ||
_sup, | ||
) = error.clone() { | ||
match (&sup_origin, &sub_origin) { | ||
(&Subtype(ref sup_trace), &Subtype(ref sub_trace)) => { | ||
if let ( | ||
ValuePairs::Types(sub_expected_found), | ||
ValuePairs::Types(sup_expected_found), | ||
CompareImplMethodObligation { trait_item_def_id, .. }, | ||
) = (&sub_trace.values, &sup_trace.values, &sub_trace.cause.code) { | ||
if sup_expected_found == sub_expected_found { | ||
self.emit_err( | ||
var_origin.span(), | ||
sub_expected_found.expected, | ||
sub_expected_found.found, | ||
self.tcx().def_span(*trait_item_def_id), | ||
); | ||
return Some(ErrorReported); | ||
} | ||
} | ||
} | ||
_ => {} | ||
} | ||
} | ||
} | ||
None | ||
} | ||
|
||
fn emit_err(&self, sp: Span, expected: Ty<'tcx>, found: Ty<'tcx>, impl_sp: Span) { | ||
let mut err = self.tcx().sess.struct_span_err( | ||
sp, | ||
"`impl` item signature doesn't match `trait` item signature", | ||
); | ||
err.note(&format!("expected `{:?}`\n found `{:?}`", expected, found)); | ||
err.span_label(sp, &format!("found {:?}", found)); | ||
err.span_label(impl_sp, &format!("expected {:?}", expected)); | ||
err.emit(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 9 additions & 14 deletions
23
src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,16 @@ | ||
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in generic type due to conflicting requirements | ||
--> $DIR/mismatched_trait_impl-2.rs:8:5 | ||
error: `impl` item signature doesn't match `trait` item signature | ||
--> $DIR/mismatched_trait_impl-2.rs:10:5 | ||
| | ||
LL | fn deref(&self) -> &dyn Trait { | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&Struct) -> &dyn Trait | ||
| | ||
::: $SRC_DIR/libcore/ops/deref.rs:LL:COL | ||
| | ||
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 8:5... | ||
--> $DIR/mismatched_trait_impl-2.rs:8:5 | ||
LL | fn deref(&self) -> &Self::Target; | ||
| --------------------------------- expected fn(&Struct) -> &(dyn Trait + 'static) | ||
| | ||
LL | / fn deref(&self) -> &dyn Trait { | ||
LL | | unimplemented!(); | ||
LL | | } | ||
| |_____^ | ||
= note: ...but the lifetime must also be valid for the static lifetime... | ||
= note: ...so that the method type is compatible with trait: | ||
expected fn(&Struct) -> &(dyn Trait + 'static) | ||
found fn(&Struct) -> &dyn Trait | ||
= note: expected `fn(&Struct) -> &(dyn Trait + 'static)` | ||
found `fn(&Struct) -> &dyn Trait` | ||
|
||
error: aborting due to previous error | ||
|
||
For more information about this error, try `rustc --explain E0495`. |
25 changes: 7 additions & 18 deletions
25
src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,14 @@ | ||
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in generic type due to conflicting requirements | ||
error: `impl` item signature doesn't match `trait` item signature | ||
--> $DIR/mismatched_trait_impl.rs:9:5 | ||
| | ||
LL | fn foo(&self, x: &'a u32, y: &u32) -> &'a u32; | ||
| ---------------------------------------------- expected fn(&i32, &'a u32, &u32) -> &'a u32 | ||
... | ||
LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&i32, &u32, &u32) -> &u32 | ||
| | ||
note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the method body at 9:5... | ||
--> $DIR/mismatched_trait_impl.rs:9:5 | ||
| | ||
LL | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { | ||
LL | | x | ||
LL | | } | ||
| |_____^ | ||
note: ...but the lifetime must also be valid for the lifetime `'a` as defined on the method body at 9:32... | ||
--> $DIR/mismatched_trait_impl.rs:9:32 | ||
| | ||
LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { | ||
| ^^ | ||
= note: ...so that the method type is compatible with trait: | ||
expected fn(&i32, &'a u32, &u32) -> &'a u32 | ||
found fn(&i32, &u32, &u32) -> &u32 | ||
= note: expected `fn(&i32, &'a u32, &u32) -> &'a u32` | ||
found `fn(&i32, &u32, &u32) -> &u32` | ||
|
||
error: aborting due to previous error | ||
|
||
For more information about this error, try `rustc --explain E0495`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
trait Foo { | ||
fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32; | ||
} | ||
|
||
impl Foo for () { | ||
fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 { | ||
//~^ ERROR `impl` item signature doesn't match `trait` item signature | ||
if x > y { x } else { y } | ||
} | ||
} | ||
|
||
fn main() {} |
14 changes: 14 additions & 0 deletions
14
src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
error: `impl` item signature doesn't match `trait` item signature | ||
--> $DIR/lifetime-mismatch-between-trait-and-impl.rs:6:5 | ||
| | ||
LL | fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32; | ||
| ------------------------------------------- expected fn(&i32, &'a i32) -> &'a i32 | ||
... | ||
LL | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 { | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&i32, &i32) -> &i32 | ||
| | ||
= note: expected `fn(&i32, &'a i32) -> &'a i32` | ||
found `fn(&i32, &i32) -> &i32` | ||
|
||
error: aborting due to previous error | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters