Better error
This commit is contained in:
parent
82148cdc66
commit
e391796d47
@ -288,7 +288,6 @@ fn check_gat_where_clauses(
|
||||
associated_items.in_definition_order().filter(|item| matches!(item.kind, ty::AssocKind::Fn))
|
||||
{
|
||||
let id = hir::HirId::make_owner(item.def_id.expect_local());
|
||||
let span = DUMMY_SP;
|
||||
let param_env = tcx.param_env(item.def_id.expect_local());
|
||||
|
||||
let sig = tcx.fn_sig(item.def_id);
|
||||
@ -308,7 +307,7 @@ fn check_gat_where_clauses(
|
||||
for (ty, ty_idx) in &visitor.types {
|
||||
tcx.infer_ctxt().enter(|infcx| {
|
||||
let mut outlives_environment = OutlivesEnvironment::new(param_env);
|
||||
outlives_environment.add_implied_bounds(&infcx, wf_tys.clone(), id, span);
|
||||
outlives_environment.add_implied_bounds(&infcx, wf_tys.clone(), id, DUMMY_SP);
|
||||
outlives_environment.save_implied_bounds(id);
|
||||
let region_bound_pairs =
|
||||
outlives_environment.region_bound_pairs_map().get(&id).unwrap();
|
||||
@ -349,7 +348,6 @@ fn check_gat_where_clauses(
|
||||
name: ty_param.name,
|
||||
}));
|
||||
let region_param = generics.param_at(*region_idx, tcx);
|
||||
// Then create a clause that is required on the GAT
|
||||
let region_param =
|
||||
tcx.mk_region(ty::RegionKind::ReEarlyBound(ty::EarlyBoundRegion {
|
||||
def_id: region_param.def_id,
|
||||
@ -372,13 +370,35 @@ fn check_gat_where_clauses(
|
||||
debug!(?clauses);
|
||||
if !clauses.is_empty() {
|
||||
let written_predicates: ty::GenericPredicates<'_> = tcx.predicates_of(trait_item.def_id);
|
||||
for clause in clauses {
|
||||
let found = written_predicates.predicates.iter().find(|p| p.0 == clause).is_some();
|
||||
debug!(?clause, ?found);
|
||||
let mut error = tcx
|
||||
.sess
|
||||
.struct_span_err(trait_item.generics.span, &format!("Missing bound: {}", clause));
|
||||
error.emit();
|
||||
let clauses: Vec<_> = clauses
|
||||
.drain_filter(|clause| {
|
||||
written_predicates.predicates.iter().find(|p| &p.0 == clause).is_none()
|
||||
})
|
||||
.map(|clause| format!("{}", clause))
|
||||
.collect();
|
||||
if !clauses.is_empty() {
|
||||
let mut err = tcx.sess.struct_span_err(
|
||||
trait_item.span,
|
||||
&format!("Missing required bounds on {}", trait_item.ident),
|
||||
);
|
||||
|
||||
let suggestion = format!(
|
||||
"{} {}",
|
||||
if !trait_item.generics.where_clause.predicates.is_empty() {
|
||||
","
|
||||
} else {
|
||||
" where"
|
||||
},
|
||||
clauses.join(", "),
|
||||
);
|
||||
err.span_suggestion(
|
||||
trait_item.generics.where_clause.tail_span_for_suggestion(),
|
||||
"add the required where clauses",
|
||||
suggestion,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
|
||||
err.emit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -69,6 +69,7 @@
|
||||
#![feature(never_type)]
|
||||
#![feature(slice_partition_dedup)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(hash_drain_filter)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
#[macro_use]
|
||||
|
@ -2,9 +2,10 @@
|
||||
|
||||
// check-fail
|
||||
|
||||
// We have a `&'a self`, so we need a `Self: 'a`
|
||||
trait Iterable {
|
||||
type Item<'x>;
|
||||
//~^ Missing bound
|
||||
//~^ Missing required bounds
|
||||
fn iter<'a>(&'a self) -> Self::Item<'a>;
|
||||
}
|
||||
|
||||
@ -17,9 +18,10 @@ fn iter<'a>(&'a self) -> Self::Item<'a> {
|
||||
}
|
||||
*/
|
||||
|
||||
// We have a `&'a T`, so we need a `T: 'x`
|
||||
trait Deserializer<T> {
|
||||
type Out<'x>;
|
||||
//~^ Missing bound
|
||||
//~^ Missing required bounds
|
||||
fn deserialize<'a>(&self, input: &'a T) -> Self::Out<'a>;
|
||||
}
|
||||
|
||||
@ -30,19 +32,21 @@ fn deserialize<'a>(&self, input: &'a T) -> Self::Out<'a> { input }
|
||||
}
|
||||
*/
|
||||
|
||||
// We have a `&'b T` and a `'b: 'a`, so it is implied that `T: 'a`. Therefore, we need a `T: 'x`
|
||||
trait Deserializer2<T> {
|
||||
type Out<'x>;
|
||||
//~^ Missing bound
|
||||
fn deserialize2<'a, 'b: 'a>(&self, input: &'a T, input2: &'b T) -> Self::Out<'a>;
|
||||
//~^ Missing required bounds
|
||||
fn deserialize2<'a, 'b: 'a>(&self, input1: &'b T) -> Self::Out<'a>;
|
||||
}
|
||||
|
||||
// We have a `&'a T` and a `&'b U`, so we need a `T: 'x` and a `U: 'y`
|
||||
trait Deserializer3<T, U> {
|
||||
type Out<'x, 'y>;
|
||||
//~^ Missing bound
|
||||
//~^^ Missing bound
|
||||
//~^ Missing required bounds
|
||||
fn deserialize2<'a, 'b>(&self, input: &'a T, input2: &'b U) -> Self::Out<'a, 'b>;
|
||||
}
|
||||
|
||||
// `T` is a param on the function, so it can't be named by the associated type
|
||||
trait Deserializer4 {
|
||||
type Out<'x>;
|
||||
fn deserialize<'a, T>(&self, input: &'a T) -> Self::Out<'a>;
|
||||
@ -50,36 +54,41 @@ trait Deserializer4 {
|
||||
|
||||
struct Wrap<T>(T);
|
||||
|
||||
// Even though we might theoretically want `D: 'x`, because we pass `Wrap<T>` and
|
||||
// we see `&'z Wrap<T>`, we are conservative and only add bounds for direct params
|
||||
trait Des {
|
||||
type Out<'x, D>;
|
||||
fn des<'z, T>(&self, data: &'z Wrap<T>) -> Self::Out<'z, Wrap<T>>;
|
||||
}
|
||||
/*
|
||||
impl Des for () {
|
||||
type Out<'x, D> = &'x D;
|
||||
type Out<'x, D> = &'x D; // Not okay
|
||||
fn des<'a, T>(&self, data: &'a Wrap<T>) -> Self::Out<'a, Wrap<T>> {
|
||||
data
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// We have `T` and `'z` as GAT substs. Because of `&'z Wrap<T>`, there is an
|
||||
// implied bound that `T: 'z`, so we require `D: 'x`
|
||||
trait Des2 {
|
||||
type Out<'x, D>;
|
||||
//~^ Missing bound
|
||||
//~^ Missing required bounds
|
||||
fn des<'z, T>(&self, data: &'z Wrap<T>) -> Self::Out<'z, T>;
|
||||
}
|
||||
/*
|
||||
impl Des2 for () {
|
||||
type Out<'x, D> = &'x D;
|
||||
fn des<'a, T>(&self, data: &'a Wrap<T>) -> Self::Out<'a, T> {
|
||||
data
|
||||
&data.0
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// We see `&'z T`, so we require `D: 'x`
|
||||
trait Des3 {
|
||||
type Out<'x, D>;
|
||||
//~^ Missing bound
|
||||
//~^ Missing required bounds
|
||||
fn des<'z, T>(&self, data: &'z T) -> Self::Out<'z, T>;
|
||||
}
|
||||
/*
|
||||
|
@ -1,44 +1,50 @@
|
||||
error: Missing bound: Self: 'x
|
||||
--> $DIR/self-outlives-lint.rs:6:14
|
||||
error: Missing required bounds on Item
|
||||
--> $DIR/self-outlives-lint.rs:7:5
|
||||
|
|
||||
LL | type Item<'x>;
|
||||
| ^^^^
|
||||
| ^^^^^^^^^^^^^-
|
||||
| |
|
||||
| help: add the required where clauses: `where Self: 'x`
|
||||
|
||||
error: Missing bound: T: 'x
|
||||
--> $DIR/self-outlives-lint.rs:21:13
|
||||
error: Missing required bounds on Out
|
||||
--> $DIR/self-outlives-lint.rs:23:5
|
||||
|
|
||||
LL | type Out<'x>;
|
||||
| ^^^^
|
||||
| ^^^^^^^^^^^^-
|
||||
| |
|
||||
| help: add the required where clauses: `where T: 'x`
|
||||
|
||||
error: Missing bound: T: 'x
|
||||
--> $DIR/self-outlives-lint.rs:34:13
|
||||
error: Missing required bounds on Out
|
||||
--> $DIR/self-outlives-lint.rs:37:5
|
||||
|
|
||||
LL | type Out<'x>;
|
||||
| ^^^^
|
||||
| ^^^^^^^^^^^^-
|
||||
| |
|
||||
| help: add the required where clauses: `where T: 'x`
|
||||
|
||||
error: Missing bound: U: 'y
|
||||
--> $DIR/self-outlives-lint.rs:40:13
|
||||
error: Missing required bounds on Out
|
||||
--> $DIR/self-outlives-lint.rs:44:5
|
||||
|
|
||||
LL | type Out<'x, 'y>;
|
||||
| ^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^-
|
||||
| |
|
||||
| help: add the required where clauses: `where U: 'y, T: 'x`
|
||||
|
||||
error: Missing bound: T: 'x
|
||||
--> $DIR/self-outlives-lint.rs:40:13
|
||||
|
|
||||
LL | type Out<'x, 'y>;
|
||||
| ^^^^^^^^
|
||||
|
||||
error: Missing bound: D: 'x
|
||||
--> $DIR/self-outlives-lint.rs:67:13
|
||||
error: Missing required bounds on Out
|
||||
--> $DIR/self-outlives-lint.rs:75:5
|
||||
|
|
||||
LL | type Out<'x, D>;
|
||||
| ^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^-
|
||||
| |
|
||||
| help: add the required where clauses: `where D: 'x`
|
||||
|
||||
error: Missing bound: D: 'x
|
||||
--> $DIR/self-outlives-lint.rs:81:13
|
||||
error: Missing required bounds on Out
|
||||
--> $DIR/self-outlives-lint.rs:90:5
|
||||
|
|
||||
LL | type Out<'x, D>;
|
||||
| ^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^-
|
||||
| |
|
||||
| help: add the required where clauses: `where D: 'x`
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user