Skip to content

Commit 888211f

Browse files
Lower AST and resolve lifetimes for unsafe binder type
1 parent 9bdba7b commit 888211f

File tree

13 files changed

+114
-0
lines changed

13 files changed

+114
-0
lines changed

compiler/rustc_ast_lowering/src/index.rs

+6
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

+9
Original file line numberDiff line numberDiff line change
@@ -1332,6 +1332,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
13321332
param_names: self.lower_fn_params_to_names(&f.decl),
13331333
}))
13341334
}
1335+
TyKind::UnsafeBinder(f) => {
1336+
let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1337+
hir::TyKind::UnsafeBinder(self.arena.alloc(hir::UnsafeBinderTy {
1338+
span: self.lower_span(t.span),
1339+
hir_id: self.next_id(),
1340+
generic_params,
1341+
inner_ty: self.lower_ty(&f.inner_ty, itctx),
1342+
}))
1343+
}
13351344
TyKind::Never => hir::TyKind::Never,
13361345
TyKind::Tup(tys) => hir::TyKind::Tup(
13371346
self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))),

compiler/rustc_ast_lowering/src/lifetime_collector.rs

+5
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

+12
Original file line numberDiff line numberDiff line change
@@ -2747,6 +2747,14 @@ pub struct BareFnTy<'hir> {
27472747
pub param_names: &'hir [Ident],
27482748
}
27492749

2750+
#[derive(Debug, Clone, Copy, HashStable_Generic)]
2751+
pub struct UnsafeBinderTy<'hir> {
2752+
pub hir_id: HirId,
2753+
pub span: Span,
2754+
pub generic_params: &'hir [GenericParam<'hir>],
2755+
pub inner_ty: &'hir Ty<'hir>,
2756+
}
2757+
27502758
#[derive(Debug, Clone, Copy, HashStable_Generic)]
27512759
pub struct OpaqueTy<'hir> {
27522760
pub generics: &'hir Generics<'hir>,
@@ -2839,6 +2847,8 @@ pub enum TyKind<'hir> {
28392847
Ref(&'hir Lifetime, MutTy<'hir>),
28402848
/// A bare function (e.g., `fn(usize) -> bool`).
28412849
BareFn(&'hir BareFnTy<'hir>),
2850+
/// Uwu
2851+
UnsafeBinder(&'hir UnsafeBinderTy<'hir>),
28422852
/// The never type (`!`).
28432853
Never,
28442854
/// A tuple (`(A, B, C, D, ...)`).
@@ -3810,6 +3820,7 @@ pub enum Node<'hir> {
38103820
// FIXME: Merge into `Node::Infer`.
38113821
ArrayLenInfer(&'hir InferArg),
38123822
PreciseCapturingNonLifetimeArg(&'hir PreciseCapturingNonLifetimeArg),
3823+
UnsafeBinder(&'hir UnsafeBinderTy<'hir>),
38133824
// Created by query feeding
38143825
Synthetic,
38153826
Err(Span),
@@ -3862,6 +3873,7 @@ impl<'hir> Node<'hir> {
38623873
| Node::Infer(..)
38633874
| Node::WhereBoundPredicate(..)
38643875
| Node::ArrayLenInfer(..)
3876+
| Node::UnsafeBinder(..)
38653877
| Node::Synthetic
38663878
| Node::Err(..) => None,
38673879
}

compiler/rustc_hir/src/intravisit.rs

+5
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

+6
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

+29
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

+1
Original file line numberDiff line numberDiff line change
@@ -2062,6 +2062,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
20622062
self.lower_fn_ty(hir_ty.hir_id, bf.safety, bf.abi, bf.decl, None, Some(hir_ty)),
20632063
)
20642064
}
2065+
hir::TyKind::UnsafeBinder(_binder) => todo!(),
20652066
hir::TyKind::TraitObject(bounds, lifetime, repr) => {
20662067
self.prohibit_or_lint_bare_trait_object_ty(hir_ty);
20672068

compiler/rustc_hir_pretty/src/lib.rs

+13
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

+2
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,8 @@ fn ty_has_local_parent(
436436
| TyKind::Ptr(_)
437437
| TyKind::Ref(_, _)
438438
| TyKind::BareFn(_)
439+
// FIXME(unsafe_binders): Do we want to consider this local?
440+
| TyKind::UnsafeBinder(_)
439441
| TyKind::Never
440442
| TyKind::Tup(_)
441443
| TyKind::Path(_)

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

+2
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

+2
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
329329
Ptr,
330330
Ref,
331331
BareFn,
332+
UnsafeBinder,
332333
Never,
333334
Tup,
334335
AnonAdt,
@@ -581,6 +582,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
581582
Ptr,
582583
Ref,
583584
BareFn,
585+
UnsafeBinder,
584586
Never,
585587
Tup,
586588
AnonStruct,

compiler/rustc_resolve/src/late.rs

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

0 commit comments

Comments
 (0)