Skip to content

Commit 6c73b95

Browse files
author
Without Boats
committed
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 990d8aa commit 6c73b95

File tree

39 files changed

+366
-279
lines changed

39 files changed

+366
-279
lines changed

src/doc/book

Submodule book updated 110 files

src/librustc/hir/intravisit.rs

Lines changed: 3 additions & 6 deletions
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, Name, Attribute};
4645
use syntax_pos::Span;
4746
use hir::*;
@@ -55,7 +54,7 @@ use std::u32;
5554
#[derive(Copy, Clone, PartialEq, Eq)]
5655
pub enum FnKind<'a> {
5756
/// fn foo() or extern "Abi" fn foo()
58-
ItemFn(Name, &'a Generics, Unsafety, Constness, Abi, &'a Visibility, &'a [Attribute]),
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]),
@@ -466,12 +465,10 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
466465
visitor.visit_ty(typ);
467466
visitor.visit_nested_body(body);
468467
}
469-
ItemFn(ref declaration, unsafety, constness, abi, ref generics, body_id) => {
468+
ItemFn(ref declaration, header, ref generics, body_id) => {
470469
visitor.visit_fn(FnKind::ItemFn(item.name,
471470
generics,
472-
unsafety,
473-
constness,
474-
abi,
471+
header,
475472
&item.vis,
476473
&item.attrs),
477474
declaration,

src/librustc/hir/lowering.rs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2194,7 +2194,7 @@ impl<'a> LoweringContext<'a> {
21942194
let value = self.lower_body(None, |this| this.lower_expr(e));
21952195
hir::ItemConst(self.lower_ty(t, ImplTraitContext::Disallowed), value)
21962196
}
2197-
ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => {
2197+
ItemKind::Fn(ref decl, header, ref generics, ref body) => {
21982198
let fn_def_id = self.resolver.definitions().local_def_id(id);
21992199
self.with_new_scopes(|this| {
22002200
let body_id = this.lower_body(Some(decl), |this| {
@@ -2210,9 +2210,7 @@ impl<'a> LoweringContext<'a> {
22102210

22112211
hir::ItemFn(
22122212
fn_decl,
2213-
this.lower_unsafety(unsafety),
2214-
this.lower_constness(constness),
2215-
abi,
2213+
this.lower_fn_header(header),
22162214
generics,
22172215
body_id,
22182216
)
@@ -2750,9 +2748,7 @@ impl<'a> LoweringContext<'a> {
27502748
impl_trait_return_allow: bool,
27512749
) -> hir::MethodSig {
27522750
hir::MethodSig {
2753-
abi: sig.abi,
2754-
unsafety: self.lower_unsafety(sig.unsafety),
2755-
constness: self.lower_constness(sig.constness),
2751+
header: self.lower_fn_header(sig.header),
27562752
decl: self.lower_fn_decl(&sig.decl, Some(fn_def_id), impl_trait_return_allow),
27572753
}
27582754
}
@@ -2764,6 +2760,15 @@ impl<'a> LoweringContext<'a> {
27642760
}
27652761
}
27662762

2763+
fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
2764+
hir::FnHeader {
2765+
unsafety: self.lower_unsafety(h.unsafety),
2766+
asyncness: self.lower_asyncness(h.asyncness),
2767+
constness: self.lower_constness(h.constness),
2768+
abi: h.abi,
2769+
}
2770+
}
2771+
27672772
fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety {
27682773
match u {
27692774
Unsafety::Unsafe => hir::Unsafety::Unsafe,
@@ -2778,6 +2783,13 @@ impl<'a> LoweringContext<'a> {
27782783
}
27792784
}
27802785

2786+
fn lower_asyncness(&mut self, a: IsAsync) -> hir::IsAsync {
2787+
match a {
2788+
IsAsync::Async => hir::IsAsync::Async,
2789+
IsAsync::NotAsync => hir::IsAsync::NotAsync,
2790+
}
2791+
}
2792+
27812793
fn lower_unop(&mut self, u: UnOp) -> hir::UnOp {
27822794
match u {
27832795
UnOp::Deref => hir::UnDeref,

src/librustc/hir/map/blocks.rs

Lines changed: 17 additions & 22 deletions
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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ impl<'hir> MapEntry<'hir> {
176176
match item.node {
177177
ItemConst(_, body) |
178178
ItemStatic(.., body) |
179-
ItemFn(_, _, _, _, _, body) => Some(body),
179+
ItemFn(_, _, _, body) => Some(body),
180180
_ => None,
181181
}
182182
}

src/librustc/hir/mod.rs

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1558,9 +1558,7 @@ pub struct MutTy {
15581558
/// Represents a method's signature in a trait declaration or implementation.
15591559
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
15601560
pub struct MethodSig {
1561-
pub unsafety: Unsafety,
1562-
pub constness: Constness,
1563-
pub abi: Abi,
1561+
pub header: FnHeader,
15641562
pub decl: P<FnDecl>,
15651563
}
15661564

@@ -1787,7 +1785,13 @@ pub enum IsAuto {
17871785
No
17881786
}
17891787

1790-
#[derive(Copy, Clone, PartialEq, Eq,PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
1788+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
1789+
pub enum IsAsync {
1790+
Async,
1791+
NotAsync,
1792+
}
1793+
1794+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
17911795
pub enum Unsafety {
17921796
Unsafe,
17931797
Normal,
@@ -2063,6 +2067,25 @@ pub struct Item {
20632067
pub span: Span,
20642068
}
20652069

2070+
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
2071+
pub struct FnHeader {
2072+
pub unsafety: Unsafety,
2073+
pub constness: Constness,
2074+
pub asyncness: IsAsync,
2075+
pub abi: Abi,
2076+
}
2077+
2078+
impl Default for FnHeader {
2079+
fn default() -> FnHeader {
2080+
FnHeader {
2081+
unsafety: Unsafety::Normal,
2082+
constness: Constness::NotConst,
2083+
asyncness: IsAsync::NotAsync,
2084+
abi: Abi::Rust,
2085+
}
2086+
}
2087+
}
2088+
20662089
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
20672090
pub enum Item_ {
20682091
/// An `extern crate` item, with optional *original* crate name if the crate was renamed.
@@ -2082,7 +2105,7 @@ pub enum Item_ {
20822105
/// A `const` item
20832106
ItemConst(P<Ty>, BodyId),
20842107
/// A function declaration
2085-
ItemFn(P<FnDecl>, Unsafety, Constness, Abi, Generics, BodyId),
2108+
ItemFn(P<FnDecl>, FnHeader, Generics, BodyId),
20862109
/// A module
20872110
ItemMod(Mod),
20882111
/// An external module
@@ -2144,7 +2167,7 @@ impl Item_ {
21442167

21452168
pub fn generics(&self) -> Option<&Generics> {
21462169
Some(match *self {
2147-
ItemFn(_, _, _, _, ref generics, _) |
2170+
ItemFn(_, _, ref generics, _) |
21482171
ItemTy(_, ref generics) |
21492172
ItemEnum(_, ref generics) |
21502173
ItemStruct(_, ref generics) |

src/librustc/hir/print.rs

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -446,9 +446,7 @@ impl<'a> State<'a> {
446446
hir::ForeignItemFn(ref decl, ref arg_names, ref generics) => {
447447
self.head("")?;
448448
self.print_fn(decl,
449-
hir::Unsafety::Normal,
450-
hir::Constness::NotConst,
451-
Abi::Rust,
449+
hir::FnHeader::default(),
452450
Some(item.name),
453451
generics,
454452
&item.vis,
@@ -585,12 +583,10 @@ impl<'a> State<'a> {
585583
self.s.word(";")?;
586584
self.end()?; // end the outer cbox
587585
}
588-
hir::ItemFn(ref decl, unsafety, constness, abi, ref typarams, body) => {
586+
hir::ItemFn(ref decl, header, ref typarams, body) => {
589587
self.head("")?;
590588
self.print_fn(decl,
591-
unsafety,
592-
constness,
593-
abi,
589+
header,
594590
Some(item.name),
595591
typarams,
596592
&item.vis,
@@ -887,9 +883,7 @@ impl<'a> State<'a> {
887883
body_id: Option<hir::BodyId>)
888884
-> io::Result<()> {
889885
self.print_fn(&m.decl,
890-
m.unsafety,
891-
m.constness,
892-
m.abi,
886+
m.header,
893887
Some(name),
894888
generics,
895889
vis,
@@ -1924,16 +1918,14 @@ impl<'a> State<'a> {
19241918

19251919
pub fn print_fn(&mut self,
19261920
decl: &hir::FnDecl,
1927-
unsafety: hir::Unsafety,
1928-
constness: hir::Constness,
1929-
abi: Abi,
1921+
header: hir::FnHeader,
19301922
name: Option<ast::Name>,
19311923
generics: &hir::Generics,
19321924
vis: &hir::Visibility,
19331925
arg_names: &[Spanned<ast::Name>],
19341926
body_id: Option<hir::BodyId>)
19351927
-> io::Result<()> {
1936-
self.print_fn_header_info(unsafety, constness, abi, vis)?;
1928+
self.print_fn_header_info(header, vis)?;
19371929

19381930
if let Some(name) = name {
19391931
self.nbsp()?;
@@ -2189,9 +2181,10 @@ impl<'a> State<'a> {
21892181
span: syntax_pos::DUMMY_SP,
21902182
};
21912183
self.print_fn(decl,
2192-
unsafety,
2193-
hir::Constness::NotConst,
2194-
abi,
2184+
hir::FnHeader {
2185+
unsafety, abi,
2186+
..hir::FnHeader::default()
2187+
},
21952188
name,
21962189
&generics,
21972190
&hir::Inherited,
@@ -2262,22 +2255,26 @@ impl<'a> State<'a> {
22622255
}
22632256

22642257
pub fn print_fn_header_info(&mut self,
2265-
unsafety: hir::Unsafety,
2266-
constness: hir::Constness,
2267-
abi: Abi,
2258+
header: hir::FnHeader,
22682259
vis: &hir::Visibility)
22692260
-> io::Result<()> {
22702261
self.s.word(&visibility_qualified(vis, ""))?;
2271-
self.print_unsafety(unsafety)?;
22722262

2273-
match constness {
2263+
match header.constness {
22742264
hir::Constness::NotConst => {}
22752265
hir::Constness::Const => self.word_nbsp("const")?,
22762266
}
22772267

2278-
if abi != Abi::Rust {
2268+
match header.asyncness {
2269+
hir::IsAsync::NotAsync => {}
2270+
hir::IsAsync::Async => self.word_nbsp("async")?,
2271+
}
2272+
2273+
self.print_unsafety(header.unsafety)?;
2274+
2275+
if header.abi != Abi::Rust {
22792276
self.word_nbsp("extern")?;
2280-
self.word_nbsp(&abi.to_string())?;
2277+
self.word_nbsp(&header.abi.to_string())?;
22812278
}
22822279

22832280
self.s.word("fn")

0 commit comments

Comments
 (0)