Skip to content

Commit 959950c

Browse files
authored
Rollup merge of rust-lang#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 rust-lang/rfcs#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
2 parents d4429ad + 03cf0d7 commit 959950c

27 files changed

+314
-263
lines changed

src/librustc/hir/lowering.rs

-1
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,6 @@ impl<'a> LoweringContext<'a> {
454454
| ItemKind::Union(_, ref generics)
455455
| ItemKind::Enum(_, ref generics)
456456
| ItemKind::TyAlias(_, ref generics)
457-
| ItemKind::OpaqueTy(_, ref generics)
458457
| ItemKind::Trait(_, _, ref generics, ..) => {
459458
let def_id = self.lctx.resolver.definitions().local_def_id(item.id);
460459
let count = generics

src/librustc/hir/lowering/item.rs

+35-27
Original file line numberDiff line numberDiff line change
@@ -337,20 +337,22 @@ impl LoweringContext<'_> {
337337
ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)),
338338
ItemKind::ForeignMod(ref nm) => hir::ItemKind::ForeignMod(self.lower_foreign_mod(nm)),
339339
ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)),
340-
ItemKind::TyAlias(ref t, ref generics) => hir::ItemKind::TyAlias(
341-
self.lower_ty(t, ImplTraitContext::disallowed()),
342-
self.lower_generics(generics, ImplTraitContext::disallowed()),
343-
),
344-
ItemKind::OpaqueTy(ref b, ref generics) => hir::ItemKind::OpaqueTy(
345-
hir::OpaqueTy {
346-
generics: self.lower_generics(generics,
347-
ImplTraitContext::OpaqueTy(None)),
348-
bounds: self.lower_param_bounds(b,
349-
ImplTraitContext::OpaqueTy(None)),
350-
impl_trait_fn: None,
351-
origin: hir::OpaqueTyOrigin::TypeAlias,
340+
ItemKind::TyAlias(ref ty, ref generics) => match ty.kind.opaque_top_hack() {
341+
None => {
342+
let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
343+
let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
344+
hir::ItemKind::TyAlias(ty, generics)
352345
},
353-
),
346+
Some(bounds) => {
347+
let ty = hir::OpaqueTy {
348+
generics: self.lower_generics(generics, ImplTraitContext::OpaqueTy(None)),
349+
bounds: self.lower_param_bounds(bounds, ImplTraitContext::OpaqueTy(None)),
350+
impl_trait_fn: None,
351+
origin: hir::OpaqueTyOrigin::TypeAlias,
352+
};
353+
hir::ItemKind::OpaqueTy(ty)
354+
}
355+
}
354356
ItemKind::Enum(ref enum_definition, ref generics) => {
355357
hir::ItemKind::Enum(
356358
hir::EnumDef {
@@ -916,16 +918,20 @@ impl LoweringContext<'_> {
916918

917919
(generics, hir::ImplItemKind::Method(sig, body_id))
918920
}
919-
ImplItemKind::TyAlias(ref ty) => (
920-
self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
921-
hir::ImplItemKind::TyAlias(self.lower_ty(ty, ImplTraitContext::disallowed())),
922-
),
923-
ImplItemKind::OpaqueTy(ref bounds) => (
924-
self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
925-
hir::ImplItemKind::OpaqueTy(
926-
self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
927-
),
928-
),
921+
ImplItemKind::TyAlias(ref ty) => {
922+
let generics = self.lower_generics(&i.generics, ImplTraitContext::disallowed());
923+
let kind = match ty.kind.opaque_top_hack() {
924+
None => {
925+
let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
926+
hir::ImplItemKind::TyAlias(ty)
927+
}
928+
Some(bs) => {
929+
let bounds = self.lower_param_bounds(bs, ImplTraitContext::disallowed());
930+
hir::ImplItemKind::OpaqueTy(bounds)
931+
}
932+
};
933+
(generics, kind)
934+
},
929935
ImplItemKind::Macro(..) => bug!("`TyMac` should have been expanded by now"),
930936
};
931937

@@ -950,11 +956,13 @@ impl LoweringContext<'_> {
950956
span: i.span,
951957
vis: self.lower_visibility(&i.vis, Some(i.id)),
952958
defaultness: self.lower_defaultness(i.defaultness, true /* [1] */),
953-
kind: match i.kind {
959+
kind: match &i.kind {
954960
ImplItemKind::Const(..) => hir::AssocItemKind::Const,
955-
ImplItemKind::TyAlias(..) => hir::AssocItemKind::Type,
956-
ImplItemKind::OpaqueTy(..) => hir::AssocItemKind::OpaqueTy,
957-
ImplItemKind::Method(ref sig, _) => hir::AssocItemKind::Method {
961+
ImplItemKind::TyAlias(ty) => match ty.kind.opaque_top_hack() {
962+
None => hir::AssocItemKind::Type,
963+
Some(_) => hir::AssocItemKind::OpaqueTy,
964+
},
965+
ImplItemKind::Method(sig, _) => hir::AssocItemKind::Method {
958966
has_self: sig.decl.has_self(),
959967
},
960968
ImplItemKind::Macro(..) => unimplemented!(),

src/librustc/hir/map/def_collector.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
107107
}
108108
ItemKind::Mod(..) | ItemKind::Trait(..) | ItemKind::TraitAlias(..) |
109109
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) |
110-
ItemKind::OpaqueTy(..) | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) |
110+
ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) |
111111
ItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.name),
112112
ItemKind::Fn(sig, generics, body) if sig.header.asyncness.node.is_async() => {
113113
return self.visit_async_fn(
@@ -239,8 +239,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
239239
}
240240
ImplItemKind::Method(..) |
241241
ImplItemKind::Const(..) => DefPathData::ValueNs(ii.ident.name),
242-
ImplItemKind::TyAlias(..) |
243-
ImplItemKind::OpaqueTy(..) => DefPathData::TypeNs(ii.ident.name),
242+
ImplItemKind::TyAlias(..) => DefPathData::TypeNs(ii.ident.name),
244243
ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id),
245244
};
246245

src/librustc_parse/parser/item.rs

+13-48
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use syntax::ast::{self, Abi, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyl
77
use syntax::ast::{ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind};
88
use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness};
99
use syntax::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind};
10-
use syntax::ast::{Ty, TyKind, Generics, GenericBounds, TraitRef, EnumDef, VariantData, StructField};
10+
use syntax::ast::{Ty, TyKind, Generics, TraitRef, EnumDef, VariantData, StructField};
1111
use syntax::ast::{Mac, MacDelimiter, Block, BindingMode, FnDecl, FnSig, SelfKind, Param};
1212
use syntax::ptr::P;
1313
use syntax::ThinVec;
@@ -24,15 +24,6 @@ use log::debug;
2424
use std::mem;
2525
use errors::{PResult, Applicability, DiagnosticBuilder, StashKey};
2626

27-
/// Whether the type alias or associated type is a concrete type or an opaque type.
28-
#[derive(Debug)]
29-
pub(super) enum AliasKind {
30-
/// Just a new name for the same type.
31-
Weak(P<Ty>),
32-
/// Only trait impls of the type will be usable, not the actual type itself.
33-
OpaqueTy(GenericBounds),
34-
}
35-
3627
pub(super) type ItemInfo = (Ident, ItemKind, Option<Vec<Attribute>>);
3728

3829
impl<'a> Parser<'a> {
@@ -269,15 +260,11 @@ impl<'a> Parser<'a> {
269260
return self.mk_item_with_info(attrs, lo, vis, info);
270261
}
271262

272-
if let Some(type_) = self.eat_type() {
273-
let (ident, alias, generics) = type_?;
263+
if self.eat_keyword(kw::Type) {
274264
// TYPE ITEM
275-
let item_ = match alias {
276-
AliasKind::Weak(ty) => ItemKind::TyAlias(ty, generics),
277-
AliasKind::OpaqueTy(bounds) => ItemKind::OpaqueTy(bounds, generics),
278-
};
279-
let span = lo.to(self.prev_span);
280-
return Ok(Some(self.mk_item(span, ident, item_, vis, attrs)));
265+
let (ident, ty, generics) = self.parse_type_alias()?;
266+
let kind = ItemKind::TyAlias(ty, generics);
267+
return self.mk_item_with_info(attrs, lo, vis, (ident, kind, None));
281268
}
282269

283270
if self.eat_keyword(kw::Enum) {
@@ -711,13 +698,9 @@ impl<'a> Parser<'a> {
711698
let lo = self.token.span;
712699
let vis = self.parse_visibility(false)?;
713700
let defaultness = self.parse_defaultness();
714-
let (name, kind, generics) = if let Some(type_) = self.eat_type() {
715-
let (name, alias, generics) = type_?;
716-
let kind = match alias {
717-
AliasKind::Weak(typ) => ast::ImplItemKind::TyAlias(typ),
718-
AliasKind::OpaqueTy(bounds) => ast::ImplItemKind::OpaqueTy(bounds),
719-
};
720-
(name, kind, generics)
701+
let (name, kind, generics) = if self.eat_keyword(kw::Type) {
702+
let (name, ty, generics) = self.parse_type_alias()?;
703+
(name, ast::ImplItemKind::TyAlias(ty), generics)
721704
} else if self.is_const_item() {
722705
self.parse_impl_const()?
723706
} else if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(&vis), at_end)? {
@@ -1322,34 +1305,16 @@ impl<'a> Parser<'a> {
13221305
})
13231306
}
13241307

1325-
/// Parses `type Foo = Bar;` or returns `None`
1326-
/// without modifying the parser state.
1327-
fn eat_type(&mut self) -> Option<PResult<'a, (Ident, AliasKind, Generics)>> {
1328-
// This parses the grammar:
1329-
// Ident ["<"...">"] ["where" ...] ("=" | ":") Ty ";"
1330-
if self.eat_keyword(kw::Type) {
1331-
Some(self.parse_type_alias())
1332-
} else {
1333-
None
1334-
}
1335-
}
1336-
1337-
/// Parses a type alias or opaque type.
1338-
fn parse_type_alias(&mut self) -> PResult<'a, (Ident, AliasKind, Generics)> {
1308+
/// Parses the grammar:
1309+
/// Ident ["<"...">"] ["where" ...] ("=" | ":") Ty ";"
1310+
fn parse_type_alias(&mut self) -> PResult<'a, (Ident, P<Ty>, Generics)> {
13391311
let ident = self.parse_ident()?;
13401312
let mut tps = self.parse_generics()?;
13411313
tps.where_clause = self.parse_where_clause()?;
13421314
self.expect(&token::Eq)?;
1343-
let alias = if self.check_keyword(kw::Impl) {
1344-
self.bump();
1345-
let bounds = self.parse_generic_bounds(Some(self.prev_span))?;
1346-
AliasKind::OpaqueTy(bounds)
1347-
} else {
1348-
let ty = self.parse_ty()?;
1349-
AliasKind::Weak(ty)
1350-
};
1315+
let ty = self.parse_ty()?;
13511316
self.expect_semi()?;
1352-
Ok((ident, alias, tps))
1317+
Ok((ident, ty, tps))
13531318
}
13541319

13551320
/// Parses an enum declaration.

src/librustc_passes/ast_validation.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use syntax::source_map::Spanned;
2020
use syntax::symbol::{kw, sym};
2121
use syntax::visit::{self, Visitor};
2222
use syntax::{span_err, struct_span_err, walk_list};
23-
use syntax_pos::{Span, MultiSpan};
23+
use syntax_pos::Span;
2424
use errors::{Applicability, FatalError};
2525

2626
use rustc_error_codes::*;
@@ -586,14 +586,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
586586
"unions cannot have zero fields");
587587
}
588588
}
589-
ItemKind::OpaqueTy(ref bounds, _) => {
590-
if !bounds.iter()
591-
.any(|b| if let GenericBound::Trait(..) = *b { true } else { false }) {
592-
let msp = MultiSpan::from_spans(bounds.iter()
593-
.map(|bound| bound.span()).collect());
594-
self.err_handler().span_err(msp, "at least one trait must be specified");
595-
}
596-
}
597589
_ => {}
598590
}
599591

src/librustc_resolve/build_reduced_graph.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -701,13 +701,12 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
701701
}
702702

703703
// These items live in the type namespace.
704-
ItemKind::TyAlias(..) => {
705-
let res = Res::Def(DefKind::TyAlias, self.r.definitions.local_def_id(item.id));
706-
self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
707-
}
708-
709-
ItemKind::OpaqueTy(_, _) => {
710-
let res = Res::Def(DefKind::OpaqueTy, self.r.definitions.local_def_id(item.id));
704+
ItemKind::TyAlias(ref ty, _) => {
705+
let def_kind = match ty.kind.opaque_top_hack() {
706+
None => DefKind::TyAlias,
707+
Some(_) => DefKind::OpaqueTy,
708+
};
709+
let res = Res::Def(def_kind, self.r.definitions.local_def_id(item.id));
711710
self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
712711
}
713712

src/librustc_resolve/late.rs

-13
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,6 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
732732

733733
match item.kind {
734734
ItemKind::TyAlias(_, ref generics) |
735-
ItemKind::OpaqueTy(_, ref generics) |
736735
ItemKind::Fn(_, ref generics, _) => {
737736
self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes),
738737
|this| visit::walk_item(this, item));
@@ -1087,18 +1086,6 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
10871086

10881087
this.visit_ty(ty);
10891088
}
1090-
ImplItemKind::OpaqueTy(ref bounds) => {
1091-
// If this is a trait impl, ensure the type
1092-
// exists in trait
1093-
this.check_trait_item(impl_item.ident,
1094-
TypeNS,
1095-
impl_item.span,
1096-
|n, s| TypeNotMemberOfTrait(n, s));
1097-
1098-
for bound in bounds {
1099-
this.visit_param_bound(bound);
1100-
}
1101-
}
11021089
ImplItemKind::Macro(_) =>
11031090
panic!("unexpanded macro in resolve!"),
11041091
}

src/librustc_save_analysis/dump_visitor.rs

-38
Original file line numberDiff line numberDiff line change
@@ -1133,12 +1133,6 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
11331133
// trait.
11341134
self.visit_ty(ty)
11351135
}
1136-
ast::ImplItemKind::OpaqueTy(ref bounds) => {
1137-
// FIXME: uses of the assoc type should ideally point to this
1138-
// 'def' and the name here should be a ref to the def in the
1139-
// trait.
1140-
self.process_bounds(&bounds);
1141-
}
11421136
ast::ImplItemKind::Macro(_) => {}
11431137
}
11441138
}
@@ -1384,38 +1378,6 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
13841378
self.visit_ty(&ty);
13851379
self.process_generic_params(ty_params, &qualname, item.id);
13861380
}
1387-
OpaqueTy(ref bounds, ref ty_params) => {
1388-
let qualname = format!("::{}",
1389-
self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)));
1390-
1391-
let value = String::new();
1392-
if !self.span.filter_generated(item.ident.span) {
1393-
let span = self.span_from_span(item.ident.span);
1394-
let id = id_from_node_id(item.id, &self.save_ctxt);
1395-
let hir_id = self.tcx.hir().node_to_hir_id(item.id);
1396-
1397-
self.dumper.dump_def(
1398-
&access_from!(self.save_ctxt, item, hir_id),
1399-
Def {
1400-
kind: DefKind::Type,
1401-
id,
1402-
span,
1403-
name: item.ident.to_string(),
1404-
qualname: qualname.clone(),
1405-
value,
1406-
parent: None,
1407-
children: vec![],
1408-
decl_id: None,
1409-
docs: self.save_ctxt.docs_for_attrs(&item.attrs),
1410-
sig: sig::item_signature(item, &self.save_ctxt),
1411-
attributes: lower_attributes(item.attrs.clone(), &self.save_ctxt),
1412-
},
1413-
);
1414-
}
1415-
1416-
self.process_bounds(bounds);
1417-
self.process_generic_params(ty_params, &qualname, item.id);
1418-
}
14191381
Mac(_) => (),
14201382
_ => visit::walk_item(self, item),
14211383
}

src/librustc_save_analysis/sig.rs

-10
Original file line numberDiff line numberDiff line change
@@ -447,16 +447,6 @@ impl Sig for ast::Item {
447447

448448
Ok(merge_sigs(sig.text.clone(), vec![sig, ty]))
449449
}
450-
ast::ItemKind::OpaqueTy(ref bounds, ref generics) => {
451-
let text = "type ".to_owned();
452-
let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?;
453-
454-
sig.text.push_str(" = impl ");
455-
sig.text.push_str(&pprust::bounds_to_string(bounds));
456-
sig.text.push(';');
457-
458-
Ok(sig)
459-
}
460450
ast::ItemKind::Enum(_, ref generics) => {
461451
let text = "enum ".to_owned();
462452
let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?;

src/libsyntax/ast.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -1579,7 +1579,6 @@ pub enum ImplItemKind {
15791579
Const(P<Ty>, P<Expr>),
15801580
Method(FnSig, P<Block>),
15811581
TyAlias(P<Ty>),
1582-
OpaqueTy(GenericBounds),
15831582
Macro(Mac),
15841583
}
15851584

@@ -1816,6 +1815,15 @@ impl TyKind {
18161815
false
18171816
}
18181817
}
1818+
1819+
/// HACK(type_alias_impl_trait, Centril): A temporary crutch used
1820+
/// in lowering to avoid making larger changes there and beyond.
1821+
pub fn opaque_top_hack(&self) -> Option<&GenericBounds> {
1822+
match self {
1823+
Self::ImplTrait(_, bounds) => Some(bounds),
1824+
_ => None,
1825+
}
1826+
}
18191827
}
18201828

18211829
/// Syntax used to declare a trait object.
@@ -2483,10 +2491,6 @@ pub enum ItemKind {
24832491
///
24842492
/// E.g., `type Foo = Bar<u8>;`.
24852493
TyAlias(P<Ty>, Generics),
2486-
/// An opaque `impl Trait` type alias.
2487-
///
2488-
/// E.g., `type Foo = impl Bar + Boo;`.
2489-
OpaqueTy(GenericBounds, Generics),
24902494
/// An enum definition (`enum`).
24912495
///
24922496
/// E.g., `enum Foo<A, B> { C<A>, D<B> }`.
@@ -2540,7 +2544,6 @@ impl ItemKind {
25402544
ItemKind::ForeignMod(..) => "foreign module",
25412545
ItemKind::GlobalAsm(..) => "global asm",
25422546
ItemKind::TyAlias(..) => "type alias",
2543-
ItemKind::OpaqueTy(..) => "opaque type",
25442547
ItemKind::Enum(..) => "enum",
25452548
ItemKind::Struct(..) => "struct",
25462549
ItemKind::Union(..) => "union",

0 commit comments

Comments
 (0)