Skip to content

Commit 9876ced

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 5b93d4d + 03cf0d7 commit 9876ced

27 files changed

+314
-263
lines changed

src/librustc/hir/lowering.rs

-1
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,6 @@ impl<'a> LoweringContext<'a> {
452452
| ItemKind::Union(_, ref generics)
453453
| ItemKind::Enum(_, ref generics)
454454
| ItemKind::TyAlias(_, ref generics)
455-
| ItemKind::OpaqueTy(_, ref generics)
456455
| ItemKind::Trait(_, _, ref generics, ..) => {
457456
let def_id = self.lctx.resolver.definitions().local_def_id(item.id);
458457
let count = generics

src/librustc/hir/lowering/item.rs

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

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

@@ -948,11 +954,13 @@ impl LoweringContext<'_> {
948954
span: i.span,
949955
vis: self.lower_visibility(&i.vis, Some(i.id)),
950956
defaultness: self.lower_defaultness(i.defaultness, true /* [1] */),
951-
kind: match i.kind {
957+
kind: match &i.kind {
952958
ImplItemKind::Const(..) => hir::AssocItemKind::Const,
953-
ImplItemKind::TyAlias(..) => hir::AssocItemKind::Type,
954-
ImplItemKind::OpaqueTy(..) => hir::AssocItemKind::OpaqueTy,
955-
ImplItemKind::Method(ref sig, _) => hir::AssocItemKind::Method {
959+
ImplItemKind::TyAlias(ty) => match ty.kind.opaque_top_hack() {
960+
None => hir::AssocItemKind::Type,
961+
Some(_) => hir::AssocItemKind::OpaqueTy,
962+
},
963+
ImplItemKind::Method(sig, _) => hir::AssocItemKind::Method {
956964
has_self: sig.decl.has_self(),
957965
},
958966
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;
@@ -21,15 +21,6 @@ use log::debug;
2121
use std::mem;
2222
use errors::{PResult, Applicability, DiagnosticBuilder, DiagnosticId, StashKey};
2323

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

3526
impl<'a> Parser<'a> {
@@ -266,15 +257,11 @@ impl<'a> Parser<'a> {
266257
return self.mk_item_with_info(attrs, lo, vis, info);
267258
}
268259

269-
if let Some(type_) = self.eat_type() {
270-
let (ident, alias, generics) = type_?;
260+
if self.eat_keyword(kw::Type) {
271261
// TYPE ITEM
272-
let item_ = match alias {
273-
AliasKind::Weak(ty) => ItemKind::TyAlias(ty, generics),
274-
AliasKind::OpaqueTy(bounds) => ItemKind::OpaqueTy(bounds, generics),
275-
};
276-
let span = lo.to(self.prev_span);
277-
return Ok(Some(self.mk_item(span, ident, item_, vis, attrs)));
262+
let (ident, ty, generics) = self.parse_type_alias()?;
263+
let kind = ItemKind::TyAlias(ty, generics);
264+
return self.mk_item_with_info(attrs, lo, vis, (ident, kind, None));
278265
}
279266

280267
if self.eat_keyword(kw::Enum) {
@@ -708,13 +695,9 @@ impl<'a> Parser<'a> {
708695
let lo = self.token.span;
709696
let vis = self.parse_visibility(false)?;
710697
let defaultness = self.parse_defaultness();
711-
let (name, kind, generics) = if let Some(type_) = self.eat_type() {
712-
let (name, alias, generics) = type_?;
713-
let kind = match alias {
714-
AliasKind::Weak(typ) => ast::ImplItemKind::TyAlias(typ),
715-
AliasKind::OpaqueTy(bounds) => ast::ImplItemKind::OpaqueTy(bounds),
716-
};
717-
(name, kind, generics)
698+
let (name, kind, generics) = if self.eat_keyword(kw::Type) {
699+
let (name, ty, generics) = self.parse_type_alias()?;
700+
(name, ast::ImplItemKind::TyAlias(ty), generics)
718701
} else if self.is_const_item() {
719702
self.parse_impl_const()?
720703
} else if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(&vis), at_end)? {
@@ -1318,34 +1301,16 @@ impl<'a> Parser<'a> {
13181301
})
13191302
}
13201303

1321-
/// Parses `type Foo = Bar;` or returns `None`
1322-
/// without modifying the parser state.
1323-
fn eat_type(&mut self) -> Option<PResult<'a, (Ident, AliasKind, Generics)>> {
1324-
// This parses the grammar:
1325-
// Ident ["<"...">"] ["where" ...] ("=" | ":") Ty ";"
1326-
if self.eat_keyword(kw::Type) {
1327-
Some(self.parse_type_alias())
1328-
} else {
1329-
None
1330-
}
1331-
}
1332-
1333-
/// Parses a type alias or opaque type.
1334-
fn parse_type_alias(&mut self) -> PResult<'a, (Ident, AliasKind, Generics)> {
1304+
/// Parses the grammar:
1305+
/// Ident ["<"...">"] ["where" ...] ("=" | ":") Ty ";"
1306+
fn parse_type_alias(&mut self) -> PResult<'a, (Ident, P<Ty>, Generics)> {
13351307
let ident = self.parse_ident()?;
13361308
let mut tps = self.parse_generics()?;
13371309
tps.where_clause = self.parse_where_clause()?;
13381310
self.expect(&token::Eq)?;
1339-
let alias = if self.check_keyword(kw::Impl) {
1340-
self.bump();
1341-
let bounds = self.parse_generic_bounds(Some(self.prev_span))?;
1342-
AliasKind::OpaqueTy(bounds)
1343-
} else {
1344-
let ty = self.parse_ty()?;
1345-
AliasKind::Weak(ty)
1346-
};
1311+
let ty = self.parse_ty()?;
13471312
self.expect_semi()?;
1348-
Ok((ident, alias, tps))
1313+
Ok((ident, ty, tps))
13491314
}
13501315

13511316
/// 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
struct AstValidator<'a> {
@@ -584,14 +584,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
584584
"unions cannot have zero fields");
585585
}
586586
}
587-
ItemKind::OpaqueTy(ref bounds, _) => {
588-
if !bounds.iter()
589-
.any(|b| if let GenericBound::Trait(..) = *b { true } else { false }) {
590-
let msp = MultiSpan::from_spans(bounds.iter()
591-
.map(|bound| bound.span()).collect());
592-
self.err_handler().span_err(msp, "at least one trait must be specified");
593-
}
594-
}
595587
_ => {}
596588
}
597589

src/librustc_resolve/build_reduced_graph.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -699,13 +699,12 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
699699
}
700700

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

src/librustc_resolve/late.rs

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

731731
match item.kind {
732732
ItemKind::TyAlias(_, ref generics) |
733-
ItemKind::OpaqueTy(_, ref generics) |
734733
ItemKind::Fn(_, ref generics, _) => {
735734
self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes),
736735
|this| visit::walk_item(this, item));
@@ -1085,18 +1084,6 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
10851084

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

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)