Skip to content

Commit 18ff7d0

Browse files
Without Boatscramertj
Without Boats
authored andcommitted
Parse async fn header.
This is gated on edition 2018 & the `async_await` feature gate. The parser will accept `async fn` and `async unsafe fn` as fn items. Along the same lines as `const fn`, only `async unsafe fn` is permitted, not `unsafe async fn`.The parser will not accept `async` functions as trait methods. To do a little code clean up, four fields of the function type struct have been merged into the new `FnHeader` struct: constness, asyncness, unsafety, and ABI. Also, a small bug in HIR printing is fixed: it previously printed `const unsafe fn` as `unsafe const fn`, which is grammatically incorrect.
1 parent 4b17d31 commit 18ff7d0

File tree

33 files changed

+367
-288
lines changed

33 files changed

+367
-288
lines changed

src/librustc/hir/intravisit.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
//! This order consistency is required in a few places in rustc, for
4242
//! example generator inference, and possibly also HIR borrowck.
4343
44-
use rustc_target::spec::abi::Abi;
4544
use syntax::ast::{NodeId, CRATE_NODE_ID, Ident, Name, Attribute};
4645
use syntax_pos::Span;
4746
use hir::*;
@@ -54,8 +53,8 @@ use std::u32;
5453

5554
#[derive(Copy, Clone, PartialEq, Eq)]
5655
pub enum FnKind<'a> {
57-
/// fn foo() or extern "Abi" fn foo()
58-
ItemFn(Name, &'a Generics, Unsafety, Constness, Abi, &'a Visibility, &'a [Attribute]),
56+
/// #[xxx] pub async/const/extern "Abi" fn foo()
57+
ItemFn(Name, &'a Generics, FnHeader, &'a Visibility, &'a [Attribute]),
5958

6059
/// fn foo(&self)
6160
Method(Name, &'a MethodSig, Option<&'a Visibility>, &'a [Attribute]),
@@ -479,12 +478,10 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
479478
visitor.visit_ty(typ);
480479
visitor.visit_nested_body(body);
481480
}
482-
ItemFn(ref declaration, unsafety, constness, abi, ref generics, body_id) => {
481+
ItemFn(ref declaration, header, ref generics, body_id) => {
483482
visitor.visit_fn(FnKind::ItemFn(item.name,
484483
generics,
485-
unsafety,
486-
constness,
487-
abi,
484+
header,
488485
&item.vis,
489486
&item.attrs),
490487
declaration,

src/librustc/hir/lowering.rs

+19-7
Original file line numberDiff line numberDiff line change
@@ -2284,7 +2284,7 @@ impl<'a> LoweringContext<'a> {
22842284
let value = self.lower_body(None, |this| this.lower_expr(e));
22852285
hir::ItemConst(self.lower_ty(t, ImplTraitContext::Disallowed), value)
22862286
}
2287-
ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => {
2287+
ItemKind::Fn(ref decl, header, ref generics, ref body) => {
22882288
let fn_def_id = self.resolver.definitions().local_def_id(id);
22892289
self.with_new_scopes(|this| {
22902290
let body_id = this.lower_body(Some(decl), |this| {
@@ -2300,9 +2300,7 @@ impl<'a> LoweringContext<'a> {
23002300

23012301
hir::ItemFn(
23022302
fn_decl,
2303-
this.lower_unsafety(unsafety),
2304-
this.lower_constness(constness),
2305-
abi,
2303+
this.lower_fn_header(header),
23062304
generics,
23072305
body_id,
23082306
)
@@ -2891,9 +2889,7 @@ impl<'a> LoweringContext<'a> {
28912889
impl_trait_return_allow: bool,
28922890
) -> hir::MethodSig {
28932891
hir::MethodSig {
2894-
abi: sig.abi,
2895-
unsafety: self.lower_unsafety(sig.unsafety),
2896-
constness: self.lower_constness(sig.constness),
2892+
header: self.lower_fn_header(sig.header),
28972893
decl: self.lower_fn_decl(&sig.decl, Some(fn_def_id), impl_trait_return_allow),
28982894
}
28992895
}
@@ -2905,6 +2901,15 @@ impl<'a> LoweringContext<'a> {
29052901
}
29062902
}
29072903

2904+
fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
2905+
hir::FnHeader {
2906+
unsafety: self.lower_unsafety(h.unsafety),
2907+
asyncness: self.lower_asyncness(h.asyncness),
2908+
constness: self.lower_constness(h.constness),
2909+
abi: h.abi,
2910+
}
2911+
}
2912+
29082913
fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety {
29092914
match u {
29102915
Unsafety::Unsafe => hir::Unsafety::Unsafe,
@@ -2919,6 +2924,13 @@ impl<'a> LoweringContext<'a> {
29192924
}
29202925
}
29212926

2927+
fn lower_asyncness(&mut self, a: IsAsync) -> hir::IsAsync {
2928+
match a {
2929+
IsAsync::Async => hir::IsAsync::Async,
2930+
IsAsync::NotAsync => hir::IsAsync::NotAsync,
2931+
}
2932+
}
2933+
29222934
fn lower_unop(&mut self, u: UnOp) -> hir::UnOp {
29232935
match u {
29242936
UnOp::Deref => hir::UnDeref,

src/librustc/hir/map/blocks.rs

+17-22
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ use hir as ast;
2525
use hir::map::{self, Node};
2626
use hir::{Expr, FnDecl};
2727
use hir::intravisit::FnKind;
28-
use rustc_target::spec::abi;
2928
use syntax::ast::{Attribute, Name, NodeId};
3029
use syntax_pos::Span;
3130

@@ -105,9 +104,7 @@ impl<'a> Code<'a> {
105104
struct ItemFnParts<'a> {
106105
name: Name,
107106
decl: &'a ast::FnDecl,
108-
unsafety: ast::Unsafety,
109-
constness: ast::Constness,
110-
abi: abi::Abi,
107+
header: ast::FnHeader,
111108
vis: &'a ast::Visibility,
112109
generics: &'a ast::Generics,
113110
body: ast::BodyId,
@@ -183,31 +180,31 @@ impl<'a> FnLikeNode<'a> {
183180

184181
pub fn constness(self) -> ast::Constness {
185182
match self.kind() {
186-
FnKind::ItemFn(_, _, _, constness, ..) => {
187-
constness
188-
}
189-
FnKind::Method(_, m, ..) => {
190-
m.constness
191-
}
183+
FnKind::ItemFn(_, _, header, ..) => header.constness,
184+
FnKind::Method(_, m, ..) => m.header.constness,
192185
_ => ast::Constness::NotConst
193186
}
194187
}
195188

189+
pub fn asyncness(self) -> ast::IsAsync {
190+
match self.kind() {
191+
FnKind::ItemFn(_, _, header, ..) => header.asyncness,
192+
FnKind::Method(_, m, ..) => m.header.asyncness,
193+
_ => ast::IsAsync::NotAsync
194+
}
195+
}
196+
196197
pub fn unsafety(self) -> ast::Unsafety {
197198
match self.kind() {
198-
FnKind::ItemFn(_, _, unsafety, ..) => {
199-
unsafety
200-
}
201-
FnKind::Method(_, m, ..) => {
202-
m.unsafety
203-
}
199+
FnKind::ItemFn(_, _, header, ..) => header.unsafety,
200+
FnKind::Method(_, m, ..) => m.header.unsafety,
204201
_ => ast::Unsafety::Normal
205202
}
206203
}
207204

208205
pub fn kind(self) -> FnKind<'a> {
209206
let item = |p: ItemFnParts<'a>| -> FnKind<'a> {
210-
FnKind::ItemFn(p.name, p.generics, p.unsafety, p.constness, p.abi, p.vis, p.attrs)
207+
FnKind::ItemFn(p.name, p.generics, p.header, p.vis, p.attrs)
211208
};
212209
let closure = |c: ClosureParts<'a>| {
213210
FnKind::Closure(c.attrs)
@@ -232,19 +229,17 @@ impl<'a> FnLikeNode<'a> {
232229
{
233230
match self.node {
234231
map::NodeItem(i) => match i.node {
235-
ast::ItemFn(ref decl, unsafety, constness, abi, ref generics, block) =>
232+
ast::ItemFn(ref decl, header, ref generics, block) =>
236233
item_fn(ItemFnParts {
237234
id: i.id,
238235
name: i.name,
239236
decl: &decl,
240-
unsafety,
241237
body: block,
242-
generics,
243-
abi,
244238
vis: &i.vis,
245-
constness,
246239
span: i.span,
247240
attrs: &i.attrs,
241+
header,
242+
generics,
248243
}),
249244
_ => bug!("item FnLikeNode that is not fn-like"),
250245
},

src/librustc/hir/map/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ impl<'hir> MapEntry<'hir> {
210210
match item.node {
211211
ItemConst(_, body) |
212212
ItemStatic(.., body) |
213-
ItemFn(_, _, _, _, _, body) => Some(body),
213+
ItemFn(_, _, _, body) => Some(body),
214214
_ => None,
215215
}
216216
}

src/librustc/hir/mod.rs

+29-6
Original file line numberDiff line numberDiff line change
@@ -1506,9 +1506,7 @@ pub struct MutTy {
15061506
/// Represents a method's signature in a trait declaration or implementation.
15071507
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
15081508
pub struct MethodSig {
1509-
pub unsafety: Unsafety,
1510-
pub constness: Constness,
1511-
pub abi: Abi,
1509+
pub header: FnHeader,
15121510
pub decl: P<FnDecl>,
15131511
}
15141512

@@ -1736,7 +1734,13 @@ pub enum IsAuto {
17361734
No
17371735
}
17381736

1739-
#[derive(Copy, Clone, PartialEq, Eq,PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
1737+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
1738+
pub enum IsAsync {
1739+
Async,
1740+
NotAsync,
1741+
}
1742+
1743+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
17401744
pub enum Unsafety {
17411745
Unsafe,
17421746
Normal,
@@ -2012,6 +2016,25 @@ pub struct Item {
20122016
pub span: Span,
20132017
}
20142018

2019+
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
2020+
pub struct FnHeader {
2021+
pub unsafety: Unsafety,
2022+
pub constness: Constness,
2023+
pub asyncness: IsAsync,
2024+
pub abi: Abi,
2025+
}
2026+
2027+
impl Default for FnHeader {
2028+
fn default() -> FnHeader {
2029+
FnHeader {
2030+
unsafety: Unsafety::Normal,
2031+
constness: Constness::NotConst,
2032+
asyncness: IsAsync::NotAsync,
2033+
abi: Abi::Rust,
2034+
}
2035+
}
2036+
}
2037+
20152038
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
20162039
pub enum Item_ {
20172040
/// An `extern crate` item, with optional *original* crate name if the crate was renamed.
@@ -2031,7 +2054,7 @@ pub enum Item_ {
20312054
/// A `const` item
20322055
ItemConst(P<Ty>, BodyId),
20332056
/// A function declaration
2034-
ItemFn(P<FnDecl>, Unsafety, Constness, Abi, Generics, BodyId),
2057+
ItemFn(P<FnDecl>, FnHeader, Generics, BodyId),
20352058
/// A module
20362059
ItemMod(Mod),
20372060
/// An external module
@@ -2096,7 +2119,7 @@ impl Item_ {
20962119

20972120
pub fn generics(&self) -> Option<&Generics> {
20982121
Some(match *self {
2099-
ItemFn(_, _, _, _, ref generics, _) |
2122+
ItemFn(_, _, ref generics, _) |
21002123
ItemTy(_, ref generics) |
21012124
ItemEnum(_, ref generics) |
21022125
ItemStruct(_, ref generics) |

src/librustc/hir/print.rs

+21-24
Original file line numberDiff line numberDiff line change
@@ -459,9 +459,7 @@ impl<'a> State<'a> {
459459
hir::ForeignItemFn(ref decl, ref arg_names, ref generics) => {
460460
self.head("")?;
461461
self.print_fn(decl,
462-
hir::Unsafety::Normal,
463-
hir::Constness::NotConst,
464-
Abi::Rust,
462+
hir::FnHeader::default(),
465463
Some(item.name),
466464
generics,
467465
&item.vis,
@@ -598,12 +596,10 @@ impl<'a> State<'a> {
598596
self.s.word(";")?;
599597
self.end()?; // end the outer cbox
600598
}
601-
hir::ItemFn(ref decl, unsafety, constness, abi, ref typarams, body) => {
599+
hir::ItemFn(ref decl, header, ref typarams, body) => {
602600
self.head("")?;
603601
self.print_fn(decl,
604-
unsafety,
605-
constness,
606-
abi,
602+
header,
607603
Some(item.name),
608604
typarams,
609605
&item.vis,
@@ -935,9 +931,7 @@ impl<'a> State<'a> {
935931
body_id: Option<hir::BodyId>)
936932
-> io::Result<()> {
937933
self.print_fn(&m.decl,
938-
m.unsafety,
939-
m.constness,
940-
m.abi,
934+
m.header,
941935
Some(name),
942936
generics,
943937
vis,
@@ -1986,16 +1980,14 @@ impl<'a> State<'a> {
19861980

19871981
pub fn print_fn(&mut self,
19881982
decl: &hir::FnDecl,
1989-
unsafety: hir::Unsafety,
1990-
constness: hir::Constness,
1991-
abi: Abi,
1983+
header: hir::FnHeader,
19921984
name: Option<ast::Name>,
19931985
generics: &hir::Generics,
19941986
vis: &hir::Visibility,
19951987
arg_names: &[Spanned<ast::Name>],
19961988
body_id: Option<hir::BodyId>)
19971989
-> io::Result<()> {
1998-
self.print_fn_header_info(unsafety, constness, abi, vis)?;
1990+
self.print_fn_header_info(header, vis)?;
19991991

20001992
if let Some(name) = name {
20011993
self.nbsp()?;
@@ -2260,9 +2252,10 @@ impl<'a> State<'a> {
22602252
span: syntax_pos::DUMMY_SP,
22612253
};
22622254
self.print_fn(decl,
2263-
unsafety,
2264-
hir::Constness::NotConst,
2265-
abi,
2255+
hir::FnHeader {
2256+
unsafety, abi,
2257+
..hir::FnHeader::default()
2258+
},
22662259
name,
22672260
&generics,
22682261
&hir::Inherited,
@@ -2333,22 +2326,26 @@ impl<'a> State<'a> {
23332326
}
23342327

23352328
pub fn print_fn_header_info(&mut self,
2336-
unsafety: hir::Unsafety,
2337-
constness: hir::Constness,
2338-
abi: Abi,
2329+
header: hir::FnHeader,
23392330
vis: &hir::Visibility)
23402331
-> io::Result<()> {
23412332
self.s.word(&visibility_qualified(vis, ""))?;
2342-
self.print_unsafety(unsafety)?;
23432333

2344-
match constness {
2334+
match header.constness {
23452335
hir::Constness::NotConst => {}
23462336
hir::Constness::Const => self.word_nbsp("const")?,
23472337
}
23482338

2349-
if abi != Abi::Rust {
2339+
match header.asyncness {
2340+
hir::IsAsync::NotAsync => {}
2341+
hir::IsAsync::Async => self.word_nbsp("async")?,
2342+
}
2343+
2344+
self.print_unsafety(header.unsafety)?;
2345+
2346+
if header.abi != Abi::Rust {
23502347
self.word_nbsp("extern")?;
2351-
self.word_nbsp(&abi.to_string())?;
2348+
self.word_nbsp(&header.abi.to_string())?;
23522349
}
23532350

23542351
self.s.word("fn")

0 commit comments

Comments
 (0)