Lower AST and resolve lifetimes for unsafe binder types
This commit is contained in:
parent
3b1adfa94b
commit
2a9e358c72
9 changed files with 98 additions and 0 deletions
|
@ -1228,6 +1228,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
param_names: self.lower_fn_params_to_names(&f.decl),
|
param_names: self.lower_fn_params_to_names(&f.decl),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
TyKind::UnsafeBinder(f) => {
|
||||||
|
let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
|
||||||
|
hir::TyKind::UnsafeBinder(self.arena.alloc(hir::UnsafeBinderTy {
|
||||||
|
generic_params,
|
||||||
|
inner_ty: self.lower_ty(&f.inner_ty, itctx),
|
||||||
|
}))
|
||||||
|
}
|
||||||
TyKind::Never => hir::TyKind::Never,
|
TyKind::Never => hir::TyKind::Never,
|
||||||
TyKind::Tup(tys) => hir::TyKind::Tup(
|
TyKind::Tup(tys) => hir::TyKind::Tup(
|
||||||
self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))),
|
self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))),
|
||||||
|
|
|
@ -2780,6 +2780,12 @@ pub struct BareFnTy<'hir> {
|
||||||
pub param_names: &'hir [Ident],
|
pub param_names: &'hir [Ident],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||||
|
pub struct UnsafeBinderTy<'hir> {
|
||||||
|
pub generic_params: &'hir [GenericParam<'hir>],
|
||||||
|
pub inner_ty: &'hir Ty<'hir>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||||
pub struct OpaqueTy<'hir> {
|
pub struct OpaqueTy<'hir> {
|
||||||
pub hir_id: HirId,
|
pub hir_id: HirId,
|
||||||
|
@ -2878,6 +2884,8 @@ pub enum TyKind<'hir> {
|
||||||
Ref(&'hir Lifetime, MutTy<'hir>),
|
Ref(&'hir Lifetime, MutTy<'hir>),
|
||||||
/// A bare function (e.g., `fn(usize) -> bool`).
|
/// A bare function (e.g., `fn(usize) -> bool`).
|
||||||
BareFn(&'hir BareFnTy<'hir>),
|
BareFn(&'hir BareFnTy<'hir>),
|
||||||
|
/// Uwu
|
||||||
|
UnsafeBinder(&'hir UnsafeBinderTy<'hir>),
|
||||||
/// The never type (`!`).
|
/// The never type (`!`).
|
||||||
Never,
|
Never,
|
||||||
/// A tuple (`(A, B, C, D, ...)`).
|
/// A tuple (`(A, B, C, D, ...)`).
|
||||||
|
|
|
@ -886,6 +886,10 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul
|
||||||
walk_list!(visitor, visit_generic_param, function_declaration.generic_params);
|
walk_list!(visitor, visit_generic_param, function_declaration.generic_params);
|
||||||
try_visit!(visitor.visit_fn_decl(function_declaration.decl));
|
try_visit!(visitor.visit_fn_decl(function_declaration.decl));
|
||||||
}
|
}
|
||||||
|
TyKind::UnsafeBinder(ref unsafe_binder) => {
|
||||||
|
walk_list!(visitor, visit_generic_param, unsafe_binder.generic_params);
|
||||||
|
try_visit!(visitor.visit_ty(unsafe_binder.inner_ty));
|
||||||
|
}
|
||||||
TyKind::Path(ref qpath) => {
|
TyKind::Path(ref qpath) => {
|
||||||
try_visit!(visitor.visit_qpath(qpath, typ.hir_id, typ.span));
|
try_visit!(visitor.visit_qpath(qpath, typ.hir_id, typ.span));
|
||||||
}
|
}
|
||||||
|
|
|
@ -470,6 +470,12 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
|
||||||
self.outer_index.shift_out(1);
|
self.outer_index.shift_out(1);
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
hir::TyKind::UnsafeBinder(_) => {
|
||||||
|
self.outer_index.shift_in(1);
|
||||||
|
let res = intravisit::walk_ty(self, ty);
|
||||||
|
self.outer_index.shift_out(1);
|
||||||
|
res
|
||||||
|
}
|
||||||
_ => intravisit::walk_ty(self, ty),
|
_ => intravisit::walk_ty(self, ty),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -781,6 +781,36 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||||
intravisit::walk_ty(this, ty);
|
intravisit::walk_ty(this, ty);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
hir::TyKind::UnsafeBinder(binder) => {
|
||||||
|
let (mut bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) =
|
||||||
|
binder
|
||||||
|
.generic_params
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(late_bound_idx, param)| {
|
||||||
|
(
|
||||||
|
(param.def_id, ResolvedArg::late(late_bound_idx as u32, param)),
|
||||||
|
late_arg_as_bound_arg(self.tcx, param),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.unzip();
|
||||||
|
|
||||||
|
deny_non_region_late_bound(self.tcx, &mut bound_vars, "function pointer types");
|
||||||
|
|
||||||
|
self.record_late_bound_vars(ty.hir_id, binders);
|
||||||
|
let scope = Scope::Binder {
|
||||||
|
hir_id: ty.hir_id,
|
||||||
|
bound_vars,
|
||||||
|
s: self.scope,
|
||||||
|
scope_type: BinderScopeType::Normal,
|
||||||
|
where_bound_origin: None,
|
||||||
|
};
|
||||||
|
self.with(scope, |this| {
|
||||||
|
// a bare fn has no bounds, so everything
|
||||||
|
// contained within is scoped within its binder.
|
||||||
|
intravisit::walk_ty(this, ty);
|
||||||
|
});
|
||||||
|
}
|
||||||
hir::TyKind::TraitObject(bounds, lifetime, _) => {
|
hir::TyKind::TraitObject(bounds, lifetime, _) => {
|
||||||
debug!(?bounds, ?lifetime, "TraitObject");
|
debug!(?bounds, ?lifetime, "TraitObject");
|
||||||
let scope = Scope::TraitRefBoundary { s: self.scope };
|
let scope = Scope::TraitRefBoundary { s: self.scope };
|
||||||
|
|
|
@ -2312,6 +2312,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
self.lower_fn_ty(hir_ty.hir_id, bf.safety, bf.abi, bf.decl, None, Some(hir_ty)),
|
self.lower_fn_ty(hir_ty.hir_id, bf.safety, bf.abi, bf.decl, None, Some(hir_ty)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
hir::TyKind::UnsafeBinder(_binder) => {
|
||||||
|
let guar = self
|
||||||
|
.dcx()
|
||||||
|
.struct_span_err(hir_ty.span, "unsafe binders are not yet implemented")
|
||||||
|
.emit();
|
||||||
|
Ty::new_error(tcx, guar)
|
||||||
|
}
|
||||||
hir::TyKind::TraitObject(bounds, lifetime, repr) => {
|
hir::TyKind::TraitObject(bounds, lifetime, repr) => {
|
||||||
if let Some(guar) = self.prohibit_or_lint_bare_trait_object_ty(hir_ty) {
|
if let Some(guar) = self.prohibit_or_lint_bare_trait_object_ty(hir_ty) {
|
||||||
// Don't continue with type analysis if the `dyn` keyword is missing
|
// Don't continue with type analysis if the `dyn` keyword is missing
|
||||||
|
|
|
@ -288,6 +288,9 @@ impl<'a> State<'a> {
|
||||||
hir::TyKind::BareFn(f) => {
|
hir::TyKind::BareFn(f) => {
|
||||||
self.print_ty_fn(f.abi, f.safety, f.decl, None, f.generic_params, f.param_names);
|
self.print_ty_fn(f.abi, f.safety, f.decl, None, f.generic_params, f.param_names);
|
||||||
}
|
}
|
||||||
|
hir::TyKind::UnsafeBinder(unsafe_binder) => {
|
||||||
|
self.print_unsafe_binder(unsafe_binder);
|
||||||
|
}
|
||||||
hir::TyKind::OpaqueDef(..) => self.word("/*impl Trait*/"),
|
hir::TyKind::OpaqueDef(..) => self.word("/*impl Trait*/"),
|
||||||
hir::TyKind::Path(ref qpath) => self.print_qpath(qpath, false),
|
hir::TyKind::Path(ref qpath) => self.print_qpath(qpath, false),
|
||||||
hir::TyKind::TraitObject(bounds, lifetime, syntax) => {
|
hir::TyKind::TraitObject(bounds, lifetime, syntax) => {
|
||||||
|
@ -339,6 +342,15 @@ impl<'a> State<'a> {
|
||||||
self.end()
|
self.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn print_unsafe_binder(&mut self, unsafe_binder: &hir::UnsafeBinderTy<'_>) {
|
||||||
|
self.ibox(INDENT_UNIT);
|
||||||
|
self.word("unsafe");
|
||||||
|
self.print_generic_params(unsafe_binder.generic_params);
|
||||||
|
self.nbsp();
|
||||||
|
self.print_type(unsafe_binder.inner_ty);
|
||||||
|
self.end();
|
||||||
|
}
|
||||||
|
|
||||||
fn print_foreign_item(&mut self, item: &hir::ForeignItem<'_>) {
|
fn print_foreign_item(&mut self, item: &hir::ForeignItem<'_>) {
|
||||||
self.hardbreak_if_not_bol();
|
self.hardbreak_if_not_bol();
|
||||||
self.maybe_print_comment(item.span.lo());
|
self.maybe_print_comment(item.span.lo());
|
||||||
|
|
|
@ -335,6 +335,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
|
||||||
Ptr,
|
Ptr,
|
||||||
Ref,
|
Ref,
|
||||||
BareFn,
|
BareFn,
|
||||||
|
UnsafeBinder,
|
||||||
Never,
|
Never,
|
||||||
Tup,
|
Tup,
|
||||||
Path,
|
Path,
|
||||||
|
@ -585,6 +586,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
|
||||||
Ref,
|
Ref,
|
||||||
PinnedRef,
|
PinnedRef,
|
||||||
BareFn,
|
BareFn,
|
||||||
|
UnsafeBinder,
|
||||||
Never,
|
Never,
|
||||||
Tup,
|
Tup,
|
||||||
Path,
|
Path,
|
||||||
|
|
|
@ -887,6 +887,28 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
TyKind::UnsafeBinder(unsafe_binder) => {
|
||||||
|
// FIXME(unsafe_binder): Better span
|
||||||
|
let span = ty.span;
|
||||||
|
self.with_generic_param_rib(
|
||||||
|
&unsafe_binder.generic_params,
|
||||||
|
RibKind::Normal,
|
||||||
|
LifetimeRibKind::Generics {
|
||||||
|
binder: ty.id,
|
||||||
|
kind: LifetimeBinderKind::BareFnType,
|
||||||
|
span,
|
||||||
|
},
|
||||||
|
|this| {
|
||||||
|
this.visit_generic_params(&unsafe_binder.generic_params, false);
|
||||||
|
this.with_lifetime_rib(
|
||||||
|
// We don't allow anonymous `unsafe &'_ ()` binders,
|
||||||
|
// although I guess we could.
|
||||||
|
LifetimeRibKind::AnonymousReportError,
|
||||||
|
|this| this.visit_ty(&unsafe_binder.inner_ty),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
TyKind::Array(element_ty, length) => {
|
TyKind::Array(element_ty, length) => {
|
||||||
self.visit_ty(element_ty);
|
self.visit_ty(element_ty);
|
||||||
self.resolve_anon_const(length, AnonConstKind::ConstArg(IsRepeatExpr::No));
|
self.resolve_anon_const(length, AnonConstKind::ConstArg(IsRepeatExpr::No));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue