Rollup merge of #69361 - Centril:free-ty-alias, r=petrochenkov
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 https://github.com/rust-lang/rust/pull/69194. r? @petrochenkov
This commit is contained in:
commit
ae50725dc3
|
@ -297,28 +297,28 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)),
|
ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)),
|
||||||
ItemKind::ForeignMod(ref nm) => hir::ItemKind::ForeignMod(self.lower_foreign_mod(nm)),
|
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::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 => {
|
None => {
|
||||||
let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
|
let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
|
||||||
let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
|
let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
|
||||||
hir::ItemKind::TyAlias(ty, generics)
|
hir::ItemKind::TyAlias(ty, generics)
|
||||||
}
|
}
|
||||||
Some(bounds) => {
|
Some(bounds) => {
|
||||||
|
let ctx = || ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc);
|
||||||
let ty = hir::OpaqueTy {
|
let ty = hir::OpaqueTy {
|
||||||
generics: self.lower_generics(
|
generics: self.lower_generics(generics, ctx()),
|
||||||
generics,
|
bounds: self.lower_param_bounds(bounds, ctx()),
|
||||||
ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc),
|
|
||||||
),
|
|
||||||
bounds: self.lower_param_bounds(
|
|
||||||
bounds,
|
|
||||||
ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc),
|
|
||||||
),
|
|
||||||
impl_trait_fn: None,
|
impl_trait_fn: None,
|
||||||
origin: hir::OpaqueTyOrigin::TypeAlias,
|
origin: hir::OpaqueTyOrigin::TypeAlias,
|
||||||
};
|
};
|
||||||
hir::ItemKind::OpaqueTy(ty)
|
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(
|
ItemKind::Enum(ref enum_definition, ref generics) => hir::ItemKind::Enum(
|
||||||
hir::EnumDef {
|
hir::EnumDef {
|
||||||
variants: self.arena.alloc_from_iter(
|
variants: self.arena.alloc_from_iter(
|
||||||
|
|
|
@ -462,7 +462,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
ItemKind::Struct(_, ref generics)
|
ItemKind::Struct(_, ref generics)
|
||||||
| ItemKind::Union(_, ref generics)
|
| ItemKind::Union(_, ref generics)
|
||||||
| ItemKind::Enum(_, ref generics)
|
| ItemKind::Enum(_, ref generics)
|
||||||
| ItemKind::TyAlias(_, ref generics)
|
| ItemKind::TyAlias(ref generics, ..)
|
||||||
| ItemKind::Trait(_, _, ref generics, ..) => {
|
| ItemKind::Trait(_, _, ref generics, ..) => {
|
||||||
let def_id = self.lctx.resolver.definitions().local_def_id(item.id);
|
let def_id = self.lctx.resolver.definitions().local_def_id(item.id);
|
||||||
let count = generics
|
let count = generics
|
||||||
|
|
|
@ -969,6 +969,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
let msg = "free static item without body";
|
let msg = "free static item without body";
|
||||||
self.error_item_without_body(item.span, "static", msg, " = <expr>;");
|
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");
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -372,7 +372,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||||
gate_feature_post!(&self, decl_macro, i.span, msg);
|
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),
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::pp::Breaks::{Consistent, Inconsistent};
|
||||||
use crate::pp::{self, Breaks};
|
use crate::pp::{self, Breaks};
|
||||||
|
|
||||||
use rustc_span::edition::Edition;
|
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::symbol::{kw, sym};
|
||||||
use rustc_span::{BytePos, FileName, Span};
|
use rustc_span::{BytePos, FileName, Span};
|
||||||
use syntax::ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax};
|
use syntax::ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax};
|
||||||
|
@ -1026,7 +1026,7 @@ impl<'a> State<'a> {
|
||||||
span: Span,
|
span: Span,
|
||||||
ident: ast::Ident,
|
ident: ast::Ident,
|
||||||
attrs: &[Attribute],
|
attrs: &[Attribute],
|
||||||
defaultness: ast::Defaultness,
|
def: ast::Defaultness,
|
||||||
kind: &ast::AssocItemKind,
|
kind: &ast::AssocItemKind,
|
||||||
vis: &ast::Visibility,
|
vis: &ast::Visibility,
|
||||||
) {
|
) {
|
||||||
|
@ -1034,19 +1034,18 @@ impl<'a> State<'a> {
|
||||||
self.hardbreak_if_not_bol();
|
self.hardbreak_if_not_bol();
|
||||||
self.maybe_print_comment(span.lo());
|
self.maybe_print_comment(span.lo());
|
||||||
self.print_outer_attributes(attrs);
|
self.print_outer_attributes(attrs);
|
||||||
self.print_defaultness(defaultness);
|
|
||||||
match kind {
|
match kind {
|
||||||
ast::ForeignItemKind::Fn(sig, gen, body) => {
|
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) => {
|
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) => {
|
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) => {
|
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) => {
|
ast::ForeignItemKind::Macro(m) => {
|
||||||
self.print_mac(m);
|
self.print_mac(m);
|
||||||
|
@ -1065,13 +1064,17 @@ impl<'a> State<'a> {
|
||||||
ty: &ast::Ty,
|
ty: &ast::Ty,
|
||||||
body: Option<&ast::Expr>,
|
body: Option<&ast::Expr>,
|
||||||
vis: &ast::Visibility,
|
vis: &ast::Visibility,
|
||||||
|
defaultness: ast::Defaultness,
|
||||||
) {
|
) {
|
||||||
|
self.head("");
|
||||||
|
self.print_visibility(vis);
|
||||||
|
self.print_defaultness(defaultness);
|
||||||
let leading = match mutbl {
|
let leading = match mutbl {
|
||||||
None => "const",
|
None => "const",
|
||||||
Some(ast::Mutability::Not) => "static",
|
Some(ast::Mutability::Not) => "static",
|
||||||
Some(ast::Mutability::Mut) => "static mut",
|
Some(ast::Mutability::Mut) => "static mut",
|
||||||
};
|
};
|
||||||
self.head(visibility_qualified(vis, leading));
|
self.word_space(leading);
|
||||||
self.print_ident(ident);
|
self.print_ident(ident);
|
||||||
self.word_space(":");
|
self.word_space(":");
|
||||||
self.print_type(ty);
|
self.print_type(ty);
|
||||||
|
@ -1091,7 +1094,12 @@ impl<'a> State<'a> {
|
||||||
generics: &ast::Generics,
|
generics: &ast::Generics,
|
||||||
bounds: &ast::GenericBounds,
|
bounds: &ast::GenericBounds,
|
||||||
ty: Option<&ast::Ty>,
|
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.word_space("type");
|
||||||
self.print_ident(ident);
|
self.print_ident(ident);
|
||||||
self.print_generic_params(&generics.params);
|
self.print_generic_params(&generics.params);
|
||||||
|
@ -1102,7 +1110,9 @@ impl<'a> State<'a> {
|
||||||
self.word_space("=");
|
self.word_space("=");
|
||||||
self.print_type(ty);
|
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.
|
/// Pretty-prints an item.
|
||||||
|
@ -1133,13 +1143,17 @@ impl<'a> State<'a> {
|
||||||
self.end(); // end outer head-block
|
self.end(); // end outer head-block
|
||||||
}
|
}
|
||||||
ast::ItemKind::Static(ref ty, mutbl, ref body) => {
|
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) => {
|
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) => {
|
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) => {
|
ast::ItemKind::Mod(ref _mod) => {
|
||||||
self.head(visibility_qualified(&item.vis, "mod"));
|
self.head(visibility_qualified(&item.vis, "mod"));
|
||||||
|
@ -1171,18 +1185,10 @@ impl<'a> State<'a> {
|
||||||
self.s.word(ga.asm.to_string());
|
self.s.word(ga.asm.to_string());
|
||||||
self.end();
|
self.end();
|
||||||
}
|
}
|
||||||
ast::ItemKind::TyAlias(ref ty, ref generics) => {
|
ast::ItemKind::TyAlias(ref generics, ref bounds, ref ty) => {
|
||||||
self.head(visibility_qualified(&item.vis, "type"));
|
let def = ast::Defaultness::Final;
|
||||||
self.print_ident(item.ident);
|
let ty = ty.as_deref();
|
||||||
self.print_generic_params(&generics.params);
|
self.print_associated_type(item.ident, generics, bounds, ty, &item.vis, def);
|
||||||
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::Enum(ref enum_definition, ref params) => {
|
ast::ItemKind::Enum(ref enum_definition, ref params) => {
|
||||||
self.print_enum_def(enum_definition, params, item.ident, item.span, &item.vis);
|
self.print_enum_def(enum_definition, params, item.ident, item.span, &item.vis);
|
||||||
|
@ -2370,13 +2376,16 @@ impl<'a> State<'a> {
|
||||||
name: ast::Ident,
|
name: ast::Ident,
|
||||||
generics: &ast::Generics,
|
generics: &ast::Generics,
|
||||||
vis: &ast::Visibility,
|
vis: &ast::Visibility,
|
||||||
|
defaultness: ast::Defaultness,
|
||||||
body: Option<&ast::Block>,
|
body: Option<&ast::Block>,
|
||||||
attrs: &[ast::Attribute],
|
attrs: &[ast::Attribute],
|
||||||
) {
|
) {
|
||||||
if body.is_some() {
|
if body.is_some() {
|
||||||
self.head("");
|
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 {
|
if let Some(body) = body {
|
||||||
self.nbsp();
|
self.nbsp();
|
||||||
self.print_block_with_attrs(body, attrs);
|
self.print_block_with_attrs(body, attrs);
|
||||||
|
@ -2391,10 +2400,8 @@ impl<'a> State<'a> {
|
||||||
header: ast::FnHeader,
|
header: ast::FnHeader,
|
||||||
name: Option<ast::Ident>,
|
name: Option<ast::Ident>,
|
||||||
generics: &ast::Generics,
|
generics: &ast::Generics,
|
||||||
vis: &ast::Visibility,
|
|
||||||
) {
|
) {
|
||||||
self.print_fn_header_info(header, vis);
|
self.print_fn_header_info(header);
|
||||||
|
|
||||||
if let Some(name) = name {
|
if let Some(name) = name {
|
||||||
self.nbsp();
|
self.nbsp();
|
||||||
self.print_ident(name);
|
self.print_ident(name);
|
||||||
|
@ -2672,8 +2679,7 @@ impl<'a> State<'a> {
|
||||||
span: rustc_span::DUMMY_SP,
|
span: rustc_span::DUMMY_SP,
|
||||||
};
|
};
|
||||||
let header = ast::FnHeader { unsafety, ext, ..ast::FnHeader::default() };
|
let header = ast::FnHeader { unsafety, ext, ..ast::FnHeader::default() };
|
||||||
let vis = dummy_spanned(ast::VisibilityKind::Inherited);
|
self.print_fn(decl, header, name, &generics);
|
||||||
self.print_fn(decl, header, name, &generics, &vis);
|
|
||||||
self.end();
|
self.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2700,9 +2706,7 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
crate fn print_fn_header_info(&mut self, header: ast::FnHeader, vis: &ast::Visibility) {
|
crate fn print_fn_header_info(&mut self, header: ast::FnHeader) {
|
||||||
self.s.word(visibility_qualified(vis, ""));
|
|
||||||
|
|
||||||
self.print_constness(header.constness);
|
self.print_constness(header.constness);
|
||||||
self.print_asyncness(header.asyncness);
|
self.print_asyncness(header.asyncness);
|
||||||
self.print_unsafety(header.unsafety);
|
self.print_unsafety(header.unsafety);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use rustc_span;
|
use rustc_span;
|
||||||
use rustc_span::source_map::{dummy_spanned, respan};
|
use rustc_span::source_map::respan;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::with_default_globals;
|
use syntax::with_default_globals;
|
||||||
|
|
||||||
|
@ -13,13 +13,7 @@ fn fun_to_string(
|
||||||
) -> String {
|
) -> String {
|
||||||
to_string(|s| {
|
to_string(|s| {
|
||||||
s.head("");
|
s.head("");
|
||||||
s.print_fn(
|
s.print_fn(decl, header, Some(name), generics);
|
||||||
decl,
|
|
||||||
header,
|
|
||||||
Some(name),
|
|
||||||
generics,
|
|
||||||
&dummy_spanned(ast::VisibilityKind::Inherited),
|
|
||||||
);
|
|
||||||
s.end(); // Close the head box.
|
s.end(); // Close the head box.
|
||||||
s.end(); // Close the outer box.
|
s.end(); // Close the outer box.
|
||||||
})
|
})
|
||||||
|
|
|
@ -156,8 +156,7 @@ impl<'a> Parser<'a> {
|
||||||
self.parse_item_mod(attrs)?
|
self.parse_item_mod(attrs)?
|
||||||
} else if self.eat_keyword(kw::Type) {
|
} else if self.eat_keyword(kw::Type) {
|
||||||
// TYPE ITEM
|
// TYPE ITEM
|
||||||
let (ident, ty, generics) = self.parse_type_alias()?;
|
self.parse_type_alias()?
|
||||||
(ident, ItemKind::TyAlias(ty, generics))
|
|
||||||
} else if self.eat_keyword(kw::Enum) {
|
} else if self.eat_keyword(kw::Enum) {
|
||||||
// ENUM ITEM
|
// ENUM ITEM
|
||||||
self.parse_item_enum()?
|
self.parse_item_enum()?
|
||||||
|
@ -676,7 +675,10 @@ impl<'a> Parser<'a> {
|
||||||
vis: &Visibility,
|
vis: &Visibility,
|
||||||
) -> PResult<'a, (Ident, AssocItemKind)> {
|
) -> PResult<'a, (Ident, AssocItemKind)> {
|
||||||
if self.eat_keyword(kw::Type) {
|
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() {
|
} else if self.check_fn_front_matter() {
|
||||||
let (ident, sig, generics, body) = self.parse_fn(at_end, attrs, req_name)?;
|
let (ident, sig, generics, body) = self.parse_fn(at_end, attrs, req_name)?;
|
||||||
Ok((ident, AssocItemKind::Fn(sig, generics, body)))
|
Ok((ident, AssocItemKind::Fn(sig, generics, body)))
|
||||||
|
@ -700,10 +702,12 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses the following grammar:
|
/// Parses a `type` alias with the following grammar:
|
||||||
///
|
/// ```
|
||||||
/// AssocTy = Ident ["<"...">"] [":" [GenericBounds]] ["where" ...] ["=" Ty]
|
/// TypeAlias = "type" Ident Generics {":" GenericBounds}? {"=" Ty}? ";" ;
|
||||||
fn parse_assoc_ty(&mut self) -> PResult<'a, (Ident, AssocItemKind)> {
|
/// ```
|
||||||
|
/// The `"type"` has already been eaten.
|
||||||
|
fn parse_type_alias(&mut self) -> PResult<'a, (Ident, ItemKind)> {
|
||||||
let ident = self.parse_ident()?;
|
let ident = self.parse_ident()?;
|
||||||
let mut generics = self.parse_generics()?;
|
let mut generics = self.parse_generics()?;
|
||||||
|
|
||||||
|
@ -715,7 +719,7 @@ impl<'a> Parser<'a> {
|
||||||
let default = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None };
|
let default = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None };
|
||||||
self.expect_semi()?;
|
self.expect_semi()?;
|
||||||
|
|
||||||
Ok((ident, AssocItemKind::TyAlias(generics, bounds, default)))
|
Ok((ident, ItemKind::TyAlias(generics, bounds, default)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a `UseTree`.
|
/// Parses a `UseTree`.
|
||||||
|
@ -989,18 +993,6 @@ impl<'a> Parser<'a> {
|
||||||
P(Ty { kind: TyKind::Infer, span: id.span, id: ast::DUMMY_NODE_ID })
|
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.
|
/// Parses an enum declaration.
|
||||||
fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> {
|
fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> {
|
||||||
let id = self.parse_ident()?;
|
let id = self.parse_ident()?;
|
||||||
|
|
|
@ -718,8 +718,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// These items live in the type namespace.
|
// These items live in the type namespace.
|
||||||
ItemKind::TyAlias(ref ty, _) => {
|
ItemKind::TyAlias(_, _, ref ty) => {
|
||||||
let def_kind = match ty.kind.opaque_top_hack() {
|
let def_kind = match ty.as_deref().and_then(|ty| ty.kind.opaque_top_hack()) {
|
||||||
None => DefKind::TyAlias,
|
None => DefKind::TyAlias,
|
||||||
Some(_) => DefKind::OpaqueTy,
|
Some(_) => DefKind::OpaqueTy,
|
||||||
};
|
};
|
||||||
|
|
|
@ -797,7 +797,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
debug!("(resolving item) resolving {} ({:?})", name, item.kind);
|
debug!("(resolving item) resolving {} ({:?})", name, item.kind);
|
||||||
|
|
||||||
match 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| {
|
self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| {
|
||||||
visit::walk_item(this, item)
|
visit::walk_item(this, item)
|
||||||
});
|
});
|
||||||
|
|
|
@ -1311,12 +1311,15 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
|
||||||
self.process_mod(item);
|
self.process_mod(item);
|
||||||
visit::walk_mod(self, m);
|
visit::walk_mod(self, m);
|
||||||
}
|
}
|
||||||
TyAlias(ref ty, ref ty_params) => {
|
TyAlias(ref ty_params, _, ref ty) => {
|
||||||
let qualname = format!(
|
let qualname = format!(
|
||||||
"::{}",
|
"::{}",
|
||||||
self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id))
|
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) {
|
if !self.span.filter_generated(item.ident.span) {
|
||||||
let span = self.span_from_span(item.ident.span);
|
let span = self.span_from_span(item.ident.span);
|
||||||
let id = id_from_node_id(item.id, &self.save_ctxt);
|
let id = id_from_node_id(item.id, &self.save_ctxt);
|
||||||
|
@ -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);
|
self.process_generic_params(ty_params, &qualname, item.id);
|
||||||
}
|
}
|
||||||
Mac(_) => (),
|
Mac(_) => (),
|
||||||
|
|
|
@ -423,12 +423,15 @@ impl Sig for ast::Item {
|
||||||
|
|
||||||
Ok(Signature { text, defs, refs: vec![] })
|
Ok(Signature { text, defs, refs: vec![] })
|
||||||
}
|
}
|
||||||
ast::ItemKind::TyAlias(ref ty, ref generics) => {
|
ast::ItemKind::TyAlias(ref generics, _, ref ty) => {
|
||||||
let text = "type ".to_owned();
|
let text = "type ".to_owned();
|
||||||
let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?;
|
let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?;
|
||||||
|
|
||||||
sig.text.push_str(" = ");
|
sig.text.push_str(" = ");
|
||||||
let ty = ty.make(offset + sig.text.len(), id, scx)?;
|
let ty = match ty {
|
||||||
|
Some(ty) => ty.make(offset + sig.text.len(), id, scx)?,
|
||||||
|
None => Err("Ty")?,
|
||||||
|
};
|
||||||
sig.text.push_str(&ty.text);
|
sig.text.push_str(&ty.text);
|
||||||
sig.text.push(';');
|
sig.text.push(';');
|
||||||
|
|
||||||
|
|
|
@ -2524,7 +2524,7 @@ pub enum ItemKind {
|
||||||
/// A type alias (`type`).
|
/// A type alias (`type`).
|
||||||
///
|
///
|
||||||
/// E.g., `type Foo = Bar<u8>;`.
|
/// E.g., `type Foo = Bar<u8>;`.
|
||||||
TyAlias(P<Ty>, Generics),
|
TyAlias(Generics, GenericBounds, Option<P<Ty>>),
|
||||||
/// An enum definition (`enum`).
|
/// An enum definition (`enum`).
|
||||||
///
|
///
|
||||||
/// E.g., `enum Foo<A, B> { C<A>, D<B> }`.
|
/// E.g., `enum Foo<A, B> { C<A>, D<B> }`.
|
||||||
|
@ -2594,7 +2594,7 @@ impl ItemKind {
|
||||||
pub fn generics(&self) -> Option<&Generics> {
|
pub fn generics(&self) -> Option<&Generics> {
|
||||||
match self {
|
match self {
|
||||||
Self::Fn(_, generics, _)
|
Self::Fn(_, generics, _)
|
||||||
| Self::TyAlias(_, generics)
|
| Self::TyAlias(generics, ..)
|
||||||
| Self::Enum(_, generics)
|
| Self::Enum(_, generics)
|
||||||
| Self::Struct(_, generics)
|
| Self::Struct(_, generics)
|
||||||
| Self::Union(_, generics)
|
| Self::Union(_, generics)
|
||||||
|
|
|
@ -902,9 +902,10 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
|
||||||
ItemKind::Mod(m) => vis.visit_mod(m),
|
ItemKind::Mod(m) => vis.visit_mod(m),
|
||||||
ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
|
ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
|
||||||
ItemKind::GlobalAsm(_ga) => {}
|
ItemKind::GlobalAsm(_ga) => {}
|
||||||
ItemKind::TyAlias(ty, generics) => {
|
ItemKind::TyAlias(generics, bounds, ty) => {
|
||||||
vis.visit_ty(ty);
|
|
||||||
vis.visit_generics(generics);
|
vis.visit_generics(generics);
|
||||||
|
visit_bounds(bounds, vis);
|
||||||
|
visit_opt(ty, |ty| vis.visit_ty(ty));
|
||||||
}
|
}
|
||||||
ItemKind::Enum(EnumDef { variants }, generics) => {
|
ItemKind::Enum(EnumDef { variants }, generics) => {
|
||||||
variants.flat_map_in_place(|variant| vis.flat_map_variant(variant));
|
variants.flat_map_in_place(|variant| vis.flat_map_variant(variant));
|
||||||
|
|
|
@ -312,9 +312,10 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
|
||||||
walk_list!(visitor, visit_foreign_item, &foreign_module.items);
|
walk_list!(visitor, visit_foreign_item, &foreign_module.items);
|
||||||
}
|
}
|
||||||
ItemKind::GlobalAsm(ref ga) => visitor.visit_global_asm(ga),
|
ItemKind::GlobalAsm(ref ga) => visitor.visit_global_asm(ga),
|
||||||
ItemKind::TyAlias(ref typ, ref generics) => {
|
ItemKind::TyAlias(ref generics, ref bounds, ref ty) => {
|
||||||
visitor.visit_ty(typ);
|
visitor.visit_generics(generics);
|
||||||
visitor.visit_generics(generics)
|
walk_list!(visitor, visit_param_bound, bounds);
|
||||||
|
walk_list!(visitor, visit_ty, ty);
|
||||||
}
|
}
|
||||||
ItemKind::Enum(ref enum_definition, ref generics) => {
|
ItemKind::Enum(ref enum_definition, ref generics) => {
|
||||||
visitor.visit_generics(generics);
|
visitor.visit_generics(generics);
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
// Check that associated types print generic parameters and where clauses.
|
|
||||||
// See issue #67509.
|
|
||||||
|
|
||||||
// pretty-compare-only
|
|
||||||
// pp-exact:gat-bounds.pp
|
|
||||||
|
|
||||||
#![feature(generic_associated_types)]
|
|
||||||
|
|
||||||
trait X {
|
|
||||||
type
|
|
||||||
Y<T>: Trait
|
|
||||||
where
|
|
||||||
Self: Sized;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl X for () {
|
|
||||||
type
|
|
||||||
Y<T>
|
|
||||||
where
|
|
||||||
Self: Sized
|
|
||||||
=
|
|
||||||
u32;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() { }
|
|
|
@ -2,7 +2,6 @@
|
||||||
// See issue #67509.
|
// See issue #67509.
|
||||||
|
|
||||||
// pretty-compare-only
|
// pretty-compare-only
|
||||||
// pp-exact:gat-bounds.pp
|
|
||||||
|
|
||||||
#![feature(generic_associated_types)]
|
#![feature(generic_associated_types)]
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
// Check that nested items have their visibility and `default`nesses in the right order.
|
||||||
|
|
||||||
|
// pp-exact
|
||||||
|
|
||||||
|
fn main() { }
|
||||||
|
|
||||||
|
#[cfg(FALSE)]
|
||||||
|
extern "C" {
|
||||||
|
static X: u8 ;
|
||||||
|
type X;
|
||||||
|
fn foo();
|
||||||
|
pub static X: u8 ;
|
||||||
|
pub type X;
|
||||||
|
pub fn foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(FALSE)]
|
||||||
|
trait T {
|
||||||
|
const X: u8 ;
|
||||||
|
type X;
|
||||||
|
fn foo();
|
||||||
|
default const X: u8 ;
|
||||||
|
default type X;
|
||||||
|
default fn foo();
|
||||||
|
pub const X: u8 ;
|
||||||
|
pub type X;
|
||||||
|
pub fn foo();
|
||||||
|
pub default const X: u8 ;
|
||||||
|
pub default type X;
|
||||||
|
pub default fn foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(FALSE)]
|
||||||
|
impl T for S {
|
||||||
|
const X: u8 ;
|
||||||
|
type X;
|
||||||
|
fn foo();
|
||||||
|
default const X: u8 ;
|
||||||
|
default type X;
|
||||||
|
default fn foo();
|
||||||
|
pub const X: u8 ;
|
||||||
|
pub type X;
|
||||||
|
pub fn foo();
|
||||||
|
pub default const X: u8 ;
|
||||||
|
pub default type X;
|
||||||
|
pub default fn foo();
|
||||||
|
}
|
|
@ -5,6 +5,6 @@ type A where 'a:, = u8; // OK
|
||||||
type A where 'a: 'b + 'c = u8; // OK
|
type A where 'a: 'b + 'c = u8; // OK
|
||||||
type A where = u8; // OK
|
type A where = u8; // OK
|
||||||
type A where 'a: 'b + = u8; // OK
|
type A where 'a: 'b + = u8; // OK
|
||||||
type A where , = u8; //~ ERROR expected one of `=`, lifetime, or type, found `,`
|
type A where , = u8; //~ ERROR expected one of `;`, `=`, lifetime, or type, found `,`
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: expected one of `=`, lifetime, or type, found `,`
|
error: expected one of `;`, `=`, lifetime, or type, found `,`
|
||||||
--> $DIR/bounds-lifetime-where.rs:8:14
|
--> $DIR/bounds-lifetime-where.rs:8:14
|
||||||
|
|
|
|
||||||
LL | type A where , = u8;
|
LL | type A where , = u8;
|
||||||
| ^ expected one of `=`, lifetime, or type
|
| ^ expected one of `;`, `=`, lifetime, or type
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
fn main() {}
|
||||||
|
|
||||||
|
fn semantics() {
|
||||||
|
type A: Ord;
|
||||||
|
//~^ ERROR bounds on `type`s in this context have no effect
|
||||||
|
//~| ERROR free type alias without body
|
||||||
|
type B: Ord = u8;
|
||||||
|
//~^ ERROR bounds on `type`s in this context have no effect
|
||||||
|
type C: Ord where 'static: 'static = u8;
|
||||||
|
//~^ ERROR bounds on `type`s in this context have no effect
|
||||||
|
type D<_T>: Ord;
|
||||||
|
//~^ ERROR bounds on `type`s in this context have no effect
|
||||||
|
//~| ERROR free type alias without body
|
||||||
|
type E<_T>: Ord = u8;
|
||||||
|
//~^ ERROR bounds on `type`s in this context have no effect
|
||||||
|
//~| ERROR type parameter `_T` is unused
|
||||||
|
type F<_T>: Ord where 'static: 'static = u8;
|
||||||
|
//~^ ERROR bounds on `type`s in this context have no effect
|
||||||
|
//~| ERROR type parameter `_T` is unused
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
error: free type alias without body
|
||||||
|
--> $DIR/item-free-type-bounds-semantic-fail.rs:4:5
|
||||||
|
|
|
||||||
|
LL | type A: Ord;
|
||||||
|
| ^^^^^^^^^^^-
|
||||||
|
| |
|
||||||
|
| help: provide a definition for the type: `= <type>;`
|
||||||
|
|
||||||
|
error: bounds on `type`s in this context have no effect
|
||||||
|
--> $DIR/item-free-type-bounds-semantic-fail.rs:4:13
|
||||||
|
|
|
||||||
|
LL | type A: Ord;
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: bounds on `type`s in this context have no effect
|
||||||
|
--> $DIR/item-free-type-bounds-semantic-fail.rs:7:13
|
||||||
|
|
|
||||||
|
LL | type B: Ord = u8;
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: bounds on `type`s in this context have no effect
|
||||||
|
--> $DIR/item-free-type-bounds-semantic-fail.rs:9:13
|
||||||
|
|
|
||||||
|
LL | type C: Ord where 'static: 'static = u8;
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: free type alias without body
|
||||||
|
--> $DIR/item-free-type-bounds-semantic-fail.rs:11:5
|
||||||
|
|
|
||||||
|
LL | type D<_T>: Ord;
|
||||||
|
| ^^^^^^^^^^^^^^^-
|
||||||
|
| |
|
||||||
|
| help: provide a definition for the type: `= <type>;`
|
||||||
|
|
||||||
|
error: bounds on `type`s in this context have no effect
|
||||||
|
--> $DIR/item-free-type-bounds-semantic-fail.rs:11:17
|
||||||
|
|
|
||||||
|
LL | type D<_T>: Ord;
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: bounds on `type`s in this context have no effect
|
||||||
|
--> $DIR/item-free-type-bounds-semantic-fail.rs:14:17
|
||||||
|
|
|
||||||
|
LL | type E<_T>: Ord = u8;
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: bounds on `type`s in this context have no effect
|
||||||
|
--> $DIR/item-free-type-bounds-semantic-fail.rs:17:17
|
||||||
|
|
|
||||||
|
LL | type F<_T>: Ord where 'static: 'static = u8;
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error[E0091]: type parameter `_T` is unused
|
||||||
|
--> $DIR/item-free-type-bounds-semantic-fail.rs:14:12
|
||||||
|
|
|
||||||
|
LL | type E<_T>: Ord = u8;
|
||||||
|
| ^^ unused type parameter
|
||||||
|
|
||||||
|
error[E0091]: type parameter `_T` is unused
|
||||||
|
--> $DIR/item-free-type-bounds-semantic-fail.rs:17:12
|
||||||
|
|
|
||||||
|
LL | type F<_T>: Ord where 'static: 'static = u8;
|
||||||
|
| ^^ unused type parameter
|
||||||
|
|
||||||
|
error: aborting due to 10 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0091`.
|
|
@ -0,0 +1,13 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
|
||||||
|
#[cfg(FALSE)]
|
||||||
|
fn syntax() {
|
||||||
|
type A: Ord;
|
||||||
|
type B: Ord = u8;
|
||||||
|
type C: Ord where 'static: 'static = u8;
|
||||||
|
type D<_T>: Ord;
|
||||||
|
type E<_T>: Ord = u8;
|
||||||
|
type F<_T>: Ord where 'static: 'static = u8;
|
||||||
|
}
|
Loading…
Reference in New Issue