Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

async/await #51580

Merged
merged 19 commits into from
Jun 23, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/librustc/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2131,5 +2131,10 @@ register_diagnostics! {
E0657, // `impl Trait` can only capture lifetimes bound at the fn level
E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax
E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
E0697, // closures cannot be static

E0906, // closures cannot be static

E0725, // multiple different lifetimes used in arguments of `async fn`
E0726, // multiple elided lifetimes used in arguments of `async fn`
E0727, // `async` non-`move` closures with arguments are not currently supported
}
11 changes: 4 additions & 7 deletions src/librustc/hir/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
//! This order consistency is required in a few places in rustc, for
//! example generator inference, and possibly also HIR borrowck.

use rustc_target::spec::abi::Abi;
use syntax::ast::{NodeId, CRATE_NODE_ID, Ident, Name, Attribute};
use syntax_pos::Span;
use hir::*;
Expand All @@ -54,8 +53,8 @@ use std::u32;

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

/// fn foo(&self)
Method(Name, &'a MethodSig, Option<&'a Visibility>, &'a [Attribute]),
Expand Down Expand Up @@ -479,12 +478,10 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
visitor.visit_ty(typ);
visitor.visit_nested_body(body);
}
ItemFn(ref declaration, unsafety, constness, abi, ref generics, body_id) => {
ItemFn(ref declaration, header, ref generics, body_id) => {
visitor.visit_fn(FnKind::ItemFn(item.name,
generics,
unsafety,
constness,
abi,
header,
&item.vis,
&item.attrs),
declaration,
Expand Down
734 changes: 562 additions & 172 deletions src/librustc/hir/lowering.rs

Large diffs are not rendered by default.

39 changes: 17 additions & 22 deletions src/librustc/hir/map/blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ use hir as ast;
use hir::map::{self, Node};
use hir::{Expr, FnDecl};
use hir::intravisit::FnKind;
use rustc_target::spec::abi;
use syntax::ast::{Attribute, Name, NodeId};
use syntax_pos::Span;

Expand Down Expand Up @@ -105,9 +104,7 @@ impl<'a> Code<'a> {
struct ItemFnParts<'a> {
name: Name,
decl: &'a ast::FnDecl,
unsafety: ast::Unsafety,
constness: ast::Constness,
abi: abi::Abi,
header: ast::FnHeader,
vis: &'a ast::Visibility,
generics: &'a ast::Generics,
body: ast::BodyId,
Expand Down Expand Up @@ -183,31 +180,31 @@ impl<'a> FnLikeNode<'a> {

pub fn constness(self) -> ast::Constness {
match self.kind() {
FnKind::ItemFn(_, _, _, constness, ..) => {
constness
}
FnKind::Method(_, m, ..) => {
m.constness
}
FnKind::ItemFn(_, _, header, ..) => header.constness,
FnKind::Method(_, m, ..) => m.header.constness,
_ => ast::Constness::NotConst
}
}

pub fn asyncness(self) -> ast::IsAsync {
match self.kind() {
FnKind::ItemFn(_, _, header, ..) => header.asyncness,
FnKind::Method(_, m, ..) => m.header.asyncness,
_ => ast::IsAsync::NotAsync
}
}

pub fn unsafety(self) -> ast::Unsafety {
match self.kind() {
FnKind::ItemFn(_, _, unsafety, ..) => {
unsafety
}
FnKind::Method(_, m, ..) => {
m.unsafety
}
FnKind::ItemFn(_, _, header, ..) => header.unsafety,
FnKind::Method(_, m, ..) => m.header.unsafety,
_ => ast::Unsafety::Normal
}
}

pub fn kind(self) -> FnKind<'a> {
let item = |p: ItemFnParts<'a>| -> FnKind<'a> {
FnKind::ItemFn(p.name, p.generics, p.unsafety, p.constness, p.abi, p.vis, p.attrs)
FnKind::ItemFn(p.name, p.generics, p.header, p.vis, p.attrs)
};
let closure = |c: ClosureParts<'a>| {
FnKind::Closure(c.attrs)
Expand All @@ -232,19 +229,17 @@ impl<'a> FnLikeNode<'a> {
{
match self.node {
map::NodeItem(i) => match i.node {
ast::ItemFn(ref decl, unsafety, constness, abi, ref generics, block) =>
ast::ItemFn(ref decl, header, ref generics, block) =>
item_fn(ItemFnParts {
id: i.id,
name: i.name,
decl: &decl,
unsafety,
body: block,
generics,
abi,
vis: &i.vis,
constness,
span: i.span,
attrs: &i.attrs,
header,
generics,
}),
_ => bug!("item FnLikeNode that is not fn-like"),
},
Expand Down
66 changes: 62 additions & 4 deletions src/librustc/hir/map/def_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,27 @@ impl<'a> DefCollector<'a> {
self.parent_def = parent;
}

fn visit_async_fn(
&mut self,
id: NodeId,
async_node_id: NodeId,
name: Name,
span: Span,
visit_fn: impl FnOnce(&mut DefCollector<'a>)
) {
// For async functions, we need to create their inner defs inside of a
// closure to match their desugared representation.
let fn_def_data = DefPathData::ValueNs(name.as_interned_str());
let fn_def = self.create_def(id, fn_def_data, ITEM_LIKE_SPACE, span);
return self.with_parent(fn_def, |this| {
let closure_def = this.create_def(async_node_id,
DefPathData::ClosureExpr,
REGULAR_SPACE,
span);
this.with_parent(closure_def, visit_fn)
})
}

fn visit_macro_invoc(&mut self, id: NodeId) {
if let Some(ref mut visit) = self.visit_macro_invoc {
visit(MacroInvocationData {
Expand All @@ -99,6 +120,15 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
ItemKind::Mod(..) if i.ident == keywords::Invalid.ident() => {
return visit::walk_item(self, i);
}
ItemKind::Fn(_, FnHeader { asyncness: IsAsync::Async(async_node_id), .. }, ..) => {
return self.visit_async_fn(
i.id,
async_node_id,
i.ident.name,
i.span,
|this| visit::walk_item(this, i)
)
}
ItemKind::Mod(..) => DefPathData::Module(i.ident.name.as_interned_str()),
ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) =>
DefPathData::ValueNs(i.ident.name.as_interned_str()),
Expand Down Expand Up @@ -197,6 +227,17 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {

fn visit_impl_item(&mut self, ii: &'a ImplItem) {
let def_data = match ii.node {
ImplItemKind::Method(MethodSig {
header: FnHeader { asyncness: IsAsync::Async(async_node_id), .. }, ..
}, ..) => {
return self.visit_async_fn(
ii.id,
async_node_id,
ii.ident.name,
ii.span,
|this| visit::walk_impl_item(this, ii)
)
}
ImplItemKind::Method(..) | ImplItemKind::Const(..) =>
DefPathData::ValueNs(ii.ident.name.as_interned_str()),
ImplItemKind::Type(..) => DefPathData::AssocTypeInImpl(ii.ident.name.as_interned_str()),
Expand Down Expand Up @@ -227,15 +268,32 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {

match expr.node {
ExprKind::Mac(..) => return self.visit_macro_invoc(expr.id),
ExprKind::Closure(..) => {
let def = self.create_def(expr.id,
ExprKind::Closure(_, asyncness, ..) => {
let closure_def = self.create_def(expr.id,
DefPathData::ClosureExpr,
REGULAR_SPACE,
expr.span);
self.parent_def = Some(def);
self.parent_def = Some(closure_def);

// Async closures desugar to closures inside of closures, so
// we must create two defs.
if let IsAsync::Async(async_id) = asyncness {
let async_def = self.create_def(async_id,
DefPathData::ClosureExpr,
REGULAR_SPACE,
expr.span);
self.parent_def = Some(async_def);
}
}
ExprKind::Async(_, async_id, _) => {
let async_def = self.create_def(async_id,
DefPathData::ClosureExpr,
REGULAR_SPACE,
expr.span);
self.parent_def = Some(async_def);
}
_ => {}
}
};

visit::walk_expr(self, expr);
self.parent_def = parent_def;
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ impl<'hir> MapEntry<'hir> {
match self {
EntryItem(_, _, ref item) => {
match item.node {
ItemFn(ref fn_decl, _, _, _, _, _) => Some(&fn_decl),
ItemFn(ref fn_decl, _, _, _) => Some(&fn_decl),
_ => None,
}
}
Expand Down Expand Up @@ -210,7 +210,7 @@ impl<'hir> MapEntry<'hir> {
match item.node {
ItemConst(_, body) |
ItemStatic(.., body) |
ItemFn(_, _, _, _, _, body) => Some(body),
ItemFn(_, _, _, body) => Some(body),
_ => None,
}
}
Expand Down
26 changes: 19 additions & 7 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ impl LifetimeName {
}
}

fn is_elided(&self) -> bool {
pub fn is_elided(&self) -> bool {
use self::LifetimeName::*;
match self {
Implicit | Underscore => true,
Expand Down Expand Up @@ -1506,9 +1506,7 @@ pub struct MutTy {
/// Represents a method's signature in a trait declaration or implementation.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct MethodSig {
pub unsafety: Unsafety,
pub constness: Constness,
pub abi: Abi,
pub header: FnHeader,
pub decl: P<FnDecl>,
}

Expand Down Expand Up @@ -1736,7 +1734,13 @@ pub enum IsAuto {
No
}

#[derive(Copy, Clone, PartialEq, Eq,PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum IsAsync {
Async,
NotAsync,
}

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum Unsafety {
Unsafe,
Normal,
Expand Down Expand Up @@ -2012,6 +2016,14 @@ pub struct Item {
pub span: Span,
}

#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct FnHeader {
pub unsafety: Unsafety,
pub constness: Constness,
pub asyncness: IsAsync,
pub abi: Abi,
}

#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum Item_ {
/// An `extern crate` item, with optional *original* crate name if the crate was renamed.
Expand All @@ -2031,7 +2043,7 @@ pub enum Item_ {
/// A `const` item
ItemConst(P<Ty>, BodyId),
/// A function declaration
ItemFn(P<FnDecl>, Unsafety, Constness, Abi, Generics, BodyId),
ItemFn(P<FnDecl>, FnHeader, Generics, BodyId),
/// A module
ItemMod(Mod),
/// An external module
Expand Down Expand Up @@ -2096,7 +2108,7 @@ impl Item_ {

pub fn generics(&self) -> Option<&Generics> {
Some(match *self {
ItemFn(_, _, _, _, ref generics, _) |
ItemFn(_, _, ref generics, _) |
ItemTy(_, ref generics) |
ItemEnum(_, ref generics) |
ItemStruct(_, ref generics) |
Expand Down
Loading