diff options
| author | Tyler Mandry <tmandry@gmail.com> | 2019-11-15 14:44:47 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-11-15 14:44:47 +0100 |
| commit | c5bb2ec0dd1f6f38117ec0e7e22c077a4b74dc09 (patch) | |
| tree | 2804bcc92024c0ad0d0a1fa39fd820630286b75c /src/librustc_parse/parser | |
| parent | ce36ab2b064c2aa716084d79717c64cc04bb6532 (diff) | |
| parent | 03cf0d737f075aa8839dd7cc5b1047910ec00ddf (diff) | |
| download | rust-c5bb2ec0dd1f6f38117ec0e7e22c077a4b74dc09.tar.gz rust-c5bb2ec0dd1f6f38117ec0e7e22c077a4b74dc09.zip | |
Rollup merge of #66197 - Centril:transparent-ast, r=varkor
Push `ast::{ItemKind, ImplItemKind}::OpaqueTy` hack down into lowering
We currently have a hack in the form of `ast::{ItemKind, ImplItemKind}::OpaqueTy` which is constructed literally when you write `type Alias = impl Trait;` but not e.g. `type Alias = Vec<impl Trait>;`. Per https://github.com/rust-lang/rfcs/pull/2515, this needs to change to allow `impl Trait` in nested positions. This PR achieves this change for the syntactic aspect but not the semantic one, which will require changes in lowering and def collection. In the interim, `TyKind::opaque_top_hack` is introduced to avoid knock-on changes in lowering, collection, and resolve. These hacks can then be removed and fixed one by one until the desired semantics are supported.
r? @varkor
Diffstat (limited to 'src/librustc_parse/parser')
| -rw-r--r-- | src/librustc_parse/parser/item.rs | 61 |
1 files changed, 13 insertions, 48 deletions
diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index cb496f2ecbe..73099169879 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -7,7 +7,7 @@ use syntax::ast::{self, Abi, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyl use syntax::ast::{ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind}; use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness}; use syntax::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind}; -use syntax::ast::{Ty, TyKind, Generics, GenericBounds, TraitRef, EnumDef, VariantData, StructField}; +use syntax::ast::{Ty, TyKind, Generics, TraitRef, EnumDef, VariantData, StructField}; use syntax::ast::{Mac, MacDelimiter, Block, BindingMode, FnDecl, FnSig, SelfKind, Param}; use syntax::ptr::P; use syntax::ThinVec; @@ -24,15 +24,6 @@ use log::debug; use std::mem; use errors::{PResult, Applicability, DiagnosticBuilder, StashKey}; -/// Whether the type alias or associated type is a concrete type or an opaque type. -#[derive(Debug)] -pub(super) enum AliasKind { - /// Just a new name for the same type. - Weak(P<Ty>), - /// Only trait impls of the type will be usable, not the actual type itself. - OpaqueTy(GenericBounds), -} - pub(super) type ItemInfo = (Ident, ItemKind, Option<Vec<Attribute>>); impl<'a> Parser<'a> { @@ -269,15 +260,11 @@ impl<'a> Parser<'a> { return self.mk_item_with_info(attrs, lo, vis, info); } - if let Some(type_) = self.eat_type() { - let (ident, alias, generics) = type_?; + if self.eat_keyword(kw::Type) { // TYPE ITEM - let item_ = match alias { - AliasKind::Weak(ty) => ItemKind::TyAlias(ty, generics), - AliasKind::OpaqueTy(bounds) => ItemKind::OpaqueTy(bounds, generics), - }; - let span = lo.to(self.prev_span); - return Ok(Some(self.mk_item(span, ident, item_, vis, attrs))); + let (ident, ty, generics) = self.parse_type_alias()?; + let kind = ItemKind::TyAlias(ty, generics); + return self.mk_item_with_info(attrs, lo, vis, (ident, kind, None)); } if self.eat_keyword(kw::Enum) { @@ -711,13 +698,9 @@ impl<'a> Parser<'a> { let lo = self.token.span; let vis = self.parse_visibility(false)?; let defaultness = self.parse_defaultness(); - let (name, kind, generics) = if let Some(type_) = self.eat_type() { - let (name, alias, generics) = type_?; - let kind = match alias { - AliasKind::Weak(typ) => ast::ImplItemKind::TyAlias(typ), - AliasKind::OpaqueTy(bounds) => ast::ImplItemKind::OpaqueTy(bounds), - }; - (name, kind, generics) + let (name, kind, generics) = if self.eat_keyword(kw::Type) { + let (name, ty, generics) = self.parse_type_alias()?; + (name, ast::ImplItemKind::TyAlias(ty), generics) } else if self.is_const_item() { self.parse_impl_const()? } else if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(&vis), at_end)? { @@ -1322,34 +1305,16 @@ impl<'a> Parser<'a> { }) } - /// Parses `type Foo = Bar;` or returns `None` - /// without modifying the parser state. - fn eat_type(&mut self) -> Option<PResult<'a, (Ident, AliasKind, Generics)>> { - // This parses the grammar: - // Ident ["<"...">"] ["where" ...] ("=" | ":") Ty ";" - if self.eat_keyword(kw::Type) { - Some(self.parse_type_alias()) - } else { - None - } - } - - /// Parses a type alias or opaque type. - fn parse_type_alias(&mut self) -> PResult<'a, (Ident, AliasKind, Generics)> { + /// Parses the grammar: + /// Ident ["<"...">"] ["where" ...] ("=" | ":") Ty ";" + fn parse_type_alias(&mut self) -> PResult<'a, (Ident, P<Ty>, Generics)> { let ident = self.parse_ident()?; let mut tps = self.parse_generics()?; tps.where_clause = self.parse_where_clause()?; self.expect(&token::Eq)?; - let alias = if self.check_keyword(kw::Impl) { - self.bump(); - let bounds = self.parse_generic_bounds(Some(self.prev_span))?; - AliasKind::OpaqueTy(bounds) - } else { - let ty = self.parse_ty()?; - AliasKind::Weak(ty) - }; + let ty = self.parse_ty()?; self.expect_semi()?; - Ok((ident, alias, tps)) + Ok((ident, ty, tps)) } /// Parses an enum declaration. |
