Skip to content

Commit

Permalink
Rollup merge of #69361 - Centril:free-ty-alias, r=petrochenkov
Browse files Browse the repository at this point in the history
parse: allow `type Foo: Ord` syntactically

This addresses:
> (Work still remains to fuse this with free type aliases, but this can be done later.)

in #69194.

r? @petrochenkov
  • Loading branch information
Dylan-DPC authored Feb 23, 2020
2 parents cec0003 + 9f3dfd2 commit ae50725
Show file tree
Hide file tree
Showing 22 changed files with 242 additions and 116 deletions.
18 changes: 9 additions & 9 deletions src/librustc_ast_lowering/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,28 +297,28 @@ impl<'hir> LoweringContext<'_, 'hir> {
ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)),
ItemKind::ForeignMod(ref nm) => hir::ItemKind::ForeignMod(self.lower_foreign_mod(nm)),
ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)),
ItemKind::TyAlias(ref ty, ref generics) => match ty.kind.opaque_top_hack() {
ItemKind::TyAlias(ref generics, _, Some(ref ty)) => match ty.kind.opaque_top_hack() {
None => {
let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
hir::ItemKind::TyAlias(ty, generics)
}
Some(bounds) => {
let ctx = || ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc);
let ty = hir::OpaqueTy {
generics: self.lower_generics(
generics,
ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc),
),
bounds: self.lower_param_bounds(
bounds,
ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc),
),
generics: self.lower_generics(generics, ctx()),
bounds: self.lower_param_bounds(bounds, ctx()),
impl_trait_fn: None,
origin: hir::OpaqueTyOrigin::TypeAlias,
};
hir::ItemKind::OpaqueTy(ty)
}
},
ItemKind::TyAlias(ref generics, _, None) => {
let ty = self.arena.alloc(self.ty(span, hir::TyKind::Err));
let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
hir::ItemKind::TyAlias(ty, generics)
}
ItemKind::Enum(ref enum_definition, ref generics) => hir::ItemKind::Enum(
hir::EnumDef {
variants: self.arena.alloc_from_iter(
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_ast_lowering/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ItemKind::Struct(_, ref generics)
| ItemKind::Union(_, ref generics)
| ItemKind::Enum(_, ref generics)
| ItemKind::TyAlias(_, ref generics)
| ItemKind::TyAlias(ref generics, ..)
| ItemKind::Trait(_, _, ref generics, ..) => {
let def_id = self.lctx.resolver.definitions().local_def_id(item.id);
let count = generics
Expand Down
7 changes: 7 additions & 0 deletions src/librustc_ast_passes/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
let msg = "free static item without body";
self.error_item_without_body(item.span, "static", msg, " = <expr>;");
}
ItemKind::TyAlias(_, ref bounds, ref body) => {
if body.is_none() {
let msg = "free type alias without body";
self.error_item_without_body(item.span, "type", msg, " = <type>;");
}
self.check_type_no_bounds(bounds, "this context");
}
_ => {}
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_ast_passes/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
gate_feature_post!(&self, decl_macro, i.span, msg);
}

ast::ItemKind::TyAlias(ref ty, ..) => self.check_impl_trait(&ty),
ast::ItemKind::TyAlias(_, _, Some(ref ty)) => self.check_impl_trait(&ty),

_ => {}
}
Expand Down
70 changes: 37 additions & 33 deletions src/librustc_ast_pretty/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::pp::Breaks::{Consistent, Inconsistent};
use crate::pp::{self, Breaks};

use rustc_span::edition::Edition;
use rustc_span::source_map::{dummy_spanned, SourceMap, Spanned};
use rustc_span::source_map::{SourceMap, Spanned};
use rustc_span::symbol::{kw, sym};
use rustc_span::{BytePos, FileName, Span};
use syntax::ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax};
Expand Down Expand Up @@ -1026,27 +1026,26 @@ impl<'a> State<'a> {
span: Span,
ident: ast::Ident,
attrs: &[Attribute],
defaultness: ast::Defaultness,
def: ast::Defaultness,
kind: &ast::AssocItemKind,
vis: &ast::Visibility,
) {
self.ann.pre(self, AnnNode::SubItem(id));
self.hardbreak_if_not_bol();
self.maybe_print_comment(span.lo());
self.print_outer_attributes(attrs);
self.print_defaultness(defaultness);
match kind {
ast::ForeignItemKind::Fn(sig, gen, body) => {
self.print_fn_full(sig, ident, gen, vis, body.as_deref(), attrs);
self.print_fn_full(sig, ident, gen, vis, def, body.as_deref(), attrs);
}
ast::ForeignItemKind::Const(ty, body) => {
self.print_item_const(ident, None, ty, body.as_deref(), vis);
self.print_item_const(ident, None, ty, body.as_deref(), vis, def);
}
ast::ForeignItemKind::Static(ty, mutbl, body) => {
self.print_item_const(ident, Some(*mutbl), ty, body.as_deref(), vis);
self.print_item_const(ident, Some(*mutbl), ty, body.as_deref(), vis, def);
}
ast::ForeignItemKind::TyAlias(generics, bounds, ty) => {
self.print_associated_type(ident, generics, bounds, ty.as_deref());
self.print_associated_type(ident, generics, bounds, ty.as_deref(), vis, def);
}
ast::ForeignItemKind::Macro(m) => {
self.print_mac(m);
Expand All @@ -1065,13 +1064,17 @@ impl<'a> State<'a> {
ty: &ast::Ty,
body: Option<&ast::Expr>,
vis: &ast::Visibility,
defaultness: ast::Defaultness,
) {
self.head("");
self.print_visibility(vis);
self.print_defaultness(defaultness);
let leading = match mutbl {
None => "const",
Some(ast::Mutability::Not) => "static",
Some(ast::Mutability::Mut) => "static mut",
};
self.head(visibility_qualified(vis, leading));
self.word_space(leading);
self.print_ident(ident);
self.word_space(":");
self.print_type(ty);
Expand All @@ -1091,7 +1094,12 @@ impl<'a> State<'a> {
generics: &ast::Generics,
bounds: &ast::GenericBounds,
ty: Option<&ast::Ty>,
vis: &ast::Visibility,
defaultness: ast::Defaultness,
) {
self.head("");
self.print_visibility(vis);
self.print_defaultness(defaultness);
self.word_space("type");
self.print_ident(ident);
self.print_generic_params(&generics.params);
Expand All @@ -1102,7 +1110,9 @@ impl<'a> State<'a> {
self.word_space("=");
self.print_type(ty);
}
self.s.word(";")
self.s.word(";");
self.end(); // end inner head-block
self.end(); // end outer head-block
}

/// Pretty-prints an item.
Expand Down Expand Up @@ -1133,13 +1143,17 @@ impl<'a> State<'a> {
self.end(); // end outer head-block
}
ast::ItemKind::Static(ref ty, mutbl, ref body) => {
self.print_item_const(item.ident, Some(mutbl), ty, body.as_deref(), &item.vis);
let def = ast::Defaultness::Final;
self.print_item_const(item.ident, Some(mutbl), ty, body.as_deref(), &item.vis, def);
}
ast::ItemKind::Const(ref ty, ref body) => {
self.print_item_const(item.ident, None, ty, body.as_deref(), &item.vis);
let def = ast::Defaultness::Final;
self.print_item_const(item.ident, None, ty, body.as_deref(), &item.vis, def);
}
ast::ItemKind::Fn(ref sig, ref gen, ref body) => {
self.print_fn_full(sig, item.ident, gen, &item.vis, body.as_deref(), &item.attrs);
let def = ast::Defaultness::Final;
let body = body.as_deref();
self.print_fn_full(sig, item.ident, gen, &item.vis, def, body, &item.attrs);
}
ast::ItemKind::Mod(ref _mod) => {
self.head(visibility_qualified(&item.vis, "mod"));
Expand Down Expand Up @@ -1171,18 +1185,10 @@ impl<'a> State<'a> {
self.s.word(ga.asm.to_string());
self.end();
}
ast::ItemKind::TyAlias(ref ty, ref generics) => {
self.head(visibility_qualified(&item.vis, "type"));
self.print_ident(item.ident);
self.print_generic_params(&generics.params);
self.end(); // end the inner ibox

self.print_where_clause(&generics.where_clause);
self.s.space();
self.word_space("=");
self.print_type(ty);
self.s.word(";");
self.end(); // end the outer ibox
ast::ItemKind::TyAlias(ref generics, ref bounds, ref ty) => {
let def = ast::Defaultness::Final;
let ty = ty.as_deref();
self.print_associated_type(item.ident, generics, bounds, ty, &item.vis, def);
}
ast::ItemKind::Enum(ref enum_definition, ref params) => {
self.print_enum_def(enum_definition, params, item.ident, item.span, &item.vis);
Expand Down Expand Up @@ -2370,13 +2376,16 @@ impl<'a> State<'a> {
name: ast::Ident,
generics: &ast::Generics,
vis: &ast::Visibility,
defaultness: ast::Defaultness,
body: Option<&ast::Block>,
attrs: &[ast::Attribute],
) {
if body.is_some() {
self.head("");
}
self.print_fn(&sig.decl, sig.header, Some(name), generics, vis);
self.print_visibility(vis);
self.print_defaultness(defaultness);
self.print_fn(&sig.decl, sig.header, Some(name), generics);
if let Some(body) = body {
self.nbsp();
self.print_block_with_attrs(body, attrs);
Expand All @@ -2391,10 +2400,8 @@ impl<'a> State<'a> {
header: ast::FnHeader,
name: Option<ast::Ident>,
generics: &ast::Generics,
vis: &ast::Visibility,
) {
self.print_fn_header_info(header, vis);

self.print_fn_header_info(header);
if let Some(name) = name {
self.nbsp();
self.print_ident(name);
Expand Down Expand Up @@ -2672,8 +2679,7 @@ impl<'a> State<'a> {
span: rustc_span::DUMMY_SP,
};
let header = ast::FnHeader { unsafety, ext, ..ast::FnHeader::default() };
let vis = dummy_spanned(ast::VisibilityKind::Inherited);
self.print_fn(decl, header, name, &generics, &vis);
self.print_fn(decl, header, name, &generics);
self.end();
}

Expand All @@ -2700,9 +2706,7 @@ impl<'a> State<'a> {
}
}

crate fn print_fn_header_info(&mut self, header: ast::FnHeader, vis: &ast::Visibility) {
self.s.word(visibility_qualified(vis, ""));

crate fn print_fn_header_info(&mut self, header: ast::FnHeader) {
self.print_constness(header.constness);
self.print_asyncness(header.asyncness);
self.print_unsafety(header.unsafety);
Expand Down
10 changes: 2 additions & 8 deletions src/librustc_ast_pretty/pprust/tests.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::*;

use rustc_span;
use rustc_span::source_map::{dummy_spanned, respan};
use rustc_span::source_map::respan;
use syntax::ast;
use syntax::with_default_globals;

Expand All @@ -13,13 +13,7 @@ fn fun_to_string(
) -> String {
to_string(|s| {
s.head("");
s.print_fn(
decl,
header,
Some(name),
generics,
&dummy_spanned(ast::VisibilityKind::Inherited),
);
s.print_fn(decl, header, Some(name), generics);
s.end(); // Close the head box.
s.end(); // Close the outer box.
})
Expand Down
32 changes: 12 additions & 20 deletions src/librustc_parse/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,7 @@ impl<'a> Parser<'a> {
self.parse_item_mod(attrs)?
} else if self.eat_keyword(kw::Type) {
// TYPE ITEM
let (ident, ty, generics) = self.parse_type_alias()?;
(ident, ItemKind::TyAlias(ty, generics))
self.parse_type_alias()?
} else if self.eat_keyword(kw::Enum) {
// ENUM ITEM
self.parse_item_enum()?
Expand Down Expand Up @@ -676,7 +675,10 @@ impl<'a> Parser<'a> {
vis: &Visibility,
) -> PResult<'a, (Ident, AssocItemKind)> {
if self.eat_keyword(kw::Type) {
self.parse_assoc_ty()
match self.parse_type_alias()? {
(ident, ItemKind::TyAlias(a, b, c)) => Ok((ident, AssocItemKind::TyAlias(a, b, c))),
_ => unreachable!(),
}
} else if self.check_fn_front_matter() {
let (ident, sig, generics, body) = self.parse_fn(at_end, attrs, req_name)?;
Ok((ident, AssocItemKind::Fn(sig, generics, body)))
Expand All @@ -700,10 +702,12 @@ impl<'a> Parser<'a> {
}
}

/// Parses the following grammar:
///
/// AssocTy = Ident ["<"...">"] [":" [GenericBounds]] ["where" ...] ["=" Ty]
fn parse_assoc_ty(&mut self) -> PResult<'a, (Ident, AssocItemKind)> {
/// Parses a `type` alias with the following grammar:
/// ```
/// TypeAlias = "type" Ident Generics {":" GenericBounds}? {"=" Ty}? ";" ;
/// ```
/// The `"type"` has already been eaten.
fn parse_type_alias(&mut self) -> PResult<'a, (Ident, ItemKind)> {
let ident = self.parse_ident()?;
let mut generics = self.parse_generics()?;

Expand All @@ -715,7 +719,7 @@ impl<'a> Parser<'a> {
let default = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None };
self.expect_semi()?;

Ok((ident, AssocItemKind::TyAlias(generics, bounds, default)))
Ok((ident, ItemKind::TyAlias(generics, bounds, default)))
}

/// Parses a `UseTree`.
Expand Down Expand Up @@ -989,18 +993,6 @@ impl<'a> Parser<'a> {
P(Ty { kind: TyKind::Infer, span: id.span, id: ast::DUMMY_NODE_ID })
}

/// 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 ty = self.parse_ty()?;
self.expect_semi()?;
Ok((ident, ty, tps))
}

/// Parses an enum declaration.
fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> {
let id = self.parse_ident()?;
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -718,8 +718,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
}

// These items live in the type namespace.
ItemKind::TyAlias(ref ty, _) => {
let def_kind = match ty.kind.opaque_top_hack() {
ItemKind::TyAlias(_, _, ref ty) => {
let def_kind = match ty.as_deref().and_then(|ty| ty.kind.opaque_top_hack()) {
None => DefKind::TyAlias,
Some(_) => DefKind::OpaqueTy,
};
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_resolve/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -797,7 +797,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
debug!("(resolving item) resolving {} ({:?})", name, item.kind);

match item.kind {
ItemKind::TyAlias(_, ref generics) | ItemKind::Fn(_, ref generics, _) => {
ItemKind::TyAlias(ref generics, _, _) | ItemKind::Fn(_, ref generics, _) => {
self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| {
visit::walk_item(this, item)
});
Expand Down
9 changes: 6 additions & 3 deletions src/librustc_save_analysis/dump_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1311,12 +1311,15 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
self.process_mod(item);
visit::walk_mod(self, m);
}
TyAlias(ref ty, ref ty_params) => {
TyAlias(ref ty_params, _, ref ty) => {
let qualname = format!(
"::{}",
self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id))
);
let value = ty_to_string(&ty);
let value = match ty {
Some(ty) => ty_to_string(&ty),
None => "_".to_string(),
};
if !self.span.filter_generated(item.ident.span) {
let span = self.span_from_span(item.ident.span);
let id = id_from_node_id(item.id, &self.save_ctxt);
Expand All @@ -1341,7 +1344,7 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
);
}

self.visit_ty(&ty);
walk_list!(self, visit_ty, ty);
self.process_generic_params(ty_params, &qualname, item.id);
}
Mac(_) => (),
Expand Down
Loading

0 comments on commit ae50725

Please sign in to comment.