Skip to content

Commit 4ab82ec

Browse files
Lower AST and resolve lifetimes for unsafe binder types
1 parent a7e8859 commit 4ab82ec

File tree

12 files changed

+116
-1
lines changed

12 files changed

+116
-1
lines changed

compiler/rustc_ast_lowering/src/index.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,12 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
291291
self.insert(ty.span, ty.hir_id, Node::Ty(ty));
292292

293293
self.with_parent(ty.hir_id, |this| {
294+
// FIXME(unsafe_binders): Should we split this out into a separate
295+
// visit function?
296+
if let TyKind::UnsafeBinder(binder) = ty.kind {
297+
this.insert(ty.span, binder.hir_id, Node::UnsafeBinder(binder));
298+
};
299+
294300
intravisit::walk_ty(this, ty);
295301
});
296302
}

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,6 +1228,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
12281228
param_names: self.lower_fn_params_to_names(&f.decl),
12291229
}))
12301230
}
1231+
TyKind::UnsafeBinder(f) => {
1232+
let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1233+
hir::TyKind::UnsafeBinder(self.arena.alloc(hir::UnsafeBinderTy {
1234+
span: self.lower_span(t.span),
1235+
hir_id: self.next_id(),
1236+
generic_params,
1237+
inner_ty: self.lower_ty(&f.inner_ty, itctx),
1238+
}))
1239+
}
12311240
TyKind::Never => hir::TyKind::Never,
12321241
TyKind::Tup(tys) => hir::TyKind::Tup(
12331242
self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))),

compiler/rustc_hir/src/hir.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2780,6 +2780,14 @@ pub struct BareFnTy<'hir> {
27802780
pub param_names: &'hir [Ident],
27812781
}
27822782

2783+
#[derive(Debug, Clone, Copy, HashStable_Generic)]
2784+
pub struct UnsafeBinderTy<'hir> {
2785+
pub hir_id: HirId,
2786+
pub span: Span,
2787+
pub generic_params: &'hir [GenericParam<'hir>],
2788+
pub inner_ty: &'hir Ty<'hir>,
2789+
}
2790+
27832791
#[derive(Debug, Clone, Copy, HashStable_Generic)]
27842792
pub struct OpaqueTy<'hir> {
27852793
pub hir_id: HirId,
@@ -2878,6 +2886,8 @@ pub enum TyKind<'hir> {
28782886
Ref(&'hir Lifetime, MutTy<'hir>),
28792887
/// A bare function (e.g., `fn(usize) -> bool`).
28802888
BareFn(&'hir BareFnTy<'hir>),
2889+
/// Uwu
2890+
UnsafeBinder(&'hir UnsafeBinderTy<'hir>),
28812891
/// The never type (`!`).
28822892
Never,
28832893
/// A tuple (`(A, B, C, D, ...)`).
@@ -3845,6 +3855,7 @@ pub enum Node<'hir> {
38453855
Infer(&'hir InferArg),
38463856
WherePredicate(&'hir WherePredicate<'hir>),
38473857
PreciseCapturingNonLifetimeArg(&'hir PreciseCapturingNonLifetimeArg),
3858+
UnsafeBinder(&'hir UnsafeBinderTy<'hir>),
38483859
// Created by query feeding
38493860
Synthetic,
38503861
Err(Span),
@@ -3897,6 +3908,7 @@ impl<'hir> Node<'hir> {
38973908
| Node::OpaqueTy(..)
38983909
| Node::Infer(..)
38993910
| Node::WherePredicate(..)
3911+
| Node::UnsafeBinder(..)
39003912
| Node::Synthetic
39013913
| Node::Err(..) => None,
39023914
}

compiler/rustc_hir/src/intravisit.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,11 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul
886886
walk_list!(visitor, visit_generic_param, function_declaration.generic_params);
887887
try_visit!(visitor.visit_fn_decl(function_declaration.decl));
888888
}
889+
TyKind::UnsafeBinder(ref unsafe_binder) => {
890+
try_visit!(visitor.visit_id(unsafe_binder.hir_id));
891+
walk_list!(visitor, visit_generic_param, unsafe_binder.generic_params);
892+
try_visit!(visitor.visit_ty(unsafe_binder.inner_ty));
893+
}
889894
TyKind::Path(ref qpath) => {
890895
try_visit!(visitor.visit_qpath(qpath, typ.hir_id, typ.span));
891896
}

compiler/rustc_hir_analysis/src/collect/generics_of.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,12 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
470470
self.outer_index.shift_out(1);
471471
res
472472
}
473+
hir::TyKind::UnsafeBinder(_) => {
474+
self.outer_index.shift_in(1);
475+
let res = intravisit::walk_ty(self, ty);
476+
self.outer_index.shift_out(1);
477+
res
478+
}
473479
_ => intravisit::walk_ty(self, ty),
474480
}
475481
}

compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,36 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
781781
intravisit::walk_ty(this, ty);
782782
});
783783
}
784+
hir::TyKind::UnsafeBinder(binder) => {
785+
let (mut bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) =
786+
binder
787+
.generic_params
788+
.iter()
789+
.enumerate()
790+
.map(|(late_bound_idx, param)| {
791+
(
792+
(param.def_id, ResolvedArg::late(late_bound_idx as u32, param)),
793+
late_arg_as_bound_arg(self.tcx, param),
794+
)
795+
})
796+
.unzip();
797+
798+
deny_non_region_late_bound(self.tcx, &mut bound_vars, "function pointer types");
799+
800+
self.record_late_bound_vars(binder.hir_id, binders);
801+
let scope = Scope::Binder {
802+
hir_id: ty.hir_id,
803+
bound_vars,
804+
s: self.scope,
805+
scope_type: BinderScopeType::Normal,
806+
where_bound_origin: None,
807+
};
808+
self.with(scope, |this| {
809+
// a bare fn has no bounds, so everything
810+
// contained within is scoped within its binder.
811+
intravisit::walk_ty(this, ty);
812+
});
813+
}
784814
hir::TyKind::TraitObject(bounds, lifetime, _) => {
785815
debug!(?bounds, ?lifetime, "TraitObject");
786816
let scope = Scope::TraitRefBoundary { s: self.scope };

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2308,6 +2308,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
23082308
self.lower_fn_ty(hir_ty.hir_id, bf.safety, bf.abi, bf.decl, None, Some(hir_ty)),
23092309
)
23102310
}
2311+
hir::TyKind::UnsafeBinder(_binder) => {
2312+
let guar = self
2313+
.dcx()
2314+
.struct_span_err(hir_ty.span, "unsafe binders are not yet implemented")
2315+
.emit();
2316+
Ty::new_error(tcx, guar)
2317+
}
23112318
hir::TyKind::TraitObject(bounds, lifetime, repr) => {
23122319
if let Some(guar) = self.prohibit_or_lint_bare_trait_object_ty(hir_ty) {
23132320
// Don't continue with type analysis if the `dyn` keyword is missing

compiler/rustc_hir_pretty/src/lib.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ impl<'a> State<'a> {
118118
Node::LetStmt(a) => self.print_local_decl(a),
119119
Node::Crate(..) => panic!("cannot print Crate"),
120120
Node::WherePredicate(pred) => self.print_where_predicate(pred),
121+
Node::UnsafeBinder(binder) => self.print_unsafe_binder(binder),
121122
Node::Synthetic => unreachable!(),
122123
Node::Err(_) => self.word("/*ERROR*/"),
123124
}
@@ -288,6 +289,9 @@ impl<'a> State<'a> {
288289
hir::TyKind::BareFn(f) => {
289290
self.print_ty_fn(f.abi, f.safety, f.decl, None, f.generic_params, f.param_names);
290291
}
292+
hir::TyKind::UnsafeBinder(unsafe_binder) => {
293+
self.print_unsafe_binder(unsafe_binder);
294+
}
291295
hir::TyKind::OpaqueDef(..) => self.word("/*impl Trait*/"),
292296
hir::TyKind::Path(ref qpath) => self.print_qpath(qpath, false),
293297
hir::TyKind::TraitObject(bounds, lifetime, syntax) => {
@@ -340,6 +344,15 @@ impl<'a> State<'a> {
340344
self.end()
341345
}
342346

347+
fn print_unsafe_binder(&mut self, unsafe_binder: &hir::UnsafeBinderTy<'_>) {
348+
self.ibox(INDENT_UNIT);
349+
self.word("unsafe");
350+
self.print_generic_params(unsafe_binder.generic_params);
351+
self.nbsp();
352+
self.print_type(unsafe_binder.inner_ty);
353+
self.end();
354+
}
355+
343356
fn print_foreign_item(&mut self, item: &hir::ForeignItem<'_>) {
344357
self.hardbreak_if_not_bol();
345358
self.maybe_print_comment(item.span.lo());

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
427427
| hir::Node::Infer(_)
428428
| hir::Node::WherePredicate(_)
429429
| hir::Node::PreciseCapturingNonLifetimeArg(_)
430-
| hir::Node::OpaqueTy(_) => {
430+
| hir::Node::OpaqueTy(_)
431+
| hir::Node::UnsafeBinder(_) => {
431432
unreachable!("no sub-expr expected for {parent_node:?}")
432433
}
433434
}

compiler/rustc_middle/src/hir/map/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,7 @@ impl<'hir> Map<'hir> {
949949
Node::Crate(item) => item.spans.inner_span,
950950
Node::WherePredicate(pred) => pred.span,
951951
Node::PreciseCapturingNonLifetimeArg(param) => param.ident.span,
952+
Node::UnsafeBinder(binder) => binder.span,
952953
Node::Synthetic => unreachable!(),
953954
Node::Err(span) => span,
954955
}
@@ -1228,6 +1229,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
12281229
Node::Synthetic => unreachable!(),
12291230
Node::Err(_) => node_str("error"),
12301231
Node::PreciseCapturingNonLifetimeArg(_param) => node_str("parameter"),
1232+
Node::UnsafeBinder(_) => node_str("unsafe binder"),
12311233
}
12321234
}
12331235

compiler/rustc_passes/src/input_stats.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
335335
Ptr,
336336
Ref,
337337
BareFn,
338+
UnsafeBinder,
338339
Never,
339340
Tup,
340341
AnonAdt,
@@ -586,6 +587,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
586587
Ref,
587588
PinnedRef,
588589
BareFn,
590+
UnsafeBinder,
589591
Never,
590592
Tup,
591593
Path,

compiler/rustc_resolve/src/late.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,28 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
887887
},
888888
)
889889
}
890+
TyKind::UnsafeBinder(unsafe_binder) => {
891+
// FIXME(unsafe_binder): Better span
892+
let span = ty.span;
893+
self.with_generic_param_rib(
894+
&unsafe_binder.generic_params,
895+
RibKind::Normal,
896+
LifetimeRibKind::Generics {
897+
binder: ty.id,
898+
kind: LifetimeBinderKind::BareFnType,
899+
span,
900+
},
901+
|this| {
902+
this.visit_generic_params(&unsafe_binder.generic_params, false);
903+
this.with_lifetime_rib(
904+
// We don't allow anonymous `unsafe &'_ ()` binders,
905+
// although I guess we could.
906+
LifetimeRibKind::AnonymousReportError,
907+
|this| this.visit_ty(&unsafe_binder.inner_ty),
908+
);
909+
},
910+
)
911+
}
890912
TyKind::Array(element_ty, length) => {
891913
self.visit_ty(element_ty);
892914
self.resolve_anon_const(length, AnonConstKind::ConstArg(IsRepeatExpr::No));

0 commit comments

Comments
 (0)