Skip to content

Commit

Permalink
Auto merge of #69023 - Centril:parse_fn, r=petrochenkov
Browse files Browse the repository at this point in the history
parse: unify function front matter parsing

Part of #68728.

- `const extern fn` feature gating is now done post-expansion such that we do not have conditional compatibilities of function qualifiers *in parsing*.

- The `FnFrontMatter` grammar becomes:
   ```rust
   Extern = "extern" StringLit ;
   FnQual = "const"? "async"? "unsafe"? Extern? ;
   FnFrontMatter = FnQual "fn" ;
   ```

   That is, all item contexts now *syntactically* allow `const async unsafe extern "C" fn` and use semantic restrictions to rule out combinations previously prevented syntactically. The semantic restrictions include in particular:

   - `fn`s in `extern { ... }` can have no qualifiers.
   - `const` and `async` cannot be combined.

- We change `ast::{Unsafety, Spanned<Constness>}>` into `enum ast::{Unsafe, Const} { Yes(Span), No }` respectively. This change in formulation allow us to exclude `Span` in the case of `No`, which facilitates parsing. Moreover, we also add a `Span` to `IsAsync` which is renamed to `Async`. The new `Span`s in `Unsafety` and `Async` are then taken advantage of for better diagnostics. A reason this change was made is to have a more uniform and clear naming scheme.

  The HIR keeps the structures in AST (with those definitions moved into HIR) for now to avoid regressing perf.

r? @petrochenkov
  • Loading branch information
bors committed Feb 13, 2020
2 parents 2e6eace + 9828559 commit be493fe
Show file tree
Hide file tree
Showing 94 changed files with 737 additions and 694 deletions.
3 changes: 1 addition & 2 deletions src/librustc/traits/auto_trait.rs
Expand Up @@ -9,7 +9,6 @@ use crate::ty::fold::TypeFolder;
use crate::ty::{Region, RegionVid};

use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use syntax::ast;

use std::collections::hash_map::Entry;
use std::collections::VecDeque;
Expand Down Expand Up @@ -350,7 +349,7 @@ impl AutoTraitFinder<'tcx> {
already_visited.remove(&pred);
self.add_user_pred(
&mut user_computed_preds,
ty::Predicate::Trait(pred, ast::Constness::NotConst),
ty::Predicate::Trait(pred, hir::Constness::NotConst),
);
predicates.push_back(pred);
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/traits/error_reporting/mod.rs
Expand Up @@ -695,7 +695,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
let unit_obligation = Obligation {
predicate: ty::Predicate::Trait(
predicate,
ast::Constness::NotConst,
hir::Constness::NotConst,
),
..obligation.clone()
};
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/traits/select.rs
Expand Up @@ -40,19 +40,19 @@ use crate::ty::fast_reject;
use crate::ty::relate::TypeRelation;
use crate::ty::subst::{Subst, SubstsRef};
use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
use rustc_hir::def_id::DefId;

use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_index::bit_set::GrowableBitSet;
use rustc_span::symbol::sym;
use rustc_target::spec::abi::Abi;
use syntax::attr;

use std::cell::{Cell, RefCell};
use std::cmp;
use std::fmt::{self, Display};
use std::iter;
use std::rc::Rc;
use syntax::{ast, attr};

pub use rustc::traits::types::select::*;

Expand Down Expand Up @@ -677,7 +677,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// if the regions match exactly.
let cycle = stack.iter().skip(1).take_while(|s| s.depth >= cycle_depth);
let cycle = cycle.map(|stack| {
ty::Predicate::Trait(stack.obligation.predicate, ast::Constness::NotConst)
ty::Predicate::Trait(stack.obligation.predicate, hir::Constness::NotConst)
});
if self.coinductive_match(cycle) {
debug!("evaluate_stack({:?}) --> recursive, coinductive", stack.fresh_trait_ref);
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/ty/fold.rs
Expand Up @@ -32,6 +32,7 @@
//! looking for, and does not need to visit anything else.

use crate::ty::{self, flags::FlagComputation, Binder, Ty, TyCtxt, TypeFlags};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;

use rustc_data_structures::fx::FxHashSet;
Expand Down Expand Up @@ -150,7 +151,7 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
}
}

impl TypeFoldable<'tcx> for syntax::ast::Constness {
impl TypeFoldable<'tcx> for hir::Constness {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
*self
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/ty/mod.rs
Expand Up @@ -35,15 +35,15 @@ use rustc_data_structures::sync::{self, par_iter, Lrc, ParallelIterator};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::{GlobMap, Node, TraitMap};
use rustc_hir::{Constness, GlobMap, Node, TraitMap};
use rustc_index::vec::{Idx, IndexVec};
use rustc_macros::HashStable;
use rustc_serialize::{self, Encodable, Encoder};
use rustc_span::hygiene::ExpnId;
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::Span;
use rustc_target::abi::Align;
use syntax::ast::{self, Constness, Ident, Name};
use syntax::ast::{self, Ident, Name};
use syntax::node_id::{NodeId, NodeMap, NodeSet};

use std::cell::RefCell;
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/print/pretty.rs
Expand Up @@ -1818,7 +1818,7 @@ define_print_and_forward_display! {
ty::Predicate<'tcx> {
match *self {
ty::Predicate::Trait(ref data, constness) => {
if let ast::Constness::Const = constness {
if let hir::Constness::Const = constness {
p!(write("const "));
}
p!(print(data))
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/ty/structural_impls.rs
Expand Up @@ -7,6 +7,7 @@ use crate::mir::ProjectionKind;
use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use crate::ty::print::{FmtPrinter, Printer};
use crate::ty::{self, InferConst, Lift, Ty, TyCtxt};
use rustc_hir as hir;
use rustc_hir::def::Namespace;
use rustc_hir::def_id::CRATE_DEF_INDEX;
use rustc_index::vec::{Idx, IndexVec};
Expand All @@ -15,7 +16,6 @@ use smallvec::SmallVec;
use std::fmt;
use std::rc::Rc;
use std::sync::Arc;
use syntax::ast;

impl fmt::Debug for ty::GenericParamDef {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand Down Expand Up @@ -236,7 +236,7 @@ impl fmt::Debug for ty::Predicate<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
ty::Predicate::Trait(ref a, constness) => {
if let ast::Constness::Const = constness {
if let hir::Constness::Const = constness {
write!(f, "const ")?;
}
a.fmt(f)
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_ast_lowering/expr.rs
Expand Up @@ -106,7 +106,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
ref body,
fn_decl_span,
) => {
if let IsAsync::Async { closure_id, .. } = asyncness {
if let Async::Yes { closure_id, .. } = asyncness {
self.lower_expr_async_closure(
capture_clause,
closure_id,
Expand Down
57 changes: 35 additions & 22 deletions src/librustc_ast_lowering/item.rs
Expand Up @@ -67,10 +67,12 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
self.lctx.with_parent_item_lifetime_defs(hir_id, |this| {
let this = &mut ItemLowerer { lctx: this };
if let ItemKind::Impl { constness, ref of_trait, .. } = item.kind {
if constness == Constness::Const {
if let Const::Yes(span) = constness {
this.lctx
.diagnostic()
.span_err(item.span, "const trait impls are not yet implemented");
.struct_span_err(item.span, "const trait impls are not yet implemented")
.span_label(span, "const because of this")
.emit();
}

this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item));
Expand Down Expand Up @@ -297,7 +299,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// `impl Future<Output = T>` here because lower_body
// only cares about the input argument patterns in the function
// declaration (decl), not the return types.
let asyncness = header.asyncness.node;
let asyncness = header.asyncness;
let body_id =
this.lower_maybe_async_body(span, &decl, asyncness, body.as_deref());

Expand Down Expand Up @@ -413,10 +415,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
});

hir::ItemKind::Impl {
unsafety,
unsafety: self.lower_unsafety(unsafety),
polarity,
defaultness: self.lower_defaultness(defaultness, true /* [1] */),
constness,
constness: self.lower_constness(constness),
generics,
of_trait: trait_ref,
self_ty: lowered_ty,
Expand All @@ -430,7 +432,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
.alloc_from_iter(items.iter().map(|item| self.lower_trait_item_ref(item)));
hir::ItemKind::Trait(
is_auto,
unsafety,
self.lower_unsafety(unsafety),
self.lower_generics(generics, ImplTraitContext::disallowed()),
bounds,
items,
Expand Down Expand Up @@ -834,19 +836,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
AssocItemKind::Fn(ref sig, ref body) => {
self.current_item = Some(i.span);
let body_id = self.lower_maybe_async_body(
i.span,
&sig.decl,
sig.header.asyncness.node,
body.as_deref(),
);
let asyncness = sig.header.asyncness;
let body_id =
self.lower_maybe_async_body(i.span, &sig.decl, asyncness, body.as_deref());
let impl_trait_return_allow = !self.is_in_trait_impl;
let (generics, sig) = self.lower_method_sig(
&i.generics,
sig,
impl_item_def_id,
impl_trait_return_allow,
sig.header.asyncness.node.opt_return_id(),
asyncness.opt_return_id(),
);

(generics, hir::ImplItemKind::Method(sig, body_id))
Expand Down Expand Up @@ -1031,12 +1030,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
&mut self,
span: Span,
decl: &FnDecl,
asyncness: IsAsync,
asyncness: Async,
body: Option<&Block>,
) -> hir::BodyId {
let closure_id = match asyncness {
IsAsync::Async { closure_id, .. } => closure_id,
IsAsync::NotAsync => return self.lower_fn_body_block(span, decl, body),
Async::Yes { closure_id, .. } => closure_id,
Async::No => return self.lower_fn_body_block(span, decl, body),
};

self.lower_body(|this| {
Expand Down Expand Up @@ -1245,9 +1244,9 @@ impl<'hir> LoweringContext<'_, 'hir> {

fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
hir::FnHeader {
unsafety: h.unsafety,
asyncness: self.lower_asyncness(h.asyncness.node),
constness: h.constness.node,
unsafety: self.lower_unsafety(h.unsafety),
asyncness: self.lower_asyncness(h.asyncness),
constness: self.lower_constness(h.constness),
abi: self.lower_extern(h.ext),
}
}
Expand All @@ -1274,10 +1273,24 @@ impl<'hir> LoweringContext<'_, 'hir> {
.emit();
}

fn lower_asyncness(&mut self, a: IsAsync) -> hir::IsAsync {
fn lower_asyncness(&mut self, a: Async) -> hir::IsAsync {
match a {
IsAsync::Async { .. } => hir::IsAsync::Async,
IsAsync::NotAsync => hir::IsAsync::NotAsync,
Async::Yes { .. } => hir::IsAsync::Async,
Async::No => hir::IsAsync::NotAsync,
}
}

fn lower_constness(&mut self, c: Const) -> hir::Constness {
match c {
Const::Yes(_) => hir::Constness::Const,
Const::No => hir::Constness::NotConst,
}
}

pub(super) fn lower_unsafety(&mut self, u: Unsafe) -> hir::Unsafety {
match u {
Unsafe::Yes(_) => hir::Unsafety::Unsafe,
Unsafe::No => hir::Unsafety::Normal,
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_ast_lowering/lib.rs
Expand Up @@ -1196,7 +1196,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&NodeMap::default(),
ImplTraitContext::disallowed(),
),
unsafety: f.unsafety,
unsafety: this.lower_unsafety(f.unsafety),
abi: this.lower_extern(f.ext),
decl: this.lower_fn_decl(&f.decl, None, false, None),
param_names: this.lower_fn_params_to_names(&f.decl),
Expand Down

0 comments on commit be493fe

Please sign in to comment.