1
Fork 0

Lower closure binders to hir & properly check them

This commit is contained in:
Maybe Waffle 2022-07-12 13:34:24 +04:00
parent f89ef3cf66
commit c2dbd62c7c
16 changed files with 214 additions and 103 deletions

View file

@ -571,7 +571,51 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
}
fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
if let hir::ExprKind::Closure { bound_generic_params, .. } = e.kind {
if let hir::ExprKind::Closure { binder, bound_generic_params, fn_decl, .. } = e.kind {
if let &hir::ClosureBinder::For { span: for_sp, .. } = binder {
fn span_of_infer(ty: &hir::Ty<'_>) -> Option<Span> {
struct V(Option<Span>);
impl<'v> Visitor<'v> for V {
fn visit_ty(&mut self, t: &'v hir::Ty<'v>) {
match t.kind {
_ if self.0.is_some() => (),
hir::TyKind::Infer => {
self.0 = Some(t.span);
}
_ => intravisit::walk_ty(self, t),
}
}
}
let mut v = V(None);
v.visit_ty(ty);
v.0
}
let infer_in_rt_sp = match fn_decl.output {
hir::FnRetTy::DefaultReturn(sp) => Some(sp),
hir::FnRetTy::Return(ty) => span_of_infer(ty),
};
let infer_spans = fn_decl
.inputs
.into_iter()
.filter_map(span_of_infer)
.chain(infer_in_rt_sp)
.collect::<Vec<_>>();
if !infer_spans.is_empty() {
self.tcx.sess
.struct_span_err(
infer_spans,
"implicit types in closure signatures are forbidden when `for<...>` is present",
)
.span_label(for_sp, "`for<...>` is here")
.emit();
}
}
let next_early_index = self.next_early_index();
let (lifetimes, binders): (FxIndexMap<LocalDefId, Region>, Vec<_>) =
bound_generic_params
@ -584,6 +628,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
(pair, r)
})
.unzip();
// FIXME: missing_named_lifetime_spots
self.map.late_bound_vars.insert(e.hir_id, binders);
let scope = Scope::Binder {
hir_id: e.hir_id,