Skip to content

Commit

Permalink
ast: Implement TryFrom<ItemKind> for associated and foreign items
Browse files Browse the repository at this point in the history
  • Loading branch information
petrochenkov committed Mar 1, 2020
1 parent 857e34c commit 9c885d4
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 20 deletions.
29 changes: 29 additions & 0 deletions src/librustc_ast/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use rustc_span::source_map::{respan, Spanned};
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::{Span, DUMMY_SP};

use std::convert::TryFrom;
use std::fmt;
use std::iter;

Expand Down Expand Up @@ -2668,6 +2669,20 @@ impl From<AssocItemKind> for ItemKind {
}
}

impl TryFrom<ItemKind> for AssocItemKind {
type Error = ItemKind;

fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
Ok(match item_kind {
ItemKind::Const(a, b, c) => AssocItemKind::Const(a, b, c),
ItemKind::Fn(a, b, c, d) => AssocItemKind::Fn(a, b, c, d),
ItemKind::TyAlias(a, b, c, d) => AssocItemKind::TyAlias(a, b, c, d),
ItemKind::Mac(a) => AssocItemKind::Macro(a),
_ => return Err(item_kind),
})
}
}

/// An item in `extern` block.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub enum ForeignItemKind {
Expand All @@ -2692,4 +2707,18 @@ impl From<ForeignItemKind> for ItemKind {
}
}

impl TryFrom<ItemKind> for ForeignItemKind {
type Error = ItemKind;

fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
Ok(match item_kind {
ItemKind::Static(a, b, c) => ForeignItemKind::Static(a, b, c),
ItemKind::Fn(a, b, c, d) => ForeignItemKind::Fn(a, b, c, d),
ItemKind::TyAlias(a, b, c, d) => ForeignItemKind::TyAlias(a, b, c, d),
ItemKind::Mac(a) => ForeignItemKind::Macro(a),
_ => return Err(item_kind),
})
}
}

pub type ForeignItem = Item<ForeignItemKind>;
40 changes: 20 additions & 20 deletions src/librustc_parse/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use rustc_span::source_map::{self, Span};
use rustc_span::symbol::{kw, sym, Symbol};

use log::debug;
use std::convert::TryFrom;
use std::mem;

pub(super) type ItemInfo = (Ident, ItemKind);
Expand Down Expand Up @@ -647,16 +648,16 @@ impl<'a> Parser<'a> {
/// Parses associated items.
fn parse_assoc_item(&mut self, req_name: ReqName) -> PResult<'a, Option<Option<P<AssocItem>>>> {
Ok(self.parse_item_(req_name)?.map(|Item { attrs, id, span, vis, ident, kind, tokens }| {
let kind = match kind {
ItemKind::Mac(a) => AssocItemKind::Macro(a),
ItemKind::Fn(a, b, c, d) => AssocItemKind::Fn(a, b, c, d),
ItemKind::TyAlias(a, b, c, d) => AssocItemKind::TyAlias(a, b, c, d),
ItemKind::Const(a, b, c) => AssocItemKind::Const(a, b, c),
ItemKind::Static(a, _, b) => {
self.struct_span_err(span, "associated `static` items are not allowed").emit();
AssocItemKind::Const(Defaultness::Final, a, b)
}
_ => return self.error_bad_item_kind(span, &kind, "`trait`s or `impl`s"),
let kind = match AssocItemKind::try_from(kind) {
Ok(kind) => kind,
Err(kind) => match kind {
ItemKind::Static(a, _, b) => {
self.struct_span_err(span, "associated `static` items are not allowed")
.emit();
AssocItemKind::Const(Defaultness::Final, a, b)
}
_ => return self.error_bad_item_kind(span, &kind, "`trait`s or `impl`s"),
},
};
Some(P(Item { attrs, id, span, vis, ident, kind, tokens }))
}))
Expand Down Expand Up @@ -833,16 +834,15 @@ impl<'a> Parser<'a> {
/// Parses a foreign item (one in an `extern { ... }` block).
pub fn parse_foreign_item(&mut self) -> PResult<'a, Option<Option<P<ForeignItem>>>> {
Ok(self.parse_item_(|_| true)?.map(|Item { attrs, id, span, vis, ident, kind, tokens }| {
let kind = match kind {
ItemKind::Mac(a) => ForeignItemKind::Macro(a),
ItemKind::Fn(a, b, c, d) => ForeignItemKind::Fn(a, b, c, d),
ItemKind::TyAlias(a, b, c, d) => ForeignItemKind::TyAlias(a, b, c, d),
ItemKind::Static(a, b, c) => ForeignItemKind::Static(a, b, c),
ItemKind::Const(_, a, b) => {
self.error_on_foreign_const(span, ident);
ForeignItemKind::Static(a, Mutability::Not, b)
}
_ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"),
let kind = match ForeignItemKind::try_from(kind) {
Ok(kind) => kind,
Err(kind) => match kind {
ItemKind::Const(_, a, b) => {
self.error_on_foreign_const(span, ident);
ForeignItemKind::Static(a, Mutability::Not, b)
}
_ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"),
},
};
Some(P(Item { attrs, id, span, vis, ident, kind, tokens }))
}))
Expand Down

0 comments on commit 9c885d4

Please sign in to comment.