Skip to content

Commit 13f6e74

Browse files
Lower AST and resolve lifetimes for unsafe binder type
1 parent ec1ab7f commit 13f6e74

File tree

13 files changed

+114
-0
lines changed

13 files changed

+114
-0
lines changed

compiler/rustc_ast_lowering/src/index.rs

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

287287
self.with_parent(ty.hir_id, |this| {
288+
// FIXME(unsafe_binders): Should we split this out into a separate
289+
// visit function?
290+
if let TyKind::UnsafeBinder(binder) = ty.kind {
291+
this.insert(ty.span, binder.hir_id, Node::UnsafeBinder(binder));
292+
};
293+
288294
intravisit::walk_ty(this, ty);
289295
});
290296
}

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,6 +1310,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
13101310
param_names: self.lower_fn_params_to_names(&f.decl),
13111311
}))
13121312
}
1313+
TyKind::UnsafeBinder(f) => {
1314+
let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1315+
hir::TyKind::UnsafeBinder(self.arena.alloc(hir::UnsafeBinderTy {
1316+
span: self.lower_span(t.span),
1317+
hir_id: self.next_id(),
1318+
generic_params,
1319+
inner_ty: self.lower_ty(&f.inner_ty, itctx),
1320+
}))
1321+
}
13131322
TyKind::Never => hir::TyKind::Never,
13141323
TyKind::Tup(tys) => hir::TyKind::Tup(
13151324
self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))),

compiler/rustc_ast_lowering/src/lifetime_collector.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@ impl<'ast> Visitor<'ast> for LifetimeCollectVisitor<'ast> {
9595
visit::walk_ty(self, t);
9696
self.current_binders.pop();
9797
}
98+
TyKind::UnsafeBinder(_) => {
99+
self.current_binders.push(t.id);
100+
visit::walk_ty(self, t);
101+
self.current_binders.pop();
102+
}
98103
TyKind::Ref(None, _) => {
99104
self.record_elided_anchor(t.id, t.span);
100105
visit::walk_ty(self, t);

compiler/rustc_hir/src/hir.rs

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

2742+
#[derive(Debug, Clone, Copy, HashStable_Generic)]
2743+
pub struct UnsafeBinderTy<'hir> {
2744+
pub hir_id: HirId,
2745+
pub span: Span,
2746+
pub generic_params: &'hir [GenericParam<'hir>],
2747+
pub inner_ty: &'hir Ty<'hir>,
2748+
}
2749+
27422750
#[derive(Debug, Clone, Copy, HashStable_Generic)]
27432751
pub struct OpaqueTy<'hir> {
27442752
pub generics: &'hir Generics<'hir>,
@@ -2831,6 +2839,8 @@ pub enum TyKind<'hir> {
28312839
Ref(&'hir Lifetime, MutTy<'hir>),
28322840
/// A bare function (e.g., `fn(usize) -> bool`).
28332841
BareFn(&'hir BareFnTy<'hir>),
2842+
/// Uwu
2843+
UnsafeBinder(&'hir UnsafeBinderTy<'hir>),
28342844
/// The never type (`!`).
28352845
Never,
28362846
/// A tuple (`(A, B, C, D, ...)`).
@@ -3801,6 +3811,7 @@ pub enum Node<'hir> {
38013811
// FIXME: Merge into `Node::Infer`.
38023812
ArrayLenInfer(&'hir InferArg),
38033813
PreciseCapturingNonLifetimeArg(&'hir PreciseCapturingNonLifetimeArg),
3814+
UnsafeBinder(&'hir UnsafeBinderTy<'hir>),
38043815
// Created by query feeding
38053816
Synthetic,
38063817
Err(Span),
@@ -3853,6 +3864,7 @@ impl<'hir> Node<'hir> {
38533864
| Node::Infer(..)
38543865
| Node::WhereBoundPredicate(..)
38553866
| Node::ArrayLenInfer(..)
3867+
| Node::UnsafeBinder(..)
38563868
| Node::Synthetic
38573869
| Node::Err(..) => None,
38583870
}

compiler/rustc_hir/src/intravisit.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,11 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul
891891
walk_list!(visitor, visit_generic_param, function_declaration.generic_params);
892892
try_visit!(visitor.visit_fn_decl(function_declaration.decl));
893893
}
894+
TyKind::UnsafeBinder(ref unsafe_binder) => {
895+
try_visit!(visitor.visit_id(unsafe_binder.hir_id));
896+
walk_list!(visitor, visit_generic_param, unsafe_binder.generic_params);
897+
try_visit!(visitor.visit_ty(unsafe_binder.inner_ty));
898+
}
894899
TyKind::Path(ref qpath) => {
895900
try_visit!(visitor.visit_qpath(qpath, typ.hir_id, typ.span));
896901
}

compiler/rustc_hir_analysis/src/collect/generics_of.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,12 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
480480
self.outer_index.shift_out(1);
481481
res
482482
}
483+
hir::TyKind::UnsafeBinder(_) => {
484+
self.outer_index.shift_in(1);
485+
let res = intravisit::walk_ty(self, ty);
486+
self.outer_index.shift_out(1);
487+
res
488+
}
483489
_ => intravisit::walk_ty(self, ty),
484490
}
485491
}

compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,35 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
648648
intravisit::walk_ty(this, ty);
649649
});
650650
}
651+
hir::TyKind::UnsafeBinder(binder) => {
652+
let (mut bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) =
653+
binder
654+
.generic_params
655+
.iter()
656+
.enumerate()
657+
.map(|(late_bound_idx, param)| {
658+
let pair = ResolvedArg::late(late_bound_idx as u32, param);
659+
let r = late_arg_as_bound_arg(self.tcx, &pair.1, param);
660+
(pair, r)
661+
})
662+
.unzip();
663+
664+
deny_non_region_late_bound(self.tcx, &mut bound_vars, "function pointer types");
665+
666+
self.record_late_bound_vars(binder.hir_id, binders);
667+
let scope = Scope::Binder {
668+
hir_id: ty.hir_id,
669+
bound_vars,
670+
s: self.scope,
671+
scope_type: BinderScopeType::Normal,
672+
where_bound_origin: None,
673+
};
674+
self.with(scope, |this| {
675+
// a bare fn has no bounds, so everything
676+
// contained within is scoped within its binder.
677+
intravisit::walk_ty(this, ty);
678+
});
679+
}
651680
hir::TyKind::TraitObject(bounds, lifetime, _) => {
652681
debug!(?bounds, ?lifetime, "TraitObject");
653682
let scope = Scope::TraitRefBoundary { s: self.scope };

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2052,6 +2052,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
20522052
self.lower_fn_ty(hir_ty.hir_id, bf.safety, bf.abi, bf.decl, None, Some(hir_ty)),
20532053
)
20542054
}
2055+
hir::TyKind::UnsafeBinder(_binder) => todo!(),
20552056
hir::TyKind::TraitObject(bounds, lifetime, repr) => {
20562057
self.prohibit_or_lint_bare_trait_object_ty(hir_ty);
20572058

compiler/rustc_hir_pretty/src/lib.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ impl<'a> State<'a> {
123123
self.print_bounds(":", pred.bounds);
124124
}
125125
Node::ArrayLenInfer(_) => self.word("_"),
126+
Node::UnsafeBinder(binder) => self.print_unsafe_binder(binder),
126127
Node::Synthetic => unreachable!(),
127128
Node::Err(_) => self.word("/*ERROR*/"),
128129
}
@@ -293,6 +294,9 @@ impl<'a> State<'a> {
293294
hir::TyKind::BareFn(f) => {
294295
self.print_ty_fn(f.abi, f.safety, f.decl, None, f.generic_params, f.param_names);
295296
}
297+
hir::TyKind::UnsafeBinder(unsafe_binder) => {
298+
self.print_unsafe_binder(unsafe_binder);
299+
}
296300
hir::TyKind::OpaqueDef(..) => self.word("/*impl Trait*/"),
297301
hir::TyKind::Path(ref qpath) => self.print_qpath(qpath, false),
298302
hir::TyKind::TraitObject(bounds, lifetime, syntax) => {
@@ -348,6 +352,15 @@ impl<'a> State<'a> {
348352
self.end()
349353
}
350354

355+
fn print_unsafe_binder(&mut self, unsafe_binder: &hir::UnsafeBinderTy<'_>) {
356+
self.ibox(INDENT_UNIT);
357+
self.word("unsafe");
358+
self.print_generic_params(unsafe_binder.generic_params);
359+
self.nbsp();
360+
self.print_type(unsafe_binder.inner_ty);
361+
self.end();
362+
}
363+
351364
fn print_foreign_item(&mut self, item: &hir::ForeignItem<'_>) {
352365
self.hardbreak_if_not_bol();
353366
self.maybe_print_comment(item.span.lo());

compiler/rustc_lint/src/non_local_def.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,8 @@ fn ty_has_local_parent(
440440
| TyKind::Ptr(_)
441441
| TyKind::Ref(_, _)
442442
| TyKind::BareFn(_)
443+
// FIXME(unsafe_binders): Do we want to consider this local?
444+
| TyKind::UnsafeBinder(_)
443445
| TyKind::Never
444446
| TyKind::Tup(_)
445447
| TyKind::Path(_)

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,7 @@ impl<'hir> Map<'hir> {
933933
Node::WhereBoundPredicate(pred) => pred.span,
934934
Node::ArrayLenInfer(inf) => inf.span,
935935
Node::PreciseCapturingNonLifetimeArg(param) => param.ident.span,
936+
Node::UnsafeBinder(binder) => binder.span,
936937
Node::Synthetic => unreachable!(),
937938
Node::Err(span) => span,
938939
}
@@ -1215,6 +1216,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
12151216
Node::Synthetic => unreachable!(),
12161217
Node::Err(_) => node_str("error"),
12171218
Node::PreciseCapturingNonLifetimeArg(_param) => node_str("parameter"),
1219+
Node::UnsafeBinder(_) => node_str("unsafe binder"),
12181220
}
12191221
}
12201222

compiler/rustc_passes/src/hir_stats.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
342342
Ptr,
343343
Ref,
344344
BareFn,
345+
UnsafeBinder,
345346
Never,
346347
Tup,
347348
AnonAdt,
@@ -606,6 +607,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
606607
Ptr,
607608
Ref,
608609
BareFn,
610+
UnsafeBinder,
609611
Never,
610612
Tup,
611613
AnonStruct,

compiler/rustc_resolve/src/late.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,28 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
865865
},
866866
)
867867
}
868+
TyKind::UnsafeBinder(unsafe_binder) => {
869+
// FIXME(unsafe_binder): Better span
870+
let span = ty.span;
871+
self.with_generic_param_rib(
872+
&unsafe_binder.generic_params,
873+
RibKind::Normal,
874+
LifetimeRibKind::Generics {
875+
binder: ty.id,
876+
kind: LifetimeBinderKind::BareFnType,
877+
span,
878+
},
879+
|this| {
880+
this.visit_generic_params(&unsafe_binder.generic_params, false);
881+
this.with_lifetime_rib(
882+
// We don't allow anonymous `unsafe &'_ ()` binders,
883+
// although I guess we could.
884+
LifetimeRibKind::AnonymousReportError,
885+
|this| this.visit_ty(&unsafe_binder.inner_ty),
886+
);
887+
},
888+
)
889+
}
868890
TyKind::Array(element_ty, length) => {
869891
self.visit_ty(element_ty);
870892
self.resolve_anon_const(length, AnonConstKind::ConstArg(IsRepeatExpr::No));

0 commit comments

Comments
 (0)