mirror of
https://github.com/openharmony/third_party_rust_rust.git
synced 2026-07-18 17:34:40 -04:00
Auto merge of #45047 - durka:trait-alias, r=petrochenkov
trait alias infrastructure This will be an implementation of trait aliases (RFC 1733, #41517). Progress so far: - [x] Feature gate - [x] Add to parser - [x] `where` clauses - [x] prohibit LHS type parameter bounds via AST validation https://github.com/rust-lang/rust/pull/45047#discussion_r143575575 - [x] Add to AST and HIR - [x] make a separate PathSource for trait alias contexts https://github.com/rust-lang/rust/pull/45047#discussion_r143353932 - [x] Stub out enough of typeck and resolve to just barely not ICE Postponed: - [ ] Actually implement the alias part - [ ] #21903 - [ ] #24010 I need some pointers on where to start with that last one. The test currently does this: ``` error[E0283]: type annotations required: cannot resolve `_: CD` --> src/test/run-pass/trait-alias.rs:34:16 | 34 | let both = foo(); | ^^^ | = note: required by `foo` ```
This commit is contained in:
@@ -37,6 +37,7 @@ pub enum Def {
|
|||||||
Trait(DefId),
|
Trait(DefId),
|
||||||
TyAlias(DefId),
|
TyAlias(DefId),
|
||||||
TyForeign(DefId),
|
TyForeign(DefId),
|
||||||
|
TraitAlias(DefId),
|
||||||
AssociatedTy(DefId),
|
AssociatedTy(DefId),
|
||||||
PrimTy(hir::PrimTy),
|
PrimTy(hir::PrimTy),
|
||||||
TyParam(DefId),
|
TyParam(DefId),
|
||||||
@@ -155,7 +156,8 @@ impl Def {
|
|||||||
pub fn def_id(&self) -> DefId {
|
pub fn def_id(&self) -> DefId {
|
||||||
match *self {
|
match *self {
|
||||||
Def::Fn(id) | Def::Mod(id) | Def::Static(id, _) |
|
Def::Fn(id) | Def::Mod(id) | Def::Static(id, _) |
|
||||||
Def::Variant(id) | Def::VariantCtor(id, ..) | Def::Enum(id) | Def::TyAlias(id) |
|
Def::Variant(id) | Def::VariantCtor(id, ..) | Def::Enum(id) |
|
||||||
|
Def::TyAlias(id) | Def::TraitAlias(id) |
|
||||||
Def::AssociatedTy(id) | Def::TyParam(id) | Def::Struct(id) | Def::StructCtor(id, ..) |
|
Def::AssociatedTy(id) | Def::TyParam(id) | Def::Struct(id) | Def::StructCtor(id, ..) |
|
||||||
Def::Union(id) | Def::Trait(id) | Def::Method(id) | Def::Const(id) |
|
Def::Union(id) | Def::Trait(id) | Def::Method(id) | Def::Const(id) |
|
||||||
Def::AssociatedConst(id) | Def::Macro(id, ..) |
|
Def::AssociatedConst(id) | Def::Macro(id, ..) |
|
||||||
@@ -186,6 +188,7 @@ impl Def {
|
|||||||
Def::VariantCtor(.., CtorKind::Fictive) => "struct variant",
|
Def::VariantCtor(.., CtorKind::Fictive) => "struct variant",
|
||||||
Def::Enum(..) => "enum",
|
Def::Enum(..) => "enum",
|
||||||
Def::TyAlias(..) => "type alias",
|
Def::TyAlias(..) => "type alias",
|
||||||
|
Def::TraitAlias(..) => "trait alias",
|
||||||
Def::AssociatedTy(..) => "associated type",
|
Def::AssociatedTy(..) => "associated type",
|
||||||
Def::Struct(..) => "struct",
|
Def::Struct(..) => "struct",
|
||||||
Def::StructCtor(.., CtorKind::Fn) => "tuple struct",
|
Def::StructCtor(.., CtorKind::Fn) => "tuple struct",
|
||||||
|
|||||||
@@ -526,6 +526,11 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
|
|||||||
walk_list!(visitor, visit_ty_param_bound, bounds);
|
walk_list!(visitor, visit_ty_param_bound, bounds);
|
||||||
walk_list!(visitor, visit_trait_item_ref, trait_item_refs);
|
walk_list!(visitor, visit_trait_item_ref, trait_item_refs);
|
||||||
}
|
}
|
||||||
|
ItemTraitAlias(ref generics, ref bounds) => {
|
||||||
|
visitor.visit_id(item.id);
|
||||||
|
visitor.visit_generics(generics);
|
||||||
|
walk_list!(visitor, visit_ty_param_bound, bounds);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
walk_list!(visitor, visit_attribute, &item.attrs);
|
walk_list!(visitor, visit_attribute, &item.attrs);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1924,9 +1924,11 @@ impl<'a> LoweringContext<'a> {
|
|||||||
bounds,
|
bounds,
|
||||||
items)
|
items)
|
||||||
}
|
}
|
||||||
ItemKind::MacroDef(..) | ItemKind::Mac(..) => {
|
ItemKind::TraitAlias(ref generics, ref bounds) => {
|
||||||
panic!("Shouldn't still be around")
|
hir::ItemTraitAlias(self.lower_generics(generics),
|
||||||
|
self.lower_bounds(bounds, ImplTraitContext::Disallowed))
|
||||||
}
|
}
|
||||||
|
ItemKind::MacroDef(..) | ItemKind::Mac(..) => panic!("Shouldn't still be around"),
|
||||||
}
|
}
|
||||||
|
|
||||||
// [1] `defaultness.has_value()` is never called for an `impl`, always `true` in order to
|
// [1] `defaultness.has_value()` is never called for an `impl`, always `true` in order to
|
||||||
|
|||||||
@@ -106,7 +106,8 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
|||||||
let def_data = match i.node {
|
let def_data = match i.node {
|
||||||
ItemKind::AutoImpl(..) | ItemKind::Impl(..) =>
|
ItemKind::AutoImpl(..) | ItemKind::Impl(..) =>
|
||||||
DefPathData::Impl,
|
DefPathData::Impl,
|
||||||
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) | ItemKind::Trait(..) |
|
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) |
|
||||||
|
ItemKind::Trait(..) | ItemKind::TraitAlias(..) |
|
||||||
ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::Ty(..) =>
|
ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::Ty(..) =>
|
||||||
DefPathData::TypeNs(i.ident.name.as_str()),
|
DefPathData::TypeNs(i.ident.name.as_str()),
|
||||||
ItemKind::Mod(..) if i.ident == keywords::Invalid.ident() => {
|
ItemKind::Mod(..) if i.ident == keywords::Invalid.ident() => {
|
||||||
|
|||||||
@@ -1185,6 +1185,7 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
|
|||||||
ItemStruct(..) => "struct",
|
ItemStruct(..) => "struct",
|
||||||
ItemUnion(..) => "union",
|
ItemUnion(..) => "union",
|
||||||
ItemTrait(..) => "trait",
|
ItemTrait(..) => "trait",
|
||||||
|
ItemTraitAlias(..) => "trait alias",
|
||||||
ItemImpl(..) => "impl",
|
ItemImpl(..) => "impl",
|
||||||
ItemAutoImpl(..) => "default impl",
|
ItemAutoImpl(..) => "default impl",
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1888,6 +1888,8 @@ pub enum Item_ {
|
|||||||
ItemUnion(VariantData, Generics),
|
ItemUnion(VariantData, Generics),
|
||||||
/// Represents a Trait Declaration
|
/// Represents a Trait Declaration
|
||||||
ItemTrait(IsAuto, Unsafety, Generics, TyParamBounds, HirVec<TraitItemRef>),
|
ItemTrait(IsAuto, Unsafety, Generics, TyParamBounds, HirVec<TraitItemRef>),
|
||||||
|
/// Represents a Trait Alias Declaration
|
||||||
|
ItemTraitAlias(Generics, TyParamBounds),
|
||||||
|
|
||||||
/// Auto trait implementations
|
/// Auto trait implementations
|
||||||
///
|
///
|
||||||
@@ -1919,6 +1921,7 @@ impl Item_ {
|
|||||||
ItemStruct(..) => "struct",
|
ItemStruct(..) => "struct",
|
||||||
ItemUnion(..) => "union",
|
ItemUnion(..) => "union",
|
||||||
ItemTrait(..) => "trait",
|
ItemTrait(..) => "trait",
|
||||||
|
ItemTraitAlias(..) => "trait alias",
|
||||||
ItemImpl(..) |
|
ItemImpl(..) |
|
||||||
ItemAutoImpl(..) => "item",
|
ItemAutoImpl(..) => "item",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -747,6 +747,27 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
self.bclose(item.span)?;
|
self.bclose(item.span)?;
|
||||||
}
|
}
|
||||||
|
hir::ItemTraitAlias(ref generics, ref bounds) => {
|
||||||
|
self.head("")?;
|
||||||
|
self.print_visibility(&item.vis)?;
|
||||||
|
self.word_nbsp("trait")?;
|
||||||
|
self.print_name(item.name)?;
|
||||||
|
self.print_generics(generics)?;
|
||||||
|
let mut real_bounds = Vec::with_capacity(bounds.len());
|
||||||
|
// FIXME(durka) this seems to be some quite outdated syntax
|
||||||
|
for b in bounds.iter() {
|
||||||
|
if let TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
|
||||||
|
self.s.space()?;
|
||||||
|
self.word_space("for ?")?;
|
||||||
|
self.print_trait_ref(&ptr.trait_ref)?;
|
||||||
|
} else {
|
||||||
|
real_bounds.push(b.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.print_bounds(" = ", &real_bounds[..])?;
|
||||||
|
self.print_where_clause(&generics.where_clause)?;
|
||||||
|
self.s.word(";")?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.ann.post(self, NodeItem(item))
|
self.ann.post(self, NodeItem(item))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -848,6 +848,7 @@ impl_stable_hash_for!(enum hir::Item_ {
|
|||||||
ItemStruct(variant_data, generics),
|
ItemStruct(variant_data, generics),
|
||||||
ItemUnion(variant_data, generics),
|
ItemUnion(variant_data, generics),
|
||||||
ItemTrait(is_auto, unsafety, generics, bounds, item_refs),
|
ItemTrait(is_auto, unsafety, generics, bounds, item_refs),
|
||||||
|
ItemTraitAlias(generics, bounds),
|
||||||
ItemAutoImpl(unsafety, trait_ref),
|
ItemAutoImpl(unsafety, trait_ref),
|
||||||
ItemImpl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
|
ItemImpl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
|
||||||
});
|
});
|
||||||
@@ -1004,6 +1005,7 @@ impl_stable_hash_for!(enum hir::def::Def {
|
|||||||
Variant(def_id),
|
Variant(def_id),
|
||||||
Trait(def_id),
|
Trait(def_id),
|
||||||
TyAlias(def_id),
|
TyAlias(def_id),
|
||||||
|
TraitAlias(def_id),
|
||||||
AssociatedTy(def_id),
|
AssociatedTy(def_id),
|
||||||
PrimTy(prim_ty),
|
PrimTy(prim_ty),
|
||||||
TyParam(def_id),
|
TyParam(def_id),
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
|
|||||||
hir::ItemExternCrate(_) | hir::ItemUse(..) |
|
hir::ItemExternCrate(_) | hir::ItemUse(..) |
|
||||||
hir::ItemTy(..) | hir::ItemStatic(..) |
|
hir::ItemTy(..) | hir::ItemStatic(..) |
|
||||||
hir::ItemMod(..) | hir::ItemForeignMod(..) |
|
hir::ItemMod(..) | hir::ItemForeignMod(..) |
|
||||||
hir::ItemImpl(..) | hir::ItemTrait(..) |
|
hir::ItemImpl(..) | hir::ItemTrait(..) | hir::ItemTraitAlias(..) |
|
||||||
hir::ItemStruct(..) | hir::ItemEnum(..) |
|
hir::ItemStruct(..) | hir::ItemEnum(..) |
|
||||||
hir::ItemUnion(..) | hir::ItemAutoImpl(..) |
|
hir::ItemUnion(..) | hir::ItemAutoImpl(..) |
|
||||||
hir::ItemGlobalAsm(..) => {}
|
hir::ItemGlobalAsm(..) => {}
|
||||||
|
|||||||
@@ -469,6 +469,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||||||
| hir::ItemStruct(_, ref generics)
|
| hir::ItemStruct(_, ref generics)
|
||||||
| hir::ItemUnion(_, ref generics)
|
| hir::ItemUnion(_, ref generics)
|
||||||
| hir::ItemTrait(_, _, ref generics, ..)
|
| hir::ItemTrait(_, _, ref generics, ..)
|
||||||
|
| hir::ItemTraitAlias(ref generics, ..)
|
||||||
| hir::ItemImpl(_, _, _, ref generics, ..) => {
|
| hir::ItemImpl(_, _, _, ref generics, ..) => {
|
||||||
// These kinds of items have only early bound lifetime parameters.
|
// These kinds of items have only early bound lifetime parameters.
|
||||||
let mut index = if let hir::ItemTrait(..) = item.node {
|
let mut index = if let hir::ItemTrait(..) = item.node {
|
||||||
|
|||||||
@@ -2577,6 +2577,7 @@ fn associated_item_def_ids<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
.map(|id| tcx.hir.local_def_id(id.node_id))
|
.map(|id| tcx.hir.local_def_id(id.node_id))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
hir::ItemTraitAlias(..) => vec![],
|
||||||
_ => span_bug!(item.span, "associated_item_def_ids: not impl or trait")
|
_ => span_bug!(item.span, "associated_item_def_ids: not impl or trait")
|
||||||
};
|
};
|
||||||
Rc::new(vec)
|
Rc::new(vec)
|
||||||
|
|||||||
@@ -248,6 +248,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
|
|||||||
hir::ItemStruct(..) |
|
hir::ItemStruct(..) |
|
||||||
hir::ItemUnion(..) |
|
hir::ItemUnion(..) |
|
||||||
hir::ItemTrait(..) |
|
hir::ItemTrait(..) |
|
||||||
|
hir::ItemTraitAlias(..) |
|
||||||
hir::ItemImpl(..) |
|
hir::ItemImpl(..) |
|
||||||
hir::ItemAutoImpl(..) => None,
|
hir::ItemAutoImpl(..) => None,
|
||||||
|
|
||||||
|
|||||||
@@ -979,6 +979,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
|||||||
EntryKind::Trait(self.lazy(&data))
|
EntryKind::Trait(self.lazy(&data))
|
||||||
}
|
}
|
||||||
hir::ItemExternCrate(_) |
|
hir::ItemExternCrate(_) |
|
||||||
|
hir::ItemTraitAlias(..) |
|
||||||
hir::ItemUse(..) => bug!("cannot encode info for item {:?}", item),
|
hir::ItemUse(..) => bug!("cannot encode info for item {:?}", item),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1526,7 +1527,8 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
|
|||||||
hir::ItemExternCrate(..) |
|
hir::ItemExternCrate(..) |
|
||||||
hir::ItemUse(..) |
|
hir::ItemUse(..) |
|
||||||
hir::ItemAutoImpl(..) |
|
hir::ItemAutoImpl(..) |
|
||||||
hir::ItemTy(..) => {
|
hir::ItemTy(..) |
|
||||||
|
hir::ItemTraitAlias(..) => {
|
||||||
// no sub-item recording needed in these cases
|
// no sub-item recording needed in these cases
|
||||||
}
|
}
|
||||||
hir::ItemEnum(..) => {
|
hir::ItemEnum(..) => {
|
||||||
|
|||||||
@@ -283,6 +283,20 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ItemKind::TraitAlias(Generics { ref ty_params, .. }, ..) => {
|
||||||
|
for &TyParam { ref bounds, ref default, span, .. } in ty_params {
|
||||||
|
if !bounds.is_empty() {
|
||||||
|
self.err_handler().span_err(span,
|
||||||
|
"type parameters on the left side of a \
|
||||||
|
trait alias cannot be bounded");
|
||||||
|
}
|
||||||
|
if !default.is_none() {
|
||||||
|
self.err_handler().span_err(span,
|
||||||
|
"type parameters on the left side of a \
|
||||||
|
trait alias cannot have defaults");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
ItemKind::Mod(_) => {
|
ItemKind::Mod(_) => {
|
||||||
// Ensure that `path` attributes on modules are recorded as used (c.f. #35584).
|
// Ensure that `path` attributes on modules are recorded as used (c.f. #35584).
|
||||||
attr::first_attr_value_str_by_name(&item.attrs, "path");
|
attr::first_attr_value_str_by_name(&item.attrs, "path");
|
||||||
|
|||||||
@@ -158,7 +158,8 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
|
|||||||
// Other `pub` items inherit levels from parents
|
// Other `pub` items inherit levels from parents
|
||||||
hir::ItemConst(..) | hir::ItemEnum(..) | hir::ItemExternCrate(..) |
|
hir::ItemConst(..) | hir::ItemEnum(..) | hir::ItemExternCrate(..) |
|
||||||
hir::ItemGlobalAsm(..) | hir::ItemFn(..) | hir::ItemMod(..) |
|
hir::ItemGlobalAsm(..) | hir::ItemFn(..) | hir::ItemMod(..) |
|
||||||
hir::ItemStatic(..) | hir::ItemStruct(..) | hir::ItemTrait(..) |
|
hir::ItemStatic(..) | hir::ItemStruct(..) |
|
||||||
|
hir::ItemTrait(..) | hir::ItemTraitAlias(..) |
|
||||||
hir::ItemTy(..) | hir::ItemUnion(..) | hir::ItemUse(..) => {
|
hir::ItemTy(..) | hir::ItemUnion(..) | hir::ItemUse(..) => {
|
||||||
if item.vis == hir::Public { self.prev_level } else { None }
|
if item.vis == hir::Public { self.prev_level } else { None }
|
||||||
}
|
}
|
||||||
@@ -212,7 +213,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::ItemUse(..) | hir::ItemStatic(..) | hir::ItemConst(..) |
|
hir::ItemUse(..) | hir::ItemStatic(..) | hir::ItemConst(..) |
|
||||||
hir::ItemGlobalAsm(..) | hir::ItemTy(..) | hir::ItemMod(..) |
|
hir::ItemGlobalAsm(..) | hir::ItemTy(..) | hir::ItemMod(..) | hir::ItemTraitAlias(..) |
|
||||||
hir::ItemFn(..) | hir::ItemExternCrate(..) | hir::ItemAutoImpl(..) => {}
|
hir::ItemFn(..) | hir::ItemExternCrate(..) | hir::ItemAutoImpl(..) => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,6 +253,11 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
hir::ItemTraitAlias(..) => {
|
||||||
|
if item_level.is_some() {
|
||||||
|
self.reach(item.id).generics().predicates();
|
||||||
|
}
|
||||||
|
}
|
||||||
// Visit everything except for private impl items
|
// Visit everything except for private impl items
|
||||||
hir::ItemImpl(.., ref trait_ref, _, ref impl_item_refs) => {
|
hir::ItemImpl(.., ref trait_ref, _, ref impl_item_refs) => {
|
||||||
if item_level.is_some() {
|
if item_level.is_some() {
|
||||||
@@ -1498,6 +1504,9 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
hir::ItemTraitAlias(..) => {
|
||||||
|
self.check(item.id, item_visibility).generics().predicates();
|
||||||
|
}
|
||||||
hir::ItemEnum(ref def, _) => {
|
hir::ItemEnum(ref def, _) => {
|
||||||
self.check(item.id, item_visibility).generics().predicates();
|
self.check(item.id, item_visibility).generics().predicates();
|
||||||
|
|
||||||
|
|||||||
@@ -344,6 +344,11 @@ impl<'a> Resolver<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ItemKind::TraitAlias(..) => {
|
||||||
|
let def = Def::TraitAlias(self.definitions.local_def_id(item.id));
|
||||||
|
self.define(parent, ident, TypeNS, (def, vis, sp, expansion));
|
||||||
|
}
|
||||||
|
|
||||||
// These items live in both the type and value namespaces.
|
// These items live in both the type and value namespaces.
|
||||||
ItemKind::Struct(ref struct_def, _) => {
|
ItemKind::Struct(ref struct_def, _) => {
|
||||||
// Define a name in the type namespace.
|
// Define a name in the type namespace.
|
||||||
@@ -411,6 +416,7 @@ impl<'a> Resolver<'a> {
|
|||||||
self.define(parent, ident, TypeNS, (module, vis, sp, expansion));
|
self.define(parent, ident, TypeNS, (module, vis, sp, expansion));
|
||||||
self.current_module = module;
|
self.current_module = module;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemKind::MacroDef(..) | ItemKind::Mac(_) => unreachable!(),
|
ItemKind::MacroDef(..) | ItemKind::Mac(_) => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-11
@@ -390,12 +390,18 @@ impl PatternSource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||||
|
enum AliasPossibility {
|
||||||
|
No,
|
||||||
|
Maybe,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||||
enum PathSource<'a> {
|
enum PathSource<'a> {
|
||||||
// Type paths `Path`.
|
// Type paths `Path`.
|
||||||
Type,
|
Type,
|
||||||
// Trait paths in bounds or impls.
|
// Trait paths in bounds or impls.
|
||||||
Trait,
|
Trait(AliasPossibility),
|
||||||
// Expression paths `path`, with optional parent context.
|
// Expression paths `path`, with optional parent context.
|
||||||
Expr(Option<&'a Expr>),
|
Expr(Option<&'a Expr>),
|
||||||
// Paths in path patterns `Path`.
|
// Paths in path patterns `Path`.
|
||||||
@@ -415,7 +421,7 @@ enum PathSource<'a> {
|
|||||||
impl<'a> PathSource<'a> {
|
impl<'a> PathSource<'a> {
|
||||||
fn namespace(self) -> Namespace {
|
fn namespace(self) -> Namespace {
|
||||||
match self {
|
match self {
|
||||||
PathSource::Type | PathSource::Trait | PathSource::Struct |
|
PathSource::Type | PathSource::Trait(_) | PathSource::Struct |
|
||||||
PathSource::Visibility | PathSource::ImportPrefix => TypeNS,
|
PathSource::Visibility | PathSource::ImportPrefix => TypeNS,
|
||||||
PathSource::Expr(..) | PathSource::Pat | PathSource::TupleStruct => ValueNS,
|
PathSource::Expr(..) | PathSource::Pat | PathSource::TupleStruct => ValueNS,
|
||||||
PathSource::TraitItem(ns) => ns,
|
PathSource::TraitItem(ns) => ns,
|
||||||
@@ -427,7 +433,7 @@ impl<'a> PathSource<'a> {
|
|||||||
PathSource::Visibility | PathSource::ImportPrefix => true,
|
PathSource::Visibility | PathSource::ImportPrefix => true,
|
||||||
PathSource::Type | PathSource::Expr(..) | PathSource::Pat |
|
PathSource::Type | PathSource::Expr(..) | PathSource::Pat |
|
||||||
PathSource::Struct | PathSource::TupleStruct |
|
PathSource::Struct | PathSource::TupleStruct |
|
||||||
PathSource::Trait | PathSource::TraitItem(..) => false,
|
PathSource::Trait(_) | PathSource::TraitItem(..) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -435,7 +441,7 @@ impl<'a> PathSource<'a> {
|
|||||||
match self {
|
match self {
|
||||||
PathSource::Type | PathSource::Expr(..) | PathSource::Pat |
|
PathSource::Type | PathSource::Expr(..) | PathSource::Pat |
|
||||||
PathSource::Struct | PathSource::TupleStruct => true,
|
PathSource::Struct | PathSource::TupleStruct => true,
|
||||||
PathSource::Trait | PathSource::TraitItem(..) |
|
PathSource::Trait(_) | PathSource::TraitItem(..) |
|
||||||
PathSource::Visibility | PathSource::ImportPrefix => false,
|
PathSource::Visibility | PathSource::ImportPrefix => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -443,7 +449,7 @@ impl<'a> PathSource<'a> {
|
|||||||
fn descr_expected(self) -> &'static str {
|
fn descr_expected(self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
PathSource::Type => "type",
|
PathSource::Type => "type",
|
||||||
PathSource::Trait => "trait",
|
PathSource::Trait(_) => "trait",
|
||||||
PathSource::Pat => "unit struct/variant or constant",
|
PathSource::Pat => "unit struct/variant or constant",
|
||||||
PathSource::Struct => "struct, variant or union type",
|
PathSource::Struct => "struct, variant or union type",
|
||||||
PathSource::TupleStruct => "tuple struct/variant",
|
PathSource::TupleStruct => "tuple struct/variant",
|
||||||
@@ -472,10 +478,15 @@ impl<'a> PathSource<'a> {
|
|||||||
Def::TyForeign(..) => true,
|
Def::TyForeign(..) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
PathSource::Trait => match def {
|
PathSource::Trait(AliasPossibility::No) => match def {
|
||||||
Def::Trait(..) => true,
|
Def::Trait(..) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
|
PathSource::Trait(AliasPossibility::Maybe) => match def {
|
||||||
|
Def::Trait(..) => true,
|
||||||
|
Def::TraitAlias(..) => true,
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
PathSource::Expr(..) => match def {
|
PathSource::Expr(..) => match def {
|
||||||
Def::StructCtor(_, CtorKind::Const) | Def::StructCtor(_, CtorKind::Fn) |
|
Def::StructCtor(_, CtorKind::Const) | Def::StructCtor(_, CtorKind::Fn) |
|
||||||
Def::VariantCtor(_, CtorKind::Const) | Def::VariantCtor(_, CtorKind::Fn) |
|
Def::VariantCtor(_, CtorKind::Const) | Def::VariantCtor(_, CtorKind::Fn) |
|
||||||
@@ -530,8 +541,8 @@ impl<'a> PathSource<'a> {
|
|||||||
__diagnostic_used!(E0577);
|
__diagnostic_used!(E0577);
|
||||||
__diagnostic_used!(E0578);
|
__diagnostic_used!(E0578);
|
||||||
match (self, has_unexpected_resolution) {
|
match (self, has_unexpected_resolution) {
|
||||||
(PathSource::Trait, true) => "E0404",
|
(PathSource::Trait(_), true) => "E0404",
|
||||||
(PathSource::Trait, false) => "E0405",
|
(PathSource::Trait(_), false) => "E0405",
|
||||||
(PathSource::Type, true) => "E0573",
|
(PathSource::Type, true) => "E0573",
|
||||||
(PathSource::Type, false) => "E0412",
|
(PathSource::Type, false) => "E0412",
|
||||||
(PathSource::Struct, true) => "E0574",
|
(PathSource::Struct, true) => "E0574",
|
||||||
@@ -693,7 +704,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
|
|||||||
tref: &'tcx ast::PolyTraitRef,
|
tref: &'tcx ast::PolyTraitRef,
|
||||||
m: &'tcx ast::TraitBoundModifier) {
|
m: &'tcx ast::TraitBoundModifier) {
|
||||||
self.smart_resolve_path(tref.trait_ref.ref_id, None,
|
self.smart_resolve_path(tref.trait_ref.ref_id, None,
|
||||||
&tref.trait_ref.path, PathSource::Trait);
|
&tref.trait_ref.path, PathSource::Trait(AliasPossibility::Maybe));
|
||||||
visit::walk_poly_trait_ref(self, tref, m);
|
visit::walk_poly_trait_ref(self, tref, m);
|
||||||
}
|
}
|
||||||
fn visit_variant(&mut self,
|
fn visit_variant(&mut self,
|
||||||
@@ -1935,6 +1946,17 @@ impl<'a> Resolver<'a> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ItemKind::TraitAlias(ref generics, ref bounds) => {
|
||||||
|
// Create a new rib for the trait-wide type parameters.
|
||||||
|
self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| {
|
||||||
|
let local_def_id = this.definitions.local_def_id(item.id);
|
||||||
|
this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| {
|
||||||
|
this.visit_generics(generics);
|
||||||
|
walk_list!(this, visit_ty_param_bound, bounds);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
ItemKind::Mod(_) | ItemKind::ForeignMod(_) => {
|
ItemKind::Mod(_) | ItemKind::ForeignMod(_) => {
|
||||||
self.with_scope(item.id, |this| {
|
self.with_scope(item.id, |this| {
|
||||||
visit::walk_item(this, item);
|
visit::walk_item(this, item);
|
||||||
@@ -2083,7 +2105,7 @@ impl<'a> Resolver<'a> {
|
|||||||
&path,
|
&path,
|
||||||
trait_ref.path.span,
|
trait_ref.path.span,
|
||||||
trait_ref.path.segments.last().unwrap().span,
|
trait_ref.path.segments.last().unwrap().span,
|
||||||
PathSource::Trait)
|
PathSource::Trait(AliasPossibility::No))
|
||||||
.base_def();
|
.base_def();
|
||||||
if def != Def::Err {
|
if def != Def::Err {
|
||||||
new_id = Some(def.def_id());
|
new_id = Some(def.def_id());
|
||||||
@@ -2635,7 +2657,7 @@ impl<'a> Resolver<'a> {
|
|||||||
err.span_label(span, format!("did you mean `{}!(...)`?", path_str));
|
err.span_label(span, format!("did you mean `{}!(...)`?", path_str));
|
||||||
return (err, candidates);
|
return (err, candidates);
|
||||||
}
|
}
|
||||||
(Def::TyAlias(..), PathSource::Trait) => {
|
(Def::TyAlias(..), PathSource::Trait(_)) => {
|
||||||
err.span_label(span, "type aliases cannot be used for traits");
|
err.span_label(span, "type aliases cannot be used for traits");
|
||||||
return (err, candidates);
|
return (err, candidates);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -285,6 +285,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
|||||||
HirDef::Enum(..) |
|
HirDef::Enum(..) |
|
||||||
HirDef::TyAlias(..) |
|
HirDef::TyAlias(..) |
|
||||||
HirDef::TyForeign(..) |
|
HirDef::TyForeign(..) |
|
||||||
|
HirDef::TraitAlias(..) |
|
||||||
HirDef::Trait(_) => {
|
HirDef::Trait(_) => {
|
||||||
let span = self.span_from_span(sub_span.expect("No span found for type ref"));
|
let span = self.span_from_span(sub_span.expect("No span found for type ref"));
|
||||||
self.dumper.dump_ref(Ref {
|
self.dumper.dump_ref(Ref {
|
||||||
|
|||||||
@@ -721,6 +721,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
|||||||
HirDef::Enum(def_id) |
|
HirDef::Enum(def_id) |
|
||||||
HirDef::TyAlias(def_id) |
|
HirDef::TyAlias(def_id) |
|
||||||
HirDef::TyForeign(def_id) |
|
HirDef::TyForeign(def_id) |
|
||||||
|
HirDef::TraitAlias(def_id) |
|
||||||
HirDef::AssociatedTy(def_id) |
|
HirDef::AssociatedTy(def_id) |
|
||||||
HirDef::Trait(def_id) |
|
HirDef::Trait(def_id) |
|
||||||
HirDef::TyParam(def_id) => {
|
HirDef::TyParam(def_id) => {
|
||||||
|
|||||||
@@ -487,6 +487,25 @@ impl Sig for ast::Item {
|
|||||||
|
|
||||||
Ok(sig)
|
Ok(sig)
|
||||||
}
|
}
|
||||||
|
ast::ItemKind::TraitAlias(ref generics, ref bounds) => {
|
||||||
|
let mut text = String::new();
|
||||||
|
text.push_str("trait ");
|
||||||
|
let mut sig = name_and_generics(text,
|
||||||
|
offset,
|
||||||
|
generics,
|
||||||
|
self.id,
|
||||||
|
self.ident,
|
||||||
|
scx)?;
|
||||||
|
|
||||||
|
if !bounds.is_empty() {
|
||||||
|
sig.text.push_str(" = ");
|
||||||
|
sig.text.push_str(&pprust::bounds_to_string(bounds));
|
||||||
|
}
|
||||||
|
// FIXME where clause
|
||||||
|
sig.text.push_str(";");
|
||||||
|
|
||||||
|
Ok(sig)
|
||||||
|
}
|
||||||
ast::ItemKind::AutoImpl(unsafety, ref trait_ref) => {
|
ast::ItemKind::AutoImpl(unsafety, ref trait_ref) => {
|
||||||
let mut text = String::new();
|
let mut text = String::new();
|
||||||
if unsafety == ast::Unsafety::Unsafe {
|
if unsafety == ast::Unsafety::Unsafe {
|
||||||
|
|||||||
@@ -894,6 +894,7 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> {
|
|||||||
hir::ItemTy(..) |
|
hir::ItemTy(..) |
|
||||||
hir::ItemAutoImpl(..) |
|
hir::ItemAutoImpl(..) |
|
||||||
hir::ItemTrait(..) |
|
hir::ItemTrait(..) |
|
||||||
|
hir::ItemTraitAlias(..) |
|
||||||
hir::ItemMod(..) => {
|
hir::ItemMod(..) => {
|
||||||
// Nothing to do, just keep recursing...
|
// Nothing to do, just keep recursing...
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -336,6 +336,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||||||
let path = &trait_ref.path;
|
let path = &trait_ref.path;
|
||||||
match path.def {
|
match path.def {
|
||||||
Def::Trait(trait_def_id) => trait_def_id,
|
Def::Trait(trait_def_id) => trait_def_id,
|
||||||
|
Def::TraitAlias(alias_def_id) => alias_def_id,
|
||||||
Def::Err => {
|
Def::Err => {
|
||||||
self.tcx().sess.fatal("cannot continue compilation due to previous error");
|
self.tcx().sess.fatal("cannot continue compilation due to previous error");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -441,6 +441,10 @@ fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
|
|||||||
tcx.at(it.span).super_predicates_of(def_id);
|
tcx.at(it.span).super_predicates_of(def_id);
|
||||||
tcx.predicates_of(def_id);
|
tcx.predicates_of(def_id);
|
||||||
},
|
},
|
||||||
|
hir::ItemTraitAlias(..) => {
|
||||||
|
span_err!(tcx.sess, it.span, E0645,
|
||||||
|
"trait aliases are not yet implemented (see issue #41517)");
|
||||||
|
},
|
||||||
hir::ItemStruct(ref struct_def, _) |
|
hir::ItemStruct(ref struct_def, _) |
|
||||||
hir::ItemUnion(ref struct_def, _) => {
|
hir::ItemUnion(ref struct_def, _) => {
|
||||||
tcx.generics_of(def_id);
|
tcx.generics_of(def_id);
|
||||||
@@ -672,6 +676,7 @@ fn super_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
|
|
||||||
let (generics, bounds) = match item.node {
|
let (generics, bounds) = match item.node {
|
||||||
hir::ItemTrait(.., ref generics, ref supertraits, _) => (generics, supertraits),
|
hir::ItemTrait(.., ref generics, ref supertraits, _) => (generics, supertraits),
|
||||||
|
hir::ItemTraitAlias(ref generics, ref supertraits) => (generics, supertraits),
|
||||||
_ => span_bug!(item.span,
|
_ => span_bug!(item.span,
|
||||||
"super_predicates invoked on non-trait"),
|
"super_predicates invoked on non-trait"),
|
||||||
};
|
};
|
||||||
@@ -715,6 +720,7 @@ fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
|
|
||||||
let unsafety = match item.node {
|
let unsafety = match item.node {
|
||||||
hir::ItemTrait(_, unsafety, ..) => unsafety,
|
hir::ItemTrait(_, unsafety, ..) => unsafety,
|
||||||
|
hir::ItemTraitAlias(..) => hir::Unsafety::Normal,
|
||||||
_ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
|
_ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -902,7 +908,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
(generics, None)
|
(generics, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemTrait(_, _, ref generics, ..) => {
|
ItemTrait(_, _, ref generics, ..) | ItemTraitAlias(ref generics, ..) => {
|
||||||
// Add in the self type parameter.
|
// Add in the self type parameter.
|
||||||
//
|
//
|
||||||
// Something of a hack: use the node id for the trait, also as
|
// Something of a hack: use the node id for the trait, also as
|
||||||
@@ -1132,7 +1138,7 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
tcx.mk_adt(def, substs)
|
tcx.mk_adt(def, substs)
|
||||||
}
|
}
|
||||||
ItemAutoImpl(..) |
|
ItemAutoImpl(..) |
|
||||||
ItemTrait(..) |
|
ItemTrait(..) | ItemTraitAlias(..) |
|
||||||
ItemMod(..) |
|
ItemMod(..) |
|
||||||
ItemForeignMod(..) |
|
ItemForeignMod(..) |
|
||||||
ItemGlobalAsm(..) |
|
ItemGlobalAsm(..) |
|
||||||
|
|||||||
@@ -4721,4 +4721,5 @@ register_diagnostics! {
|
|||||||
E0632, // cannot provide explicit type parameters when `impl Trait` is used in
|
E0632, // cannot provide explicit type parameters when `impl Trait` is used in
|
||||||
// argument position.
|
// argument position.
|
||||||
E0641, // cannot cast to/from a pointer with an unknown kind
|
E0641, // cannot cast to/from a pointer with an unknown kind
|
||||||
|
E0645, // trait aliases not finished
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -512,6 +512,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||||||
};
|
};
|
||||||
om.traits.push(t);
|
om.traits.push(t);
|
||||||
},
|
},
|
||||||
|
hir::ItemTraitAlias(..) => {
|
||||||
|
unimplemented!("trait objects are not yet implemented")
|
||||||
|
},
|
||||||
|
|
||||||
hir::ItemImpl(unsafety,
|
hir::ItemImpl(unsafety,
|
||||||
polarity,
|
polarity,
|
||||||
|
|||||||
@@ -1929,6 +1929,10 @@ pub enum ItemKind {
|
|||||||
///
|
///
|
||||||
/// E.g. `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`
|
/// E.g. `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`
|
||||||
Trait(IsAuto, Unsafety, Generics, TyParamBounds, Vec<TraitItem>),
|
Trait(IsAuto, Unsafety, Generics, TyParamBounds, Vec<TraitItem>),
|
||||||
|
/// Trait alias
|
||||||
|
///
|
||||||
|
/// E.g. `trait Foo = Bar + Quux;`
|
||||||
|
TraitAlias(Generics, TyParamBounds),
|
||||||
/// Auto trait implementation.
|
/// Auto trait implementation.
|
||||||
///
|
///
|
||||||
/// E.g. `impl Trait for .. {}` or `impl<T> Trait<T> for .. {}`
|
/// E.g. `impl Trait for .. {}` or `impl<T> Trait<T> for .. {}`
|
||||||
@@ -1968,6 +1972,7 @@ impl ItemKind {
|
|||||||
ItemKind::Struct(..) => "struct",
|
ItemKind::Struct(..) => "struct",
|
||||||
ItemKind::Union(..) => "union",
|
ItemKind::Union(..) => "union",
|
||||||
ItemKind::Trait(..) => "trait",
|
ItemKind::Trait(..) => "trait",
|
||||||
|
ItemKind::TraitAlias(..) => "trait alias",
|
||||||
ItemKind::Mac(..) |
|
ItemKind::Mac(..) |
|
||||||
ItemKind::MacroDef(..) |
|
ItemKind::MacroDef(..) |
|
||||||
ItemKind::Impl(..) |
|
ItemKind::Impl(..) |
|
||||||
|
|||||||
@@ -368,6 +368,8 @@ declare_features! (
|
|||||||
// Generators
|
// Generators
|
||||||
(active, generators, "1.21.0", None),
|
(active, generators, "1.21.0", None),
|
||||||
|
|
||||||
|
// Trait aliases
|
||||||
|
(active, trait_alias, "1.24.0", Some(41517)),
|
||||||
|
|
||||||
// global allocators and their internals
|
// global allocators and their internals
|
||||||
(active, global_allocator, "1.20.0", None),
|
(active, global_allocator, "1.20.0", None),
|
||||||
@@ -1406,6 +1408,12 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ast::ItemKind::TraitAlias(..) => {
|
||||||
|
gate_feature_post!(&self, trait_alias,
|
||||||
|
i.span,
|
||||||
|
"trait aliases are not yet fully implemented");
|
||||||
|
}
|
||||||
|
|
||||||
ast::ItemKind::AutoImpl(..) => {
|
ast::ItemKind::AutoImpl(..) => {
|
||||||
gate_feature_post!(&self, optin_builtin_traits,
|
gate_feature_post!(&self, optin_builtin_traits,
|
||||||
i.span,
|
i.span,
|
||||||
|
|||||||
@@ -921,6 +921,9 @@ pub fn noop_fold_item_kind<T: Folder>(i: ItemKind, folder: &mut T) -> ItemKind {
|
|||||||
folder.fold_bounds(bounds),
|
folder.fold_bounds(bounds),
|
||||||
items.move_flat_map(|item| folder.fold_trait_item(item)),
|
items.move_flat_map(|item| folder.fold_trait_item(item)),
|
||||||
),
|
),
|
||||||
|
ItemKind::TraitAlias(generics, bounds) => ItemKind::TraitAlias(
|
||||||
|
folder.fold_generics(generics),
|
||||||
|
folder.fold_bounds(bounds)),
|
||||||
ItemKind::Mac(m) => ItemKind::Mac(folder.fold_mac(m)),
|
ItemKind::Mac(m) => ItemKind::Mac(folder.fold_mac(m)),
|
||||||
ItemKind::MacroDef(def) => ItemKind::MacroDef(folder.fold_macro_def(def)),
|
ItemKind::MacroDef(def) => ItemKind::MacroDef(folder.fold_macro_def(def)),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5182,7 +5182,7 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse trait Foo { ... }
|
/// Parse `trait Foo { ... }` or `trait Foo = Bar;`
|
||||||
fn parse_item_trait(&mut self, is_auto: IsAuto, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
|
fn parse_item_trait(&mut self, is_auto: IsAuto, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
|
||||||
let ident = self.parse_ident()?;
|
let ident = self.parse_ident()?;
|
||||||
let mut tps = self.parse_generics()?;
|
let mut tps = self.parse_generics()?;
|
||||||
@@ -5194,23 +5194,34 @@ impl<'a> Parser<'a> {
|
|||||||
Vec::new()
|
Vec::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
tps.where_clause = self.parse_where_clause()?;
|
if self.eat(&token::Eq) {
|
||||||
|
// it's a trait alias
|
||||||
self.expect(&token::OpenDelim(token::Brace))?;
|
let bounds = self.parse_ty_param_bounds()?;
|
||||||
let mut trait_items = vec![];
|
tps.where_clause = self.parse_where_clause()?;
|
||||||
while !self.eat(&token::CloseDelim(token::Brace)) {
|
self.expect(&token::Semi)?;
|
||||||
let mut at_end = false;
|
if unsafety != Unsafety::Normal {
|
||||||
match self.parse_trait_item(&mut at_end) {
|
self.span_err(self.prev_span, "trait aliases cannot be unsafe");
|
||||||
Ok(item) => trait_items.push(item),
|
}
|
||||||
Err(mut e) => {
|
Ok((ident, ItemKind::TraitAlias(tps, bounds), None))
|
||||||
e.emit();
|
} else {
|
||||||
if !at_end {
|
// it's a normal trait
|
||||||
self.recover_stmt_(SemiColonMode::Break, BlockMode::Break);
|
tps.where_clause = self.parse_where_clause()?;
|
||||||
|
self.expect(&token::OpenDelim(token::Brace))?;
|
||||||
|
let mut trait_items = vec![];
|
||||||
|
while !self.eat(&token::CloseDelim(token::Brace)) {
|
||||||
|
let mut at_end = false;
|
||||||
|
match self.parse_trait_item(&mut at_end) {
|
||||||
|
Ok(item) => trait_items.push(item),
|
||||||
|
Err(mut e) => {
|
||||||
|
e.emit();
|
||||||
|
if !at_end {
|
||||||
|
self.recover_stmt_(SemiColonMode::Break, BlockMode::Break);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok((ident, ItemKind::Trait(is_auto, unsafety, tps, bounds, trait_items), None))
|
||||||
}
|
}
|
||||||
Ok((ident, ItemKind::Trait(is_auto, unsafety, tps, bounds, trait_items), None))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses items implementations variants
|
/// Parses items implementations variants
|
||||||
|
|||||||
@@ -1381,6 +1381,27 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
self.bclose(item.span)?;
|
self.bclose(item.span)?;
|
||||||
}
|
}
|
||||||
|
ast::ItemKind::TraitAlias(ref generics, ref bounds) => {
|
||||||
|
self.head("")?;
|
||||||
|
self.print_visibility(&item.vis)?;
|
||||||
|
self.word_nbsp("trait")?;
|
||||||
|
self.print_ident(item.ident)?;
|
||||||
|
self.print_generics(generics)?;
|
||||||
|
let mut real_bounds = Vec::with_capacity(bounds.len());
|
||||||
|
// FIXME(durka) this seems to be some quite outdated syntax
|
||||||
|
for b in bounds.iter() {
|
||||||
|
if let TraitTyParamBound(ref ptr, ast::TraitBoundModifier::Maybe) = *b {
|
||||||
|
self.s.space()?;
|
||||||
|
self.word_space("for ?")?;
|
||||||
|
self.print_trait_ref(&ptr.trait_ref)?;
|
||||||
|
} else {
|
||||||
|
real_bounds.push(b.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.print_bounds(" = ", &real_bounds[..])?;
|
||||||
|
self.print_where_clause(&generics.where_clause)?;
|
||||||
|
self.s.word(";")?;
|
||||||
|
}
|
||||||
ast::ItemKind::Mac(codemap::Spanned { ref node, .. }) => {
|
ast::ItemKind::Mac(codemap::Spanned { ref node, .. }) => {
|
||||||
self.print_path(&node.path, false, 0, false)?;
|
self.print_path(&node.path, false, 0, false)?;
|
||||||
self.s.word("! ")?;
|
self.s.word("! ")?;
|
||||||
|
|||||||
@@ -291,6 +291,10 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
|
|||||||
walk_list!(visitor, visit_ty_param_bound, bounds);
|
walk_list!(visitor, visit_ty_param_bound, bounds);
|
||||||
walk_list!(visitor, visit_trait_item, methods);
|
walk_list!(visitor, visit_trait_item, methods);
|
||||||
}
|
}
|
||||||
|
ItemKind::TraitAlias(ref generics, ref bounds) => {
|
||||||
|
visitor.visit_generics(generics);
|
||||||
|
walk_list!(visitor, visit_ty_param_bound, bounds);
|
||||||
|
}
|
||||||
ItemKind::Mac(ref mac) => visitor.visit_mac(mac),
|
ItemKind::Mac(ref mac) => visitor.visit_mac(mac),
|
||||||
ItemKind::MacroDef(ref ts) => visitor.visit_mac_def(ts, item.id),
|
ItemKind::MacroDef(ref ts) => visitor.visit_mac_def(ts, item.id),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// gate-test-trait_alias
|
||||||
|
|
||||||
|
trait Alias1<T> = Default where T: Clone; // ok
|
||||||
|
//~^ERROR trait aliases are not yet fully implemented
|
||||||
|
trait Alias2<T: Clone = ()> = Default;
|
||||||
|
//~^ERROR type parameters on the left side of a trait alias cannot be bounded
|
||||||
|
//~^^ERROR type parameters on the left side of a trait alias cannot have defaults
|
||||||
|
//~^^^ERROR trait aliases are not yet fully implemented
|
||||||
|
|
||||||
|
impl Alias1 { //~ERROR expected type, found trait alias
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Alias1 for () { //~ERROR expected trait, found trait alias
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![feature(trait_alias)]
|
||||||
|
|
||||||
|
trait SimpleAlias = Default; //~ERROR E0645
|
||||||
|
trait GenericAlias<T> = Iterator<Item=T>; //~ERROR E0645
|
||||||
|
trait Partial<T> = IntoIterator<Item=T>; //~ERROR E0645
|
||||||
|
|
||||||
|
trait Things<T> {}
|
||||||
|
trait Romeo {}
|
||||||
|
struct The<T>(T);
|
||||||
|
struct Fore<T>(T);
|
||||||
|
impl<T, U> Things<T> for The<U> {}
|
||||||
|
impl<T> Romeo for Fore<T> {}
|
||||||
|
|
||||||
|
trait WithWhere<Art, Thou> = Romeo + Romeo where Fore<(Art, Thou)>: Romeo; //~ERROR E0645
|
||||||
|
trait BareWhere<Wild, Are> = where The<Wild>: Things<Are>; //~ERROR E0645
|
||||||
|
|
||||||
|
trait CD = Clone + Default; //~ERROR E0645
|
||||||
|
|
||||||
|
fn foo<T: CD>() -> (T, T) {
|
||||||
|
let one = T::default();
|
||||||
|
let two = one.clone();
|
||||||
|
(one, two)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let both = foo();
|
||||||
|
assert_eq!(both.0, 0);
|
||||||
|
assert_eq!(both.1, 0);
|
||||||
|
let both: (i32, i32) = foo();
|
||||||
|
assert_eq!(both.0, 0);
|
||||||
|
assert_eq!(both.1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
error[E0645]: trait aliases are not yet implemented (see issue #41517)
|
||||||
|
--> $DIR/trait-alias.rs:13:1
|
||||||
|
|
|
||||||
|
13 | trait SimpleAlias = Default; //~ERROR E0645
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0645]: trait aliases are not yet implemented (see issue #41517)
|
||||||
|
--> $DIR/trait-alias.rs:14:1
|
||||||
|
|
|
||||||
|
14 | trait GenericAlias<T> = Iterator<Item=T>; //~ERROR E0645
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0645]: trait aliases are not yet implemented (see issue #41517)
|
||||||
|
--> $DIR/trait-alias.rs:15:1
|
||||||
|
|
|
||||||
|
15 | trait Partial<T> = IntoIterator<Item=T>; //~ERROR E0645
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0645]: trait aliases are not yet implemented (see issue #41517)
|
||||||
|
--> $DIR/trait-alias.rs:24:1
|
||||||
|
|
|
||||||
|
24 | trait WithWhere<Art, Thou> = Romeo + Romeo where Fore<(Art, Thou)>: Romeo; //~ERROR E0645
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0645]: trait aliases are not yet implemented (see issue #41517)
|
||||||
|
--> $DIR/trait-alias.rs:25:1
|
||||||
|
|
|
||||||
|
25 | trait BareWhere<Wild, Are> = where The<Wild>: Things<Are>; //~ERROR E0645
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0645]: trait aliases are not yet implemented (see issue #41517)
|
||||||
|
--> $DIR/trait-alias.rs:27:1
|
||||||
|
|
|
||||||
|
27 | trait CD = Clone + Default; //~ERROR E0645
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
@@ -32,4 +32,5 @@ clippy = "Testing"
|
|||||||
rls = "Broken"
|
rls = "Broken"
|
||||||
|
|
||||||
# ping @nrc
|
# ping @nrc
|
||||||
|
# when breaking rustfmt, always break rls as well
|
||||||
rustfmt = "Broken"
|
rustfmt = "Broken"
|
||||||
|
|||||||
Reference in New Issue
Block a user