Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge TraitItem & ImplItem into AssocItem` #67131

Merged
merged 26 commits into from
Dec 20, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
c4bbe9c
Alias `TraitItem` & `ImplItem`.
Centril Nov 30, 2019
73557fa
Use `Option` in `ImplItemKind::Const`.
Centril Dec 1, 2019
f6403c6
Use `Option` in `ImplItemKind::Method`.
Centril Dec 1, 2019
c02fd31
`TraitItemKind::Type` -> `TraitItemKind::TyAlias`.
Centril Dec 1, 2019
3907376
Unify `{Trait,Impl}ItemKind::TyAlias` structures.
Centril Dec 1, 2019
92a372b
Unify `{Impl,Trait}Item` as `AssocItem`.
Centril Dec 1, 2019
2d92aa5
Fuse associated constant parsing.
Centril Dec 1, 2019
10270bc
Fuse associated type parsing.
Centril Dec 1, 2019
7672bff
Unify associated function parsing.
Centril Dec 1, 2019
63a9030
Unify associated item parsing.
Centril Dec 1, 2019
fa828d7
Relocate `is_const_item`.
Centril Dec 1, 2019
404013e
Leave a FIXME re. `allow_plus`.
Centril Dec 1, 2019
34d9170
parse: refactor fun ret ty & param ty
Centril Dec 1, 2019
9193d7a
Unify associated item pretty printing.
Centril Dec 1, 2019
76576d4
Unify associated item mut visitors.
Centril Dec 1, 2019
c6c17e3
Simplify `nt_to_tokenstream`.
Centril Dec 1, 2019
0d8a9d7
Unify associated item visitor.
Centril Dec 1, 2019
51ccdeb
Unify associated item parsing more.
Centril Dec 1, 2019
b499a88
Unify assoc item visitors more.
Centril Dec 2, 2019
0d41d0f
Move `allow_c_varadic` logic to `ast_validation`.
Centril Dec 2, 2019
3a57a2c
`ast_validation`: move trait item logic to proper place.
Centril Dec 2, 2019
35e9e09
More c-variadic errors as semantic restrictions.
Centril Dec 2, 2019
abf2e7a
Remove `ast::{Impl,Trait}{Item,ItemKind}`.
Centril Dec 7, 2019
e52f902
`AssocImplKind::{Method -> Fn}`.
Centril Dec 7, 2019
74d4fbc
De-fatalize `...` parsing.
Centril Dec 8, 2019
054458b
make visitor uses more robust
Centril Dec 11, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Unify {Trait,Impl}ItemKind::TyAlias structures.
  • Loading branch information
Centril committed Dec 12, 2019
commit 39073767a483d10f8b4b2ac2f32bc9573d9dabbf
37 changes: 15 additions & 22 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1253,6 +1253,14 @@ impl<'a> LoweringContext<'a> {
ty
}

fn ty(&mut self, span: Span, kind: hir::TyKind) -> hir::Ty {
hir::Ty { hir_id: self.next_id(), kind, span }
}

fn ty_tup(&mut self, span: Span, tys: HirVec<hir::Ty>) -> hir::Ty {
self.ty(span, hir::TyKind::Tup(tys))
}

fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_>) -> hir::Ty {
let kind = match t.kind {
TyKind::Infer => hir::TyKind::Infer,
Expand Down Expand Up @@ -2084,12 +2092,9 @@ impl<'a> LoweringContext<'a> {
.iter()
.map(|ty| this.lower_ty_direct(ty, ImplTraitContext::disallowed()))
.collect();
let mk_tup = |this: &mut Self, tys, span| {
hir::Ty { kind: hir::TyKind::Tup(tys), hir_id: this.next_id(), span }
};
(
hir::GenericArgs {
args: hir_vec![GenericArg::Type(mk_tup(this, inputs, span))],
args: hir_vec![GenericArg::Type(this.ty_tup(span, inputs))],
bindings: hir_vec![
hir::TypeBinding {
hir_id: this.next_id(),
Expand All @@ -2102,7 +2107,7 @@ impl<'a> LoweringContext<'a> {
ImplTraitContext::disallowed()
))
.unwrap_or_else(||
P(mk_tup(this, hir::HirVec::new(), span))
P(this.ty_tup(span, hir::HirVec::new()))
),
},
span: output.as_ref().map_or(span, |ty| ty.span),
Expand Down Expand Up @@ -2474,17 +2479,13 @@ impl<'a> LoweringContext<'a> {
})
);

// Create the `Foo<...>` refernece itself. Note that the `type
// Create the `Foo<...>` reference itself. Note that the `type
// Foo = impl Trait` is, internally, created as a child of the
// async fn, so the *type parameters* are inherited. It's
// only the lifetime parameters that we must supply.
let opaque_ty_ref = hir::TyKind::Def(hir::ItemId { id: opaque_ty_id }, generic_args.into());

hir::FunctionRetTy::Return(P(hir::Ty {
kind: opaque_ty_ref,
span: opaque_ty_span,
hir_id: self.next_id(),
}))
let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
hir::FunctionRetTy::Return(P(opaque_ty))
}

/// Transforms `-> T` into `Future<Output = T>`
Expand All @@ -2496,16 +2497,8 @@ impl<'a> LoweringContext<'a> {
) -> hir::GenericBound {
// Compute the `T` in `Future<Output = T>` from the return type.
let output_ty = match output {
FunctionRetTy::Ty(ty) => {
self.lower_ty(ty, ImplTraitContext::OpaqueTy(Some(fn_def_id)))
}
FunctionRetTy::Default(ret_ty_span) => {
P(hir::Ty {
hir_id: self.next_id(),
kind: hir::TyKind::Tup(hir_vec![]),
span: *ret_ty_span,
})
}
FunctionRetTy::Ty(ty) => self.lower_ty(ty, ImplTraitContext::OpaqueTy(Some(fn_def_id))),
FunctionRetTy::Default(ret_ty_span) => P(self.ty_tup(*ret_ty_span, hir_vec![])),
};

// "<Output = T>"
Expand Down
24 changes: 16 additions & 8 deletions src/librustc/hir/lowering/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -932,16 +932,21 @@ impl LoweringContext<'_> {

(generics, hir::ImplItemKind::Method(sig, body_id))
}
ImplItemKind::TyAlias(ref ty) => {
ImplItemKind::TyAlias(_, ref ty) => {
let generics = self.lower_generics(&i.generics, ImplTraitContext::disallowed());
let kind = match ty.kind.opaque_top_hack() {
let kind = match ty {
None => {
let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
hir::ImplItemKind::TyAlias(ty)
hir::ImplItemKind::TyAlias(P(self.ty(i.span, hir::TyKind::Err)))
}
Some(bs) => {
let bounds = self.lower_param_bounds(bs, ImplTraitContext::disallowed());
hir::ImplItemKind::OpaqueTy(bounds)
Some(ty) => match ty.kind.opaque_top_hack() {
None => {
let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
hir::ImplItemKind::TyAlias(ty)
}
Some(bs) => {
let bs = self.lower_param_bounds(bs, ImplTraitContext::disallowed());
hir::ImplItemKind::OpaqueTy(bs)
}
}
};
(generics, kind)
Expand Down Expand Up @@ -972,7 +977,10 @@ impl LoweringContext<'_> {
defaultness: self.lower_defaultness(i.defaultness, true /* [1] */),
kind: match &i.kind {
ImplItemKind::Const(..) => hir::AssocItemKind::Const,
ImplItemKind::TyAlias(ty) => match ty.kind.opaque_top_hack() {
ImplItemKind::TyAlias(_, ty) => match ty
.as_deref()
.and_then(|ty| ty.kind.opaque_top_hack())
{
None => hir::AssocItemKind::Type,
Some(_) => hir::AssocItemKind::OpaqueTy,
},
Expand Down
30 changes: 27 additions & 3 deletions src/librustc_parse/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -697,8 +697,7 @@ impl<'a> Parser<'a> {
let vis = self.parse_visibility(FollowedByType::No)?;
let defaultness = self.parse_defaultness();
let (name, kind, generics) = if self.eat_keyword(kw::Type) {
let (name, ty, generics) = self.parse_type_alias()?;
(name, ast::ImplItemKind::TyAlias(ty), generics)
self.parse_impl_assoc_ty()?
} else if self.is_const_item() {
self.parse_impl_const()?
} else if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(&vis), at_end)? {
Expand Down Expand Up @@ -766,6 +765,31 @@ impl<'a> Parser<'a> {
Ok((ident, ImplItemKind::Const(ty, expr), Generics::default()))
}

/// Parses the following grammar:
///
/// AssocTy = Ident ["<"...">"] [":" [GenericBounds]] ["where" ...] ["=" Ty]
fn parse_impl_assoc_ty(&mut self) -> PResult<'a, (Ident, ImplItemKind, Generics)> {
let ident = self.parse_ident()?;
let mut generics = self.parse_generics()?;

// Parse optional colon and param bounds.
let bounds = if self.eat(&token::Colon) {
self.parse_generic_bounds(None)?
} else {
Vec::new()
};
generics.where_clause = self.parse_where_clause()?;

let default = if self.eat(&token::Eq) {
Some(self.parse_ty()?)
} else {
None
};
self.expect_semi()?;

Ok((ident, ImplItemKind::TyAlias(bounds, default), generics))
}

/// Parses `auto? trait Foo { ... }` or `trait Foo = Bar;`.
fn parse_item_trait(&mut self, lo: Span, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
// Parse optional `auto` prefix.
Expand Down Expand Up @@ -924,7 +948,7 @@ impl<'a> Parser<'a> {

/// Parses the following grammar:
///
/// TraitItemAssocTy = Ident ["<"...">"] [":" [GenericBounds]] ["where" ...] ["=" Ty]
/// AssocTy = Ident ["<"...">"] [":" [GenericBounds]] ["where" ...] ["=" Ty]
fn parse_trait_item_assoc_ty(&mut self) -> PResult<'a, (Ident, TraitItemKind, Generics)> {
let ident = self.parse_ident()?;
let mut generics = self.parse_generics()?;
Expand Down
15 changes: 15 additions & 0 deletions src/librustc_passes/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,17 @@ impl<'a> AstValidator<'a> {
)
.emit();
}

fn check_impl_assoc_type_no_bounds(&self, bounds: &[GenericBound]) {
let span = match bounds {
[] => return,
[b0] => b0.span(),
[b0, .., bl] => b0.span().to(bl.span()),
};
self.err_handler()
.struct_span_err(span, "bounds on associated `type`s in `impl`s have no effect")
.emit();
}
}

enum GenericPosition {
Expand Down Expand Up @@ -770,6 +781,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.check_impl_item_provided(ii.span, body, "function", " { <body> }");
self.check_fn_decl(&sig.decl);
}
ImplItemKind::TyAlias(bounds, body) => {
self.check_impl_item_provided(ii.span, body, "type", " = <type>;");
self.check_impl_assoc_type_no_bounds(bounds);
}
_ => {}
}
visit::walk_impl_item(self, ii);
Expand Down
1 change: 1 addition & 0 deletions src/librustc_passes/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#![feature(in_band_lifetimes)]
#![feature(nll)]
#![feature(slice_patterns)]

#![recursion_limit="256"]

Expand Down
3 changes: 2 additions & 1 deletion src/librustc_resolve/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1119,7 +1119,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {

visit::walk_impl_item(this, impl_item);
}
ImplItemKind::TyAlias(ref ty) => {
ImplItemKind::TyAlias(_, Some(ref ty)) => {
// If this is a trait impl, ensure the type
// exists in trait
this.check_trait_item(impl_item.ident,
Expand All @@ -1129,6 +1129,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {

this.visit_ty(ty);
}
ImplItemKind::TyAlias(_, None) => {}
ImplItemKind::Macro(_) =>
panic!("unexpanded macro in resolve!"),
}
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_save_analysis/dump_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1127,7 +1127,8 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
impl_item.span,
);
}
ast::ImplItemKind::TyAlias(ref ty) => {
ast::ImplItemKind::TyAlias(_, None) => {}
ast::ImplItemKind::TyAlias(_, Some(ref ty)) => {
// FIXME: uses of the assoc type should ideally point to this
// 'def' and the name here should be a ref to the def in the
// trait.
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1638,7 +1638,7 @@ pub struct ImplItem<K = ImplItemKind> {
pub enum ImplItemKind {
Const(P<Ty>, Option<P<Expr>>),
Method(FnSig, Option<P<Block>>),
TyAlias(P<Ty>),
TyAlias(GenericBounds, Option<P<Ty>>),
Macro(Mac),
}

Expand Down
6 changes: 4 additions & 2 deletions src/libsyntax/feature_gate/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -612,8 +612,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
"C-variadic functions are unstable");
}
}
ast::ImplItemKind::TyAlias(ref ty) => {
self.check_impl_trait(ty);
ast::ImplItemKind::TyAlias(_, ref ty) => {
if let Some(ty) = ty {
self.check_impl_trait(ty);
}
self.check_gat(&ii.generics, ii.span);
}
_ => {}
Expand Down
5 changes: 4 additions & 1 deletion src/libsyntax/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -987,7 +987,10 @@ pub fn noop_flat_map_impl_item<T: MutVisitor>(mut item: ImplItem, visitor: &mut
visit_fn_sig(sig, visitor);
visit_opt(body, |body| visitor.visit_block(body));
}
ImplItemKind::TyAlias(ty) => visitor.visit_ty(ty),
ImplItemKind::TyAlias(bounds, ty) => {
visit_bounds(bounds, visitor);
visit_opt(ty, |ty| visitor.visit_ty(ty));
}
ImplItemKind::Macro(mac) => visitor.visit_mac(mac),
}
visitor.visit_span(span);
Expand Down
22 changes: 10 additions & 12 deletions src/libsyntax/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1128,16 +1128,15 @@ impl<'a> State<'a> {
self.s.word(";")
}

fn print_associated_type(&mut self,
ident: ast::Ident,
bounds: Option<&ast::GenericBounds>,
ty: Option<&ast::Ty>)
{
fn print_associated_type(
&mut self,
ident: ast::Ident,
bounds: &ast::GenericBounds,
ty: Option<&ast::Ty>,
) {
self.word_space("type");
self.print_ident(ident);
if let Some(bounds) = bounds {
self.print_type_bounds(":", bounds);
}
self.print_type_bounds(":", bounds);
if let Some(ty) = ty {
self.s.space();
self.word_space("=");
Expand Down Expand Up @@ -1568,8 +1567,7 @@ impl<'a> State<'a> {
}
}
ast::TraitItemKind::TyAlias(ref bounds, ref default) => {
self.print_associated_type(ti.ident, Some(bounds),
default.as_ref().map(|ty| &**ty));
self.print_associated_type(ti.ident, bounds, default.as_deref());
}
ast::TraitItemKind::Macro(ref mac) => {
self.print_mac(mac);
Expand Down Expand Up @@ -1603,8 +1601,8 @@ impl<'a> State<'a> {
self.s.word(";");
}
}
ast::ImplItemKind::TyAlias(ref ty) => {
self.print_associated_type(ii.ident, None, Some(ty));
ast::ImplItemKind::TyAlias(ref bounds, ref ty) => {
self.print_associated_type(ii.ident, bounds, ty.as_deref());
}
ast::ImplItemKind::Macro(ref mac) => {
self.print_mac(mac);
Expand Down
5 changes: 3 additions & 2 deletions src/libsyntax/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -627,8 +627,9 @@ pub fn walk_impl_item<'a, V: Visitor<'a>>(visitor: &mut V, impl_item: &'a ImplIt
visitor.visit_fn(FnKind::Method(impl_item.ident, sig, &impl_item.vis, body),
&sig.decl, impl_item.span, impl_item.id);
}
ImplItemKind::TyAlias(ref ty) => {
visitor.visit_ty(ty);
ImplItemKind::TyAlias(ref bounds, ref ty) => {
walk_list!(visitor, visit_param_bound, bounds);
walk_list!(visitor, visit_ty, ty);
}
ImplItemKind::Macro(ref mac) => {
visitor.visit_mac(mac);
Expand Down
4 changes: 3 additions & 1 deletion src/libsyntax_ext/deriving/generic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,9 @@ impl<'a> TraitDef<'a> {
attrs: Vec::new(),
generics: Generics::default(),
kind: ast::ImplItemKind::TyAlias(
type_def.to_ty(cx, self.span, type_ident, generics)),
Vec::new(),
Some(type_def.to_ty(cx, self.span, type_ident, generics)),
),
tokens: None,
}
});
Expand Down
11 changes: 11 additions & 0 deletions src/test/ui/parser/impl-item-type-no-body-pass.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// check-pass

fn main() {}

#[cfg(FALSE)]
impl X {
type Y;
type Z: Ord;
type W: Ord where Self: Eq;
type W where Self: Eq;
}
22 changes: 22 additions & 0 deletions src/test/ui/parser/impl-item-type-no-body-semantic-fail.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#![feature(generic_associated_types)]
//~^ WARN the feature `generic_associated_types` is incomplete

fn main() {}

struct X;

impl X {
type Y;
//~^ ERROR associated type in `impl` without body
//~| ERROR associated types are not yet supported in inherent impls
type Z: Ord;
//~^ ERROR associated type in `impl` without body
//~| ERROR bounds on associated `type`s in `impl`s have no effect
//~| ERROR associated types are not yet supported in inherent impls
type W: Ord where Self: Eq;
//~^ ERROR associated type in `impl` without body
//~| ERROR bounds on associated `type`s in `impl`s have no effect
//~| ERROR associated types are not yet supported in inherent impls
type W where Self: Eq;
//~^ ERROR associated type in `impl` without body
}
Loading