Skip to content

Commit 8fa33fe

Browse files
author
Alexander Regueiro
committed
Implemented cross-crate usage of trait aliases.
1 parent e7c17a8 commit 8fa33fe

File tree

18 files changed

+140
-48
lines changed

18 files changed

+140
-48
lines changed

src/librustc/hir/def.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ pub enum Def {
4141
Enum(DefId),
4242
Variant(DefId),
4343
Trait(DefId),
44+
TraitAlias(DefId),
4445
/// `existential type Foo: Bar;`
4546
Existential(DefId),
4647
/// `type Foo = Bar;`
4748
TyAlias(DefId),
4849
ForeignTy(DefId),
49-
TraitAlias(DefId),
5050
AssociatedTy(DefId),
5151
/// `existential type Foo: Bar;`
5252
AssociatedExistential(DefId),

src/librustc/hir/map/def_collector.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,10 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
120120
let def_data = match i.node {
121121
ItemKind::Impl(..) => DefPathData::Impl,
122122
ItemKind::Trait(..) => DefPathData::Trait(i.ident.as_interned_str()),
123+
ItemKind::TraitAlias(..) => DefPathData::TraitAlias(i.ident.as_interned_str()),
123124
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) |
124-
ItemKind::TraitAlias(..) | ItemKind::Existential(..) |
125-
ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::Ty(..) =>
126-
DefPathData::TypeNs(i.ident.as_interned_str()),
125+
ItemKind::Existential(..) | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) |
126+
ItemKind::Ty(..) => DefPathData::TypeNs(i.ident.as_interned_str()),
127127
ItemKind::Mod(..) if i.ident == keywords::Invalid.ident() => {
128128
return visit::walk_item(self, i);
129129
}

src/librustc/hir/map/definitions.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,9 @@ pub enum DefPathData {
373373
/// GlobalMetaData identifies a piece of crate metadata that is global to
374374
/// a whole crate (as opposed to just one item). GlobalMetaData components
375375
/// are only supposed to show up right below the crate root.
376-
GlobalMetaData(InternedString)
376+
GlobalMetaData(InternedString),
377+
/// A trait alias.
378+
TraitAlias(InternedString),
377379
}
378380

379381
#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug,
@@ -615,6 +617,7 @@ impl DefPathData {
615617
match *self {
616618
TypeNs(name) |
617619
Trait(name) |
620+
TraitAlias(name) |
618621
AssocTypeInTrait(name) |
619622
AssocTypeInImpl(name) |
620623
AssocExistentialInImpl(name) |
@@ -642,6 +645,7 @@ impl DefPathData {
642645
let s = match *self {
643646
TypeNs(name) |
644647
Trait(name) |
648+
TraitAlias(name) |
645649
AssocTypeInTrait(name) |
646650
AssocTypeInImpl(name) |
647651
AssocExistentialInImpl(name) |

src/librustc/traits/select.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2251,7 +2251,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
22512251

22522252
let def_id = obligation.predicate.def_id();
22532253

2254-
if ty::is_trait_alias(self.tcx(), def_id) {
2254+
if self.tcx().is_trait_alias(def_id) {
22552255
candidates.vec.push(TraitAliasCandidate(def_id.clone()));
22562256
}
22572257

src/librustc/traits/util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ impl<'cx, 'gcx, 'tcx> TraitRefExpander<'cx, 'gcx, 'tcx> {
352352

353353
debug!("expand_trait_refs: trait_ref={:?}", trait_ref);
354354

355-
if !ty::is_trait_alias(tcx, trait_ref.def_id()) {
355+
if !tcx.is_trait_alias(trait_ref.def_id()) {
356356
return true;
357357
}
358358

src/librustc/ty/item_path.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
311311
data @ DefPathData::Misc |
312312
data @ DefPathData::TypeNs(..) |
313313
data @ DefPathData::Trait(..) |
314+
data @ DefPathData::TraitAlias(..) |
314315
data @ DefPathData::AssocTypeInTrait(..) |
315316
data @ DefPathData::AssocTypeInImpl(..) |
316317
data @ DefPathData::AssocExistentialInImpl(..) |

src/librustc/ty/mod.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3119,18 +3119,6 @@ pub fn is_impl_trait_defn(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Option<DefI
31193119
None
31203120
}
31213121

3122-
/// Returns `true` if `def_id` is a trait alias.
3123-
pub fn is_trait_alias(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> bool {
3124-
if let Some(node_id) = tcx.hir().as_local_node_id(def_id) {
3125-
if let Node::Item(item) = tcx.hir().get(node_id) {
3126-
if let hir::ItemKind::TraitAlias(..) = item.node {
3127-
return true;
3128-
}
3129-
}
3130-
}
3131-
false
3132-
}
3133-
31343122
/// See `ParamEnv` struct definition for details.
31353123
fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
31363124
def_id: DefId)

src/librustc/ty/util.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
526526
}
527527
}
528528

529+
/// True if `def_id` refers to a trait alias (i.e., `trait Foo = ...;`).
530+
pub fn is_trait_alias(self, def_id: DefId) -> bool {
531+
if let DefPathData::TraitAlias(_) = self.def_key(def_id).disambiguated_data.data {
532+
true
533+
} else {
534+
false
535+
}
536+
}
537+
529538
/// True if this def-id refers to the implicit constructor for
530539
/// a tuple struct like `struct Foo(u32)`.
531540
pub fn is_struct_constructor(self, def_id: DefId) -> bool {

src/librustc/util/ppaux.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ impl PrintContext {
264264
DefPathData::AssocTypeInImpl(_) |
265265
DefPathData::AssocExistentialInImpl(_) |
266266
DefPathData::Trait(_) |
267+
DefPathData::TraitAlias(_) |
267268
DefPathData::Impl |
268269
DefPathData::TypeNs(_) => {
269270
break;

src/librustc_metadata/decoder.rs

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@ impl<'tcx> EntryKind<'tcx> {
418418
EntryKind::Mod(_) => Def::Mod(did),
419419
EntryKind::Variant(_) => Def::Variant(did),
420420
EntryKind::Trait(_) => Def::Trait(did),
421+
EntryKind::TraitAlias(_) => Def::TraitAlias(did),
421422
EntryKind::Enum(..) => Def::Enum(did),
422423
EntryKind::MacroDef(_) => Def::Macro(did, MacroKind::Bang),
423424
EntryKind::ForeignType => Def::ForeignTy(did),
@@ -520,17 +521,26 @@ impl<'a, 'tcx> CrateMetadata {
520521
}
521522

522523
pub fn get_trait_def(&self, item_id: DefIndex, sess: &Session) -> ty::TraitDef {
523-
let data = match self.entry(item_id).kind {
524-
EntryKind::Trait(data) => data.decode((self, sess)),
525-
_ => bug!(),
526-
};
527-
528-
ty::TraitDef::new(self.local_def_id(item_id),
529-
data.unsafety,
530-
data.paren_sugar,
531-
data.has_auto_impl,
532-
data.is_marker,
533-
self.def_path_table.def_path_hash(item_id))
524+
match self.entry(item_id).kind {
525+
EntryKind::Trait(data) => {
526+
let data = data.decode((self, sess));
527+
ty::TraitDef::new(self.local_def_id(item_id),
528+
data.unsafety,
529+
data.paren_sugar,
530+
data.has_auto_impl,
531+
data.is_marker,
532+
self.def_path_table.def_path_hash(item_id))
533+
},
534+
EntryKind::TraitAlias(_) => {
535+
ty::TraitDef::new(self.local_def_id(item_id),
536+
hir::Unsafety::Normal,
537+
false,
538+
false,
539+
false,
540+
self.def_path_table.def_path_hash(item_id))
541+
},
542+
_ => bug!("def-index does not refer to trait or trait alias"),
543+
}
534544
}
535545

536546
fn get_variant(&self,
@@ -544,7 +554,7 @@ impl<'a, 'tcx> CrateMetadata {
544554
EntryKind::Variant(data) |
545555
EntryKind::Struct(data, _) |
546556
EntryKind::Union(data, _) => data.decode(self),
547-
_ => bug!(),
557+
_ => bug!("def-index does not refer to ADT"),
548558
};
549559

550560
let def_id = self.local_def_id(data.struct_ctor.unwrap_or(index));
@@ -615,10 +625,13 @@ impl<'a, 'tcx> CrateMetadata {
615625
item_id: DefIndex,
616626
tcx: TyCtxt<'a, 'tcx, 'tcx>)
617627
-> ty::GenericPredicates<'tcx> {
618-
match self.entry(item_id).kind {
619-
EntryKind::Trait(data) => data.decode(self).super_predicates.decode((self, tcx)),
620-
_ => bug!(),
621-
}
628+
let super_predicates = match self.entry(item_id).kind {
629+
EntryKind::Trait(data) => data.decode(self).super_predicates,
630+
EntryKind::TraitAlias(data) => data.decode(self).super_predicates,
631+
_ => bug!("def-index does not refer to trait or trait alias"),
632+
};
633+
634+
super_predicates.decode((self, tcx))
622635
}
623636

624637
pub fn get_generics(&self,
@@ -656,7 +669,7 @@ impl<'a, 'tcx> CrateMetadata {
656669
fn get_impl_data(&self, id: DefIndex) -> ImplData<'tcx> {
657670
match self.entry(id).kind {
658671
EntryKind::Impl(data) => data.decode(self),
659-
_ => bug!(),
672+
_ => bug!("def-index does not refer to impl"),
660673
}
661674
}
662675

@@ -833,7 +846,7 @@ impl<'a, 'tcx> CrateMetadata {
833846
match self.entry(id).kind {
834847
EntryKind::AssociatedConst(_, data, _) |
835848
EntryKind::Const(data, _) => data.ast_promotable,
836-
_ => bug!(),
849+
_ => bug!("def-index does not refer to const"),
837850
}
838851
}
839852

@@ -859,7 +872,7 @@ impl<'a, 'tcx> CrateMetadata {
859872
EntryKind::AssociatedConst(AssociatedContainer::ImplFinal, qualif, _) => {
860873
qualif.mir
861874
}
862-
_ => bug!(),
875+
_ => bug!("def-index does not refer to const"),
863876
}
864877
}
865878

@@ -1014,7 +1027,8 @@ impl<'a, 'tcx> CrateMetadata {
10141027
}
10151028
def_key.parent.and_then(|parent_index| {
10161029
match self.entry(parent_index).kind {
1017-
EntryKind::Trait(_) => Some(self.local_def_id(parent_index)),
1030+
EntryKind::Trait(_) |
1031+
EntryKind::TraitAlias(_) => Some(self.local_def_id(parent_index)),
10181032
_ => None,
10191033
}
10201034
})
@@ -1092,15 +1106,15 @@ impl<'a, 'tcx> CrateMetadata {
10921106
match self.entry(id).kind {
10931107
EntryKind::Const(_, data) |
10941108
EntryKind::AssociatedConst(_, _, data) => data.decode(self).0,
1095-
_ => bug!(),
1109+
_ => bug!("def-index does not refer to const"),
10961110
}
10971111
}
10981112

10991113
pub fn get_macro(&self, id: DefIndex) -> MacroDef {
11001114
let entry = self.entry(id);
11011115
match entry.kind {
11021116
EntryKind::MacroDef(macro_def) => macro_def.decode(self),
1103-
_ => bug!(),
1117+
_ => bug!("def-index does not refer to macro def"),
11041118
}
11051119
}
11061120

@@ -1133,7 +1147,7 @@ impl<'a, 'tcx> CrateMetadata {
11331147
EntryKind::Variant(data) |
11341148
EntryKind::Struct(data, _) => data.decode(self).ctor_sig.unwrap(),
11351149
EntryKind::Closure(data) => data.decode(self).sig,
1136-
_ => bug!(),
1150+
_ => bug!("def-index does not refer to function"),
11371151
};
11381152
sig.decode((self, tcx))
11391153
}

src/librustc_metadata/encoder.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,8 +1132,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
11321132

11331133
EntryKind::Impl(self.lazy(&data))
11341134
}
1135-
hir::ItemKind::Trait(..) |
1136-
hir::ItemKind::TraitAlias(..) => {
1135+
hir::ItemKind::Trait(..) => {
11371136
let trait_def = tcx.trait_def(def_id);
11381137
let data = TraitData {
11391138
unsafety: trait_def.unsafety,
@@ -1145,6 +1144,13 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
11451144

11461145
EntryKind::Trait(self.lazy(&data))
11471146
}
1147+
hir::ItemKind::TraitAlias(..) => {
1148+
let data = TraitAliasData {
1149+
super_predicates: self.lazy(&tcx.super_predicates_of(def_id)),
1150+
};
1151+
1152+
EntryKind::TraitAlias(self.lazy(&data))
1153+
}
11481154
hir::ItemKind::ExternCrate(_) |
11491155
hir::ItemKind::Use(..) => bug!("cannot encode info for item {:?}", item),
11501156
};
@@ -1218,6 +1224,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
12181224
hir::ItemKind::Impl(..) |
12191225
hir::ItemKind::Existential(..) |
12201226
hir::ItemKind::Trait(..) => Some(self.encode_generics(def_id)),
1227+
hir::ItemKind::TraitAlias(..) => Some(self.encode_generics(def_id)),
12211228
_ => None,
12221229
},
12231230
predicates: match item.node {
@@ -1230,7 +1237,8 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
12301237
hir::ItemKind::Union(..) |
12311238
hir::ItemKind::Impl(..) |
12321239
hir::ItemKind::Existential(..) |
1233-
hir::ItemKind::Trait(..) => Some(self.encode_predicates(def_id)),
1240+
hir::ItemKind::Trait(..) |
1241+
hir::ItemKind::TraitAlias(..) => Some(self.encode_predicates(def_id)),
12341242
_ => None,
12351243
},
12361244

@@ -1240,7 +1248,8 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
12401248
// hack. (No reason not to expand it in the future if
12411249
// necessary.)
12421250
predicates_defined_on: match item.node {
1243-
hir::ItemKind::Trait(..) => Some(self.encode_predicates_defined_on(def_id)),
1251+
hir::ItemKind::Trait(..) |
1252+
hir::ItemKind::TraitAlias(..) => Some(self.encode_predicates_defined_on(def_id)),
12441253
_ => None, // not *wrong* for other kinds of items, but not needed
12451254
},
12461255

src/librustc_metadata/schema.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ pub enum EntryKind<'tcx> {
316316
AssociatedType(AssociatedContainer),
317317
AssociatedExistential(AssociatedContainer),
318318
AssociatedConst(AssociatedContainer, ConstQualif, Lazy<RenderedConst>),
319+
TraitAlias(Lazy<TraitAliasData<'tcx>>),
319320
}
320321

321322
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for EntryKind<'gcx> {
@@ -370,6 +371,9 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for EntryKind<'gcx> {
370371
EntryKind::Trait(ref trait_data) => {
371372
trait_data.hash_stable(hcx, hasher);
372373
}
374+
EntryKind::TraitAlias(ref trait_alias_data) => {
375+
trait_alias_data.hash_stable(hcx, hasher);
376+
}
373377
EntryKind::Impl(ref impl_data) => {
374378
impl_data.hash_stable(hcx, hasher);
375379
}
@@ -474,6 +478,15 @@ impl_stable_hash_for!(struct TraitData<'tcx> {
474478
super_predicates
475479
});
476480

481+
#[derive(RustcEncodable, RustcDecodable)]
482+
pub struct TraitAliasData<'tcx> {
483+
pub super_predicates: Lazy<ty::GenericPredicates<'tcx>>,
484+
}
485+
486+
impl_stable_hash_for!(struct TraitAliasData<'tcx> {
487+
super_predicates
488+
});
489+
477490
#[derive(RustcEncodable, RustcDecodable)]
478491
pub struct ImplData<'tcx> {
479492
pub polarity: hir::ImplPolarity,

src/librustc_resolve/build_reduced_graph.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,9 @@ impl<'a> Resolver<'a> {
674674
}
675675
module.populated.set(true);
676676
}
677+
Def::TraitAlias(..) => {
678+
self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion));
679+
}
677680
Def::Struct(..) | Def::Union(..) => {
678681
self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion));
679682

src/librustc_traits/lowering/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ crate fn program_clauses_for<'a, 'tcx>(
158158
def_id: DefId,
159159
) -> Clauses<'tcx> {
160160
match tcx.def_key(def_id).disambiguated_data.data {
161-
DefPathData::Trait(_) => program_clauses_for_trait(tcx, def_id),
161+
DefPathData::Trait(_) |
162+
DefPathData::TraitAlias(_) => program_clauses_for_trait(tcx, def_id),
162163
DefPathData::Impl => program_clauses_for_impl(tcx, def_id),
163164
DefPathData::AssocTypeInImpl(..) => program_clauses_for_associated_type_value(tcx, def_id),
164165
DefPathData::AssocTypeInTrait(..) => program_clauses_for_associated_type_def(tcx, def_id),

src/librustc_typeck/collect.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,7 @@ fn super_predicates_of<'a, 'tcx>(
706706
// In the case of trait aliases, however, we include all bounds in the where clause,
707707
// so e.g., `trait Foo = where u32: PartialEq<Self>` would include `u32: PartialEq<Self>`
708708
// as one of its "superpredicates".
709-
let is_trait_alias = ty::is_trait_alias(tcx, trait_def_id);
709+
let is_trait_alias = tcx.is_trait_alias(trait_def_id);
710710
let superbounds2 = icx.type_parameter_bounds_in_generics(
711711
generics, item.id, self_param_ty, OnlySelfBounds(!is_trait_alias));
712712

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#![feature(trait_alias)]
2+
3+
pub trait SendSync = Send + Sync;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// aux-build:trait_alias.rs
2+
3+
#![feature(trait_alias)]
4+
5+
extern crate trait_alias;
6+
7+
use std::rc::Rc;
8+
use trait_alias::SendSync;
9+
10+
fn use_alias<T: SendSync>() {}
11+
12+
fn main() {
13+
use_alias::<u32>();
14+
use_alias::<Rc<u32>>();
15+
//~^ ERROR `std::rc::Rc<u32>` cannot be sent between threads safely [E0277]
16+
//~^^ ERROR `std::rc::Rc<u32>` cannot be shared between threads safely [E0277]
17+
}

0 commit comments

Comments
 (0)