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/libsyntax/feature_gate | |
| 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/libsyntax/feature_gate')
| -rw-r--r-- | src/libsyntax/feature_gate/check.rs | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs index d95dac9bf52..bd836eee42a 100644 --- a/src/libsyntax/feature_gate/check.rs +++ b/src/libsyntax/feature_gate/check.rs @@ -321,6 +321,27 @@ impl<'a> PostExpansionVisitor<'a> { ); } } + + /// Feature gate `impl Trait` inside `type Alias = $type_expr;`. + fn check_impl_trait(&self, ty: &ast::Ty) { + struct ImplTraitVisitor<'a> { + vis: &'a PostExpansionVisitor<'a>, + } + impl Visitor<'_> for ImplTraitVisitor<'_> { + fn visit_ty(&mut self, ty: &ast::Ty) { + if let ast::TyKind::ImplTrait(..) = ty.kind { + gate_feature_post!( + &self.vis, + type_alias_impl_trait, + ty.span, + "`impl Trait` in type aliases is unstable" + ); + } + visit::walk_ty(self, ty); + } + } + ImplTraitVisitor { vis: self }.visit_ty(ty); + } } impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { @@ -455,14 +476,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { gate_feature_post!(&self, decl_macro, i.span, msg); } - ast::ItemKind::OpaqueTy(..) => { - gate_feature_post!( - &self, - type_alias_impl_trait, - i.span, - "`impl Trait` in type aliases is unstable" - ); - } + ast::ItemKind::TyAlias(ref ty, ..) => self.check_impl_trait(&ty), _ => {} } @@ -636,9 +650,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } } ast::TraitItemKind::Type(_, ref default) => { - // We use three if statements instead of something like match guards so that all - // of these errors can be emitted if all cases apply. - if default.is_some() { + if let Some(ty) = default { + self.check_impl_trait(ty); gate_feature_post!(&self, associated_type_defaults, ti.span, "associated type defaults are unstable"); } @@ -663,15 +676,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { "C-variadic functions are unstable"); } } - ast::ImplItemKind::OpaqueTy(..) => { - gate_feature_post!( - &self, - type_alias_impl_trait, - ii.span, - "`impl Trait` in type aliases is unstable" - ); - } - ast::ImplItemKind::TyAlias(_) => { + ast::ImplItemKind::TyAlias(ref ty) => { + self.check_impl_trait(ty); self.check_gat(&ii.generics, ii.span); } _ => {} |
