Parsing unsafe binders
This commit is contained in:
parent
8e37e15183
commit
3b1adfa94b
6 changed files with 45 additions and 1 deletions
|
@ -2223,6 +2223,12 @@ pub struct BareFnTy {
|
||||||
pub decl_span: Span,
|
pub decl_span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
|
pub struct UnsafeBinderTy {
|
||||||
|
pub generic_params: ThinVec<GenericParam>,
|
||||||
|
pub inner_ty: P<Ty>,
|
||||||
|
}
|
||||||
|
|
||||||
/// The various kinds of type recognized by the compiler.
|
/// The various kinds of type recognized by the compiler.
|
||||||
//
|
//
|
||||||
// Adding a new variant? Please update `test_ty` in `tests/ui/macros/stringify.rs`.
|
// Adding a new variant? Please update `test_ty` in `tests/ui/macros/stringify.rs`.
|
||||||
|
@ -2242,6 +2248,8 @@ pub enum TyKind {
|
||||||
PinnedRef(Option<Lifetime>, MutTy),
|
PinnedRef(Option<Lifetime>, MutTy),
|
||||||
/// A bare function (e.g., `fn(usize) -> bool`).
|
/// A bare function (e.g., `fn(usize) -> bool`).
|
||||||
BareFn(P<BareFnTy>),
|
BareFn(P<BareFnTy>),
|
||||||
|
/// An unsafe existential lifetime binder (e.g., `unsafe<'a> &'a ()`).
|
||||||
|
UnsafeBinder(P<UnsafeBinderTy>),
|
||||||
/// The never type (`!`).
|
/// The never type (`!`).
|
||||||
Never,
|
Never,
|
||||||
/// A tuple (`(A, B, C, D,...)`).
|
/// A tuple (`(A, B, C, D,...)`).
|
||||||
|
|
|
@ -558,6 +558,11 @@ pub fn walk_ty<T: MutVisitor>(vis: &mut T, ty: &mut P<Ty>) {
|
||||||
vis.visit_fn_decl(decl);
|
vis.visit_fn_decl(decl);
|
||||||
vis.visit_span(decl_span);
|
vis.visit_span(decl_span);
|
||||||
}
|
}
|
||||||
|
TyKind::UnsafeBinder(binder) => {
|
||||||
|
let UnsafeBinderTy { generic_params, inner_ty } = binder.deref_mut();
|
||||||
|
generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
|
||||||
|
vis.visit_ty(inner_ty);
|
||||||
|
}
|
||||||
TyKind::Tup(tys) => visit_thin_vec(tys, |ty| vis.visit_ty(ty)),
|
TyKind::Tup(tys) => visit_thin_vec(tys, |ty| vis.visit_ty(ty)),
|
||||||
TyKind::Paren(ty) => vis.visit_ty(ty),
|
TyKind::Paren(ty) => vis.visit_ty(ty),
|
||||||
TyKind::Pat(ty, pat) => {
|
TyKind::Pat(ty, pat) => {
|
||||||
|
|
|
@ -253,6 +253,10 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> {
|
||||||
ty = &mut_ty.ty;
|
ty = &mut_ty.ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ast::TyKind::UnsafeBinder(binder) => {
|
||||||
|
ty = &binder.inner_ty;
|
||||||
|
}
|
||||||
|
|
||||||
ast::TyKind::BareFn(fn_ty) => match &fn_ty.decl.output {
|
ast::TyKind::BareFn(fn_ty) => match &fn_ty.decl.output {
|
||||||
ast::FnRetTy::Default(_) => break None,
|
ast::FnRetTy::Default(_) => break None,
|
||||||
ast::FnRetTy::Ty(ret) => ty = ret,
|
ast::FnRetTy::Ty(ret) => ty = ret,
|
||||||
|
|
|
@ -522,6 +522,10 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result {
|
||||||
walk_list!(visitor, visit_generic_param, generic_params);
|
walk_list!(visitor, visit_generic_param, generic_params);
|
||||||
try_visit!(visitor.visit_fn_decl(decl));
|
try_visit!(visitor.visit_fn_decl(decl));
|
||||||
}
|
}
|
||||||
|
TyKind::UnsafeBinder(binder) => {
|
||||||
|
walk_list!(visitor, visit_generic_param, &binder.generic_params);
|
||||||
|
try_visit!(visitor.visit_ty(&binder.inner_ty));
|
||||||
|
}
|
||||||
TyKind::Path(maybe_qself, path) => {
|
TyKind::Path(maybe_qself, path) => {
|
||||||
try_visit!(visitor.visit_qself(maybe_qself));
|
try_visit!(visitor.visit_qself(maybe_qself));
|
||||||
try_visit!(visitor.visit_path(path, *id));
|
try_visit!(visitor.visit_path(path, *id));
|
||||||
|
|
|
@ -1198,6 +1198,14 @@ impl<'a> State<'a> {
|
||||||
ast::TyKind::BareFn(f) => {
|
ast::TyKind::BareFn(f) => {
|
||||||
self.print_ty_fn(f.ext, f.safety, &f.decl, None, &f.generic_params);
|
self.print_ty_fn(f.ext, f.safety, &f.decl, None, &f.generic_params);
|
||||||
}
|
}
|
||||||
|
ast::TyKind::UnsafeBinder(f) => {
|
||||||
|
self.ibox(INDENT_UNIT);
|
||||||
|
self.word("unsafe");
|
||||||
|
self.print_generic_params(&f.generic_params);
|
||||||
|
self.nbsp();
|
||||||
|
self.print_type(&f.inner_ty);
|
||||||
|
self.end();
|
||||||
|
}
|
||||||
ast::TyKind::Path(None, path) => {
|
ast::TyKind::Path(None, path) => {
|
||||||
self.print_path(path, false, 0);
|
self.print_path(path, false, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use rustc_ast::{
|
||||||
self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnRetTy,
|
self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnRetTy,
|
||||||
GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability,
|
GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability,
|
||||||
Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty,
|
Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty,
|
||||||
TyKind,
|
TyKind, UnsafeBinderTy,
|
||||||
};
|
};
|
||||||
use rustc_errors::{Applicability, PResult};
|
use rustc_errors::{Applicability, PResult};
|
||||||
use rustc_span::symbol::{Ident, kw, sym};
|
use rustc_span::symbol::{Ident, kw, sym};
|
||||||
|
@ -348,6 +348,8 @@ impl<'a> Parser<'a> {
|
||||||
TyKind::Err(guar)
|
TyKind::Err(guar)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if self.check_keyword(kw::Unsafe) {
|
||||||
|
self.parse_unsafe_binder_ty()?
|
||||||
} else {
|
} else {
|
||||||
let msg = format!("expected type, found {}", super::token_descr(&self.token));
|
let msg = format!("expected type, found {}", super::token_descr(&self.token));
|
||||||
let mut err = self.dcx().struct_span_err(lo, msg);
|
let mut err = self.dcx().struct_span_err(lo, msg);
|
||||||
|
@ -369,6 +371,19 @@ impl<'a> Parser<'a> {
|
||||||
if allow_qpath_recovery { self.maybe_recover_from_bad_qpath(ty) } else { Ok(ty) }
|
if allow_qpath_recovery { self.maybe_recover_from_bad_qpath(ty) } else { Ok(ty) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_unsafe_binder_ty(&mut self) -> PResult<'a, TyKind> {
|
||||||
|
let lo = self.token.span;
|
||||||
|
assert!(self.eat_keyword(kw::Unsafe));
|
||||||
|
self.expect_lt()?;
|
||||||
|
let generic_params = self.parse_generic_params()?;
|
||||||
|
self.expect_gt()?;
|
||||||
|
let inner_ty = self.parse_ty()?;
|
||||||
|
let span = lo.to(self.prev_token.span);
|
||||||
|
self.psess.gated_spans.gate(sym::unsafe_binders, span);
|
||||||
|
|
||||||
|
Ok(TyKind::UnsafeBinder(P(UnsafeBinderTy { generic_params, inner_ty })))
|
||||||
|
}
|
||||||
|
|
||||||
/// Parses either:
|
/// Parses either:
|
||||||
/// - `(TYPE)`, a parenthesized type.
|
/// - `(TYPE)`, a parenthesized type.
|
||||||
/// - `(TYPE,)`, a tuple with a single field of type TYPE.
|
/// - `(TYPE,)`, a tuple with a single field of type TYPE.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue