mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Unify {Trait,Impl}ItemKind::TyAlias
structures.
This commit is contained in:
parent
c02fd31302
commit
39073767a4
@ -1253,6 +1253,14 @@ impl<'a> LoweringContext<'a> {
|
|||||||
ty
|
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 {
|
fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_>) -> hir::Ty {
|
||||||
let kind = match t.kind {
|
let kind = match t.kind {
|
||||||
TyKind::Infer => hir::TyKind::Infer,
|
TyKind::Infer => hir::TyKind::Infer,
|
||||||
@ -2084,12 +2092,9 @@ impl<'a> LoweringContext<'a> {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|ty| this.lower_ty_direct(ty, ImplTraitContext::disallowed()))
|
.map(|ty| this.lower_ty_direct(ty, ImplTraitContext::disallowed()))
|
||||||
.collect();
|
.collect();
|
||||||
let mk_tup = |this: &mut Self, tys, span| {
|
|
||||||
hir::Ty { kind: hir::TyKind::Tup(tys), hir_id: this.next_id(), span }
|
|
||||||
};
|
|
||||||
(
|
(
|
||||||
hir::GenericArgs {
|
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![
|
bindings: hir_vec![
|
||||||
hir::TypeBinding {
|
hir::TypeBinding {
|
||||||
hir_id: this.next_id(),
|
hir_id: this.next_id(),
|
||||||
@ -2102,7 +2107,7 @@ impl<'a> LoweringContext<'a> {
|
|||||||
ImplTraitContext::disallowed()
|
ImplTraitContext::disallowed()
|
||||||
))
|
))
|
||||||
.unwrap_or_else(||
|
.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),
|
span: output.as_ref().map_or(span, |ty| ty.span),
|
||||||
@ -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
|
// Foo = impl Trait` is, internally, created as a child of the
|
||||||
// async fn, so the *type parameters* are inherited. It's
|
// async fn, so the *type parameters* are inherited. It's
|
||||||
// only the lifetime parameters that we must supply.
|
// only the lifetime parameters that we must supply.
|
||||||
let opaque_ty_ref = hir::TyKind::Def(hir::ItemId { id: opaque_ty_id }, generic_args.into());
|
let opaque_ty_ref = hir::TyKind::Def(hir::ItemId { id: opaque_ty_id }, generic_args.into());
|
||||||
|
let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
|
||||||
hir::FunctionRetTy::Return(P(hir::Ty {
|
hir::FunctionRetTy::Return(P(opaque_ty))
|
||||||
kind: opaque_ty_ref,
|
|
||||||
span: opaque_ty_span,
|
|
||||||
hir_id: self.next_id(),
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transforms `-> T` into `Future<Output = T>`
|
/// Transforms `-> T` into `Future<Output = T>`
|
||||||
@ -2496,16 +2497,8 @@ impl<'a> LoweringContext<'a> {
|
|||||||
) -> hir::GenericBound {
|
) -> hir::GenericBound {
|
||||||
// Compute the `T` in `Future<Output = T>` from the return type.
|
// Compute the `T` in `Future<Output = T>` from the return type.
|
||||||
let output_ty = match output {
|
let output_ty = match output {
|
||||||
FunctionRetTy::Ty(ty) => {
|
FunctionRetTy::Ty(ty) => self.lower_ty(ty, ImplTraitContext::OpaqueTy(Some(fn_def_id))),
|
||||||
self.lower_ty(ty, ImplTraitContext::OpaqueTy(Some(fn_def_id)))
|
FunctionRetTy::Default(ret_ty_span) => P(self.ty_tup(*ret_ty_span, hir_vec![])),
|
||||||
}
|
|
||||||
FunctionRetTy::Default(ret_ty_span) => {
|
|
||||||
P(hir::Ty {
|
|
||||||
hir_id: self.next_id(),
|
|
||||||
kind: hir::TyKind::Tup(hir_vec![]),
|
|
||||||
span: *ret_ty_span,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// "<Output = T>"
|
// "<Output = T>"
|
||||||
|
@ -932,16 +932,21 @@ impl LoweringContext<'_> {
|
|||||||
|
|
||||||
(generics, hir::ImplItemKind::Method(sig, body_id))
|
(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 generics = self.lower_generics(&i.generics, ImplTraitContext::disallowed());
|
||||||
let kind = match ty.kind.opaque_top_hack() {
|
let kind = match ty {
|
||||||
None => {
|
None => {
|
||||||
let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
|
hir::ImplItemKind::TyAlias(P(self.ty(i.span, hir::TyKind::Err)))
|
||||||
hir::ImplItemKind::TyAlias(ty)
|
|
||||||
}
|
}
|
||||||
Some(bs) => {
|
Some(ty) => match ty.kind.opaque_top_hack() {
|
||||||
let bounds = self.lower_param_bounds(bs, ImplTraitContext::disallowed());
|
None => {
|
||||||
hir::ImplItemKind::OpaqueTy(bounds)
|
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)
|
(generics, kind)
|
||||||
@ -972,7 +977,10 @@ impl LoweringContext<'_> {
|
|||||||
defaultness: self.lower_defaultness(i.defaultness, true /* [1] */),
|
defaultness: self.lower_defaultness(i.defaultness, true /* [1] */),
|
||||||
kind: match &i.kind {
|
kind: match &i.kind {
|
||||||
ImplItemKind::Const(..) => hir::AssocItemKind::Const,
|
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,
|
None => hir::AssocItemKind::Type,
|
||||||
Some(_) => hir::AssocItemKind::OpaqueTy,
|
Some(_) => hir::AssocItemKind::OpaqueTy,
|
||||||
},
|
},
|
||||||
|
@ -697,8 +697,7 @@ impl<'a> Parser<'a> {
|
|||||||
let vis = self.parse_visibility(FollowedByType::No)?;
|
let vis = self.parse_visibility(FollowedByType::No)?;
|
||||||
let defaultness = self.parse_defaultness();
|
let defaultness = self.parse_defaultness();
|
||||||
let (name, kind, generics) = if self.eat_keyword(kw::Type) {
|
let (name, kind, generics) = if self.eat_keyword(kw::Type) {
|
||||||
let (name, ty, generics) = self.parse_type_alias()?;
|
self.parse_impl_assoc_ty()?
|
||||||
(name, ast::ImplItemKind::TyAlias(ty), generics)
|
|
||||||
} else if self.is_const_item() {
|
} else if self.is_const_item() {
|
||||||
self.parse_impl_const()?
|
self.parse_impl_const()?
|
||||||
} else if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(&vis), at_end)? {
|
} else if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(&vis), at_end)? {
|
||||||
@ -766,6 +765,31 @@ impl<'a> Parser<'a> {
|
|||||||
Ok((ident, ImplItemKind::Const(ty, expr), Generics::default()))
|
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;`.
|
/// Parses `auto? trait Foo { ... }` or `trait Foo = Bar;`.
|
||||||
fn parse_item_trait(&mut self, lo: Span, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
|
fn parse_item_trait(&mut self, lo: Span, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
|
||||||
// Parse optional `auto` prefix.
|
// Parse optional `auto` prefix.
|
||||||
@ -924,7 +948,7 @@ impl<'a> Parser<'a> {
|
|||||||
|
|
||||||
/// Parses the following grammar:
|
/// 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)> {
|
fn parse_trait_item_assoc_ty(&mut self) -> PResult<'a, (Ident, TraitItemKind, Generics)> {
|
||||||
let ident = self.parse_ident()?;
|
let ident = self.parse_ident()?;
|
||||||
let mut generics = self.parse_generics()?;
|
let mut generics = self.parse_generics()?;
|
||||||
|
@ -295,6 +295,17 @@ impl<'a> AstValidator<'a> {
|
|||||||
)
|
)
|
||||||
.emit();
|
.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 {
|
enum GenericPosition {
|
||||||
@ -770,6 +781,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||||||
self.check_impl_item_provided(ii.span, body, "function", " { <body> }");
|
self.check_impl_item_provided(ii.span, body, "function", " { <body> }");
|
||||||
self.check_fn_decl(&sig.decl);
|
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);
|
visit::walk_impl_item(self, ii);
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
|
#![feature(slice_patterns)]
|
||||||
|
|
||||||
#![recursion_limit="256"]
|
#![recursion_limit="256"]
|
||||||
|
|
||||||
|
@ -1119,7 +1119,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
|
|||||||
|
|
||||||
visit::walk_impl_item(this, impl_item);
|
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
|
// If this is a trait impl, ensure the type
|
||||||
// exists in trait
|
// exists in trait
|
||||||
this.check_trait_item(impl_item.ident,
|
this.check_trait_item(impl_item.ident,
|
||||||
@ -1129,6 +1129,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
|
|||||||
|
|
||||||
this.visit_ty(ty);
|
this.visit_ty(ty);
|
||||||
}
|
}
|
||||||
|
ImplItemKind::TyAlias(_, None) => {}
|
||||||
ImplItemKind::Macro(_) =>
|
ImplItemKind::Macro(_) =>
|
||||||
panic!("unexpanded macro in resolve!"),
|
panic!("unexpanded macro in resolve!"),
|
||||||
}
|
}
|
||||||
|
@ -1127,7 +1127,8 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
|
|||||||
impl_item.span,
|
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
|
// 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
|
// 'def' and the name here should be a ref to the def in the
|
||||||
// trait.
|
// trait.
|
||||||
|
@ -1638,7 +1638,7 @@ pub struct ImplItem<K = ImplItemKind> {
|
|||||||
pub enum ImplItemKind {
|
pub enum ImplItemKind {
|
||||||
Const(P<Ty>, Option<P<Expr>>),
|
Const(P<Ty>, Option<P<Expr>>),
|
||||||
Method(FnSig, Option<P<Block>>),
|
Method(FnSig, Option<P<Block>>),
|
||||||
TyAlias(P<Ty>),
|
TyAlias(GenericBounds, Option<P<Ty>>),
|
||||||
Macro(Mac),
|
Macro(Mac),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -612,8 +612,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
|||||||
"C-variadic functions are unstable");
|
"C-variadic functions are unstable");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::ImplItemKind::TyAlias(ref ty) => {
|
ast::ImplItemKind::TyAlias(_, ref ty) => {
|
||||||
self.check_impl_trait(ty);
|
if let Some(ty) = ty {
|
||||||
|
self.check_impl_trait(ty);
|
||||||
|
}
|
||||||
self.check_gat(&ii.generics, ii.span);
|
self.check_gat(&ii.generics, ii.span);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -987,7 +987,10 @@ pub fn noop_flat_map_impl_item<T: MutVisitor>(mut item: ImplItem, visitor: &mut
|
|||||||
visit_fn_sig(sig, visitor);
|
visit_fn_sig(sig, visitor);
|
||||||
visit_opt(body, |body| visitor.visit_block(body));
|
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),
|
ImplItemKind::Macro(mac) => visitor.visit_mac(mac),
|
||||||
}
|
}
|
||||||
visitor.visit_span(span);
|
visitor.visit_span(span);
|
||||||
|
@ -1128,16 +1128,15 @@ impl<'a> State<'a> {
|
|||||||
self.s.word(";")
|
self.s.word(";")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_associated_type(&mut self,
|
fn print_associated_type(
|
||||||
ident: ast::Ident,
|
&mut self,
|
||||||
bounds: Option<&ast::GenericBounds>,
|
ident: ast::Ident,
|
||||||
ty: Option<&ast::Ty>)
|
bounds: &ast::GenericBounds,
|
||||||
{
|
ty: Option<&ast::Ty>,
|
||||||
|
) {
|
||||||
self.word_space("type");
|
self.word_space("type");
|
||||||
self.print_ident(ident);
|
self.print_ident(ident);
|
||||||
if let Some(bounds) = bounds {
|
self.print_type_bounds(":", bounds);
|
||||||
self.print_type_bounds(":", bounds);
|
|
||||||
}
|
|
||||||
if let Some(ty) = ty {
|
if let Some(ty) = ty {
|
||||||
self.s.space();
|
self.s.space();
|
||||||
self.word_space("=");
|
self.word_space("=");
|
||||||
@ -1568,8 +1567,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::TraitItemKind::TyAlias(ref bounds, ref default) => {
|
ast::TraitItemKind::TyAlias(ref bounds, ref default) => {
|
||||||
self.print_associated_type(ti.ident, Some(bounds),
|
self.print_associated_type(ti.ident, bounds, default.as_deref());
|
||||||
default.as_ref().map(|ty| &**ty));
|
|
||||||
}
|
}
|
||||||
ast::TraitItemKind::Macro(ref mac) => {
|
ast::TraitItemKind::Macro(ref mac) => {
|
||||||
self.print_mac(mac);
|
self.print_mac(mac);
|
||||||
@ -1603,8 +1601,8 @@ impl<'a> State<'a> {
|
|||||||
self.s.word(";");
|
self.s.word(";");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::ImplItemKind::TyAlias(ref ty) => {
|
ast::ImplItemKind::TyAlias(ref bounds, ref ty) => {
|
||||||
self.print_associated_type(ii.ident, None, Some(ty));
|
self.print_associated_type(ii.ident, bounds, ty.as_deref());
|
||||||
}
|
}
|
||||||
ast::ImplItemKind::Macro(ref mac) => {
|
ast::ImplItemKind::Macro(ref mac) => {
|
||||||
self.print_mac(mac);
|
self.print_mac(mac);
|
||||||
|
@ -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),
|
visitor.visit_fn(FnKind::Method(impl_item.ident, sig, &impl_item.vis, body),
|
||||||
&sig.decl, impl_item.span, impl_item.id);
|
&sig.decl, impl_item.span, impl_item.id);
|
||||||
}
|
}
|
||||||
ImplItemKind::TyAlias(ref ty) => {
|
ImplItemKind::TyAlias(ref bounds, ref ty) => {
|
||||||
visitor.visit_ty(ty);
|
walk_list!(visitor, visit_param_bound, bounds);
|
||||||
|
walk_list!(visitor, visit_ty, ty);
|
||||||
}
|
}
|
||||||
ImplItemKind::Macro(ref mac) => {
|
ImplItemKind::Macro(ref mac) => {
|
||||||
visitor.visit_mac(mac);
|
visitor.visit_mac(mac);
|
||||||
|
@ -519,7 +519,9 @@ impl<'a> TraitDef<'a> {
|
|||||||
attrs: Vec::new(),
|
attrs: Vec::new(),
|
||||||
generics: Generics::default(),
|
generics: Generics::default(),
|
||||||
kind: ast::ImplItemKind::TyAlias(
|
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,
|
tokens: None,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
11
src/test/ui/parser/impl-item-type-no-body-pass.rs
Normal file
11
src/test/ui/parser/impl-item-type-no-body-pass.rs
Normal file
@ -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
src/test/ui/parser/impl-item-type-no-body-semantic-fail.rs
Normal file
22
src/test/ui/parser/impl-item-type-no-body-semantic-fail.rs
Normal file
@ -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
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
error: associated type in `impl` without body
|
||||||
|
--> $DIR/impl-item-type-no-body-semantic-fail.rs:9:5
|
||||||
|
|
|
||||||
|
LL | type Y;
|
||||||
|
| ^^^^^^-
|
||||||
|
| |
|
||||||
|
| help: provide a definition for the type: `= <type>;`
|
||||||
|
|
||||||
|
error: associated type in `impl` without body
|
||||||
|
--> $DIR/impl-item-type-no-body-semantic-fail.rs:12:5
|
||||||
|
|
|
||||||
|
LL | type Z: Ord;
|
||||||
|
| ^^^^^^^^^^^-
|
||||||
|
| |
|
||||||
|
| help: provide a definition for the type: `= <type>;`
|
||||||
|
|
||||||
|
error: bounds on associated `type`s in `impl`s have no effect
|
||||||
|
--> $DIR/impl-item-type-no-body-semantic-fail.rs:12:13
|
||||||
|
|
|
||||||
|
LL | type Z: Ord;
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: associated type in `impl` without body
|
||||||
|
--> $DIR/impl-item-type-no-body-semantic-fail.rs:16:5
|
||||||
|
|
|
||||||
|
LL | type W: Ord where Self: Eq;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^-
|
||||||
|
| |
|
||||||
|
| help: provide a definition for the type: `= <type>;`
|
||||||
|
|
||||||
|
error: bounds on associated `type`s in `impl`s have no effect
|
||||||
|
--> $DIR/impl-item-type-no-body-semantic-fail.rs:16:13
|
||||||
|
|
|
||||||
|
LL | type W: Ord where Self: Eq;
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: associated type in `impl` without body
|
||||||
|
--> $DIR/impl-item-type-no-body-semantic-fail.rs:20:5
|
||||||
|
|
|
||||||
|
LL | type W where Self: Eq;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^-
|
||||||
|
| |
|
||||||
|
| help: provide a definition for the type: `= <type>;`
|
||||||
|
|
||||||
|
warning: the feature `generic_associated_types` is incomplete and may cause the compiler to crash
|
||||||
|
--> $DIR/impl-item-type-no-body-semantic-fail.rs:1:12
|
||||||
|
|
|
||||||
|
LL | #![feature(generic_associated_types)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
error[E0202]: associated types are not yet supported in inherent impls (see #8995)
|
||||||
|
--> $DIR/impl-item-type-no-body-semantic-fail.rs:9:5
|
||||||
|
|
|
||||||
|
LL | type Y;
|
||||||
|
| ^^^^^^^
|
||||||
|
|
||||||
|
error[E0202]: associated types are not yet supported in inherent impls (see #8995)
|
||||||
|
--> $DIR/impl-item-type-no-body-semantic-fail.rs:12:5
|
||||||
|
|
|
||||||
|
LL | type Z: Ord;
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0202]: associated types are not yet supported in inherent impls (see #8995)
|
||||||
|
--> $DIR/impl-item-type-no-body-semantic-fail.rs:16:5
|
||||||
|
|
|
||||||
|
LL | type W: Ord where Self: Eq;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 9 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0202`.
|
Loading…
Reference in New Issue
Block a user