Pull out some shared code into a new function
This commit is contained in:
parent
0e11fc8053
commit
9e42d3e434
@ -1483,36 +1483,25 @@ fn add_predicates_for_ast_type_binding(
|
||||
tcx.collect_referenced_late_bound_regions(&ty::Binder::bind(ty));
|
||||
debug!("late_bound_in_trait_ref = {:?}", late_bound_in_trait_ref);
|
||||
debug!("late_bound_in_ty = {:?}", late_bound_in_ty);
|
||||
for br in late_bound_in_ty.difference(&late_bound_in_trait_ref) {
|
||||
let br_name = match *br {
|
||||
ty::BrNamed(_, name) => format!("lifetime `{}`", name),
|
||||
_ => "an anonymous lifetime".to_string(),
|
||||
};
|
||||
// FIXME: point at the type params that don't have appropriate lifetimes:
|
||||
// struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
|
||||
// ---- ---- ^^^^^^^
|
||||
let mut err = struct_span_err!(
|
||||
tcx.sess,
|
||||
binding.span,
|
||||
E0582,
|
||||
"binding for associated type `{}` references {}, \
|
||||
which does not appear in the trait input types",
|
||||
binding.item_name,
|
||||
br_name
|
||||
);
|
||||
|
||||
if let ty::BrAnon(_) = *br {
|
||||
// The only way for an anonymous lifetime to wind up
|
||||
// in the return type but **also** be unconstrained is
|
||||
// if it only appears in "associated types" in the
|
||||
// input. See #62200 for an example. In this case,
|
||||
// though we can easily give a hint that ought to be
|
||||
// relevant.
|
||||
err.note("lifetimes appearing in an associated type are not considered constrained");
|
||||
}
|
||||
|
||||
err.emit();
|
||||
}
|
||||
// FIXME: point at the type params that don't have appropriate lifetimes:
|
||||
// struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
|
||||
// ---- ---- ^^^^^^^
|
||||
self.validate_late_bound_regions(
|
||||
late_bound_in_trait_ref,
|
||||
late_bound_in_ty,
|
||||
|br_name| {
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
binding.span,
|
||||
E0582,
|
||||
"binding for associated type `{}` references {}, \
|
||||
which does not appear in the trait input types",
|
||||
binding.item_name,
|
||||
br_name
|
||||
)
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3085,33 +3074,48 @@ pub fn ty_of_fn(
|
||||
tcx.collect_constrained_late_bound_regions(&inputs.map_bound(|i| i.to_owned()));
|
||||
let output = bare_fn_ty.output();
|
||||
let late_bound_in_ret = tcx.collect_referenced_late_bound_regions(&output);
|
||||
for br in late_bound_in_ret.difference(&late_bound_in_args) {
|
||||
let lifetime_name = match *br {
|
||||
ty::BrNamed(_, name) => format!("lifetime `{}`,", name),
|
||||
ty::BrAnon(_) | ty::BrEnv => "an anonymous lifetime".to_string(),
|
||||
};
|
||||
let mut err = struct_span_err!(
|
||||
|
||||
self.validate_late_bound_regions(late_bound_in_args, late_bound_in_ret, |br_name| {
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
decl.output.span(),
|
||||
E0581,
|
||||
"return type references {} which is not constrained by the fn input types",
|
||||
lifetime_name
|
||||
);
|
||||
br_name
|
||||
)
|
||||
});
|
||||
|
||||
bare_fn_ty
|
||||
}
|
||||
|
||||
fn validate_late_bound_regions(
|
||||
&self,
|
||||
constrained_regions: FxHashSet<ty::BoundRegion>,
|
||||
referenced_regions: FxHashSet<ty::BoundRegion>,
|
||||
generate_err: impl Fn(&str) -> rustc_errors::DiagnosticBuilder<'tcx>,
|
||||
) {
|
||||
for br in referenced_regions.difference(&constrained_regions) {
|
||||
let br_name = match *br {
|
||||
ty::BrNamed(_, name) => format!("lifetime `{}`", name),
|
||||
ty::BrAnon(_) | ty::BrEnv => "an anonymous lifetime".to_string(),
|
||||
};
|
||||
|
||||
let mut err = generate_err(&br_name);
|
||||
|
||||
if let ty::BrAnon(_) = *br {
|
||||
// The only way for an anonymous lifetime to wind up
|
||||
// in the return type but **also** be unconstrained is
|
||||
// if it only appears in "associated types" in the
|
||||
// input. See #47511 for an example. In this case,
|
||||
// input. See #47511 and #62200 for examples. In this case,
|
||||
// though we can easily give a hint that ought to be
|
||||
// relevant.
|
||||
err.note(
|
||||
"lifetimes appearing in an associated type are not considered constrained",
|
||||
);
|
||||
}
|
||||
|
||||
err.emit();
|
||||
}
|
||||
|
||||
bare_fn_ty
|
||||
}
|
||||
|
||||
/// Given the bounds on an object, determines what single region bound (if any) we can
|
||||
|
Loading…
Reference in New Issue
Block a user