Skip to content

Commit 9af6b3d

Browse files
committed
Auto merge of #74737 - smmalis37:astconv-factor, r=davidtwco
Pull out some duplicated code into a new function I debated pulling the actual struct_span_err calls into the new method, but I felt like having to pass in multiple arguments for it and wiring up string formatting outweighed the benefits. Viewing the diff with whitespace ignored is recommended.
2 parents 1841fb9 + 617dd0a commit 9af6b3d

File tree

2 files changed

+46
-42
lines changed

2 files changed

+46
-42
lines changed

src/librustc_typeck/astconv.rs

+45-41
Original file line numberDiff line numberDiff line change
@@ -1483,36 +1483,25 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
14831483
tcx.collect_referenced_late_bound_regions(&ty::Binder::bind(ty));
14841484
debug!("late_bound_in_trait_ref = {:?}", late_bound_in_trait_ref);
14851485
debug!("late_bound_in_ty = {:?}", late_bound_in_ty);
1486-
for br in late_bound_in_ty.difference(&late_bound_in_trait_ref) {
1487-
let br_name = match *br {
1488-
ty::BrNamed(_, name) => format!("lifetime `{}`", name),
1489-
_ => "an anonymous lifetime".to_string(),
1490-
};
1491-
// FIXME: point at the type params that don't have appropriate lifetimes:
1492-
// struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
1493-
// ---- ---- ^^^^^^^
1494-
let mut err = struct_span_err!(
1495-
tcx.sess,
1496-
binding.span,
1497-
E0582,
1498-
"binding for associated type `{}` references {}, \
1499-
which does not appear in the trait input types",
1500-
binding.item_name,
1501-
br_name
1502-
);
1503-
1504-
if let ty::BrAnon(_) = *br {
1505-
// The only way for an anonymous lifetime to wind up
1506-
// in the return type but **also** be unconstrained is
1507-
// if it only appears in "associated types" in the
1508-
// input. See #62200 for an example. In this case,
1509-
// though we can easily give a hint that ought to be
1510-
// relevant.
1511-
err.note("lifetimes appearing in an associated type are not considered constrained");
1512-
}
15131486

1514-
err.emit();
1515-
}
1487+
// FIXME: point at the type params that don't have appropriate lifetimes:
1488+
// struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
1489+
// ---- ---- ^^^^^^^
1490+
self.validate_late_bound_regions(
1491+
late_bound_in_trait_ref,
1492+
late_bound_in_ty,
1493+
|br_name| {
1494+
struct_span_err!(
1495+
tcx.sess,
1496+
binding.span,
1497+
E0582,
1498+
"binding for associated type `{}` references {}, \
1499+
which does not appear in the trait input types",
1500+
binding.item_name,
1501+
br_name
1502+
)
1503+
},
1504+
);
15161505
}
15171506
}
15181507

@@ -3085,33 +3074,48 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
30853074
tcx.collect_constrained_late_bound_regions(&inputs.map_bound(|i| i.to_owned()));
30863075
let output = bare_fn_ty.output();
30873076
let late_bound_in_ret = tcx.collect_referenced_late_bound_regions(&output);
3088-
for br in late_bound_in_ret.difference(&late_bound_in_args) {
3089-
let lifetime_name = match *br {
3090-
ty::BrNamed(_, name) => format!("lifetime `{}`,", name),
3091-
ty::BrAnon(_) | ty::BrEnv => "an anonymous lifetime".to_string(),
3092-
};
3093-
let mut err = struct_span_err!(
3077+
3078+
self.validate_late_bound_regions(late_bound_in_args, late_bound_in_ret, |br_name| {
3079+
struct_span_err!(
30943080
tcx.sess,
30953081
decl.output.span(),
30963082
E0581,
3097-
"return type references {} which is not constrained by the fn input types",
3098-
lifetime_name
3099-
);
3083+
"return type references {}, which is not constrained by the fn input types",
3084+
br_name
3085+
)
3086+
});
3087+
3088+
bare_fn_ty
3089+
}
3090+
3091+
fn validate_late_bound_regions(
3092+
&self,
3093+
constrained_regions: FxHashSet<ty::BoundRegion>,
3094+
referenced_regions: FxHashSet<ty::BoundRegion>,
3095+
generate_err: impl Fn(&str) -> rustc_errors::DiagnosticBuilder<'tcx>,
3096+
) {
3097+
for br in referenced_regions.difference(&constrained_regions) {
3098+
let br_name = match *br {
3099+
ty::BrNamed(_, name) => format!("lifetime `{}`", name),
3100+
ty::BrAnon(_) | ty::BrEnv => "an anonymous lifetime".to_string(),
3101+
};
3102+
3103+
let mut err = generate_err(&br_name);
3104+
31003105
if let ty::BrAnon(_) = *br {
31013106
// The only way for an anonymous lifetime to wind up
31023107
// in the return type but **also** be unconstrained is
31033108
// if it only appears in "associated types" in the
3104-
// input. See #47511 for an example. In this case,
3109+
// input. See #47511 and #62200 for examples. In this case,
31053110
// though we can easily give a hint that ought to be
31063111
// relevant.
31073112
err.note(
31083113
"lifetimes appearing in an associated type are not considered constrained",
31093114
);
31103115
}
3116+
31113117
err.emit();
31123118
}
3113-
3114-
bare_fn_ty
31153119
}
31163120

31173121
/// Given the bounds on an object, determines what single region bound (if any) we can

src/test/ui/issues/issue-47511.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0581]: return type references an anonymous lifetime which is not constrained by the fn input types
1+
error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
22
--> $DIR/issue-47511.rs:5:15
33
|
44
LL | fn f(_: X) -> X {

0 commit comments

Comments
 (0)