Skip to content

Commit 78a8418

Browse files
committed
librustc: Implement associated types behind a feature gate.
The implementation essentially desugars during type collection and AST type conversion time into the parameter scheme we have now. Only fully qualified names--e.g. `<T as Foo>::Bar`--are supported.
1 parent 8067f44 commit 78a8418

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+3032
-551
lines changed

Diff for: src/doc/rust.md

+2
Original file line numberDiff line numberDiff line change
@@ -2557,6 +2557,8 @@ The currently implemented features of the reference compiler are:
25572557

25582558
* `tuple_indexing` - Allows use of tuple indexing (expressions like `expr.0`)
25592559

2560+
* `associated_types` - Allows type aliases in traits. Experimental.
2561+
25602562
If a feature is promoted to a language feature, then all existing programs will
25612563
start to receive compilation warnings about #[feature] directives which enabled
25622564
the new feature (because the directive is no longer necessary). However, if

Diff for: src/librustc/lint/builtin.rs

+14-7
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,17 @@ fn method_context(cx: &Context, m: &ast::Method) -> MethodContext {
844844
}
845845
}
846846
}
847+
ty::TypeTraitItem(typedef) => {
848+
match typedef.container {
849+
ty::TraitContainer(..) => TraitDefaultImpl,
850+
ty::ImplContainer(cid) => {
851+
match ty::impl_trait_ref(cx.tcx, cid) {
852+
Some(..) => TraitImpl,
853+
None => PlainImpl
854+
}
855+
}
856+
}
857+
}
847858
}
848859
}
849860
}
@@ -1511,13 +1522,9 @@ impl LintPass for Stability {
15111522
method_num: index,
15121523
..
15131524
}) => {
1514-
match ty::trait_item(cx.tcx,
1515-
trait_ref.def_id,
1516-
index) {
1517-
ty::MethodTraitItem(method) => {
1518-
method.def_id
1519-
}
1520-
}
1525+
ty::trait_item(cx.tcx,
1526+
trait_ref.def_id,
1527+
index).def_id()
15211528
}
15221529
}
15231530
}

Diff for: src/librustc/lint/context.rs

+21
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
//! for all lint attributes.
2626
2727
use middle::privacy::ExportedItems;
28+
use middle::subst;
2829
use middle::ty;
2930
use middle::typeck::astconv::AstConv;
3031
use middle::typeck::infer;
@@ -491,6 +492,26 @@ impl<'a, 'tcx> AstConv<'tcx> for Context<'a, 'tcx>{
491492
fn ty_infer(&self, _span: Span) -> ty::t {
492493
infer::new_infer_ctxt(self.tcx).next_ty_var()
493494
}
495+
496+
fn associated_types_of_trait_are_valid(&self, _: ty::t, _: ast::DefId)
497+
-> bool {
498+
// FIXME(pcwalton): This is wrong.
499+
true
500+
}
501+
502+
fn associated_type_binding(&self,
503+
_: Span,
504+
_: Option<ty::t>,
505+
trait_id: ast::DefId,
506+
associated_type_id: ast::DefId)
507+
-> ty::t {
508+
// FIXME(pcwalton): This is wrong.
509+
let trait_def = self.get_trait_def(trait_id);
510+
let index = ty::associated_type_parameter_index(self.tcx,
511+
&*trait_def,
512+
associated_type_id);
513+
ty::mk_param(self.tcx, subst::TypeSpace, index, associated_type_id)
514+
}
494515
}
495516

496517
impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {

Diff for: src/librustc/metadata/csearch.rs

+6
Original file line numberDiff line numberDiff line change
@@ -349,3 +349,9 @@ pub fn get_stability(cstore: &cstore::CStore,
349349
let cdata = cstore.get_crate_data(def.krate);
350350
decoder::get_stability(&*cdata, def.node)
351351
}
352+
353+
pub fn is_associated_type(cstore: &cstore::CStore, def: ast::DefId) -> bool {
354+
let cdata = cstore.get_crate_data(def.krate);
355+
decoder::is_associated_type(&*cdata, def.node)
356+
}
357+

Diff for: src/librustc/metadata/decoder.rs

+25-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use metadata::tydecode::{parse_ty_data, parse_region_data, parse_def_id,
2323
parse_bare_fn_ty_data, parse_trait_ref_data};
2424
use middle::def;
2525
use middle::lang_items;
26-
use middle::resolve::TraitItemKind;
26+
use middle::resolve::{TraitItemKind, TypeTraitItemKind};
2727
use middle::subst;
2828
use middle::ty::{ImplContainer, TraitContainer};
2929
use middle::ty;
@@ -167,6 +167,8 @@ fn item_visibility(item: rbml::Doc) -> ast::Visibility {
167167
}
168168

169169
fn item_sort(item: rbml::Doc) -> char {
170+
// NB(pcwalton): The default of 'r' here is relied upon in
171+
// `is_associated_type` below.
170172
let mut ret = 'r';
171173
reader::tagged_docs(item, tag_item_trait_item_sort, |doc| {
172174
ret = doc.as_str_slice().as_bytes()[0] as char;
@@ -714,6 +716,7 @@ pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId)
714716
let def_id = item_def_id(doc, cdata);
715717
match item_sort(doc) {
716718
'r' | 'p' => impl_items.push(ty::MethodTraitItemId(def_id)),
719+
't' => impl_items.push(ty::TypeTraitItemId(def_id)),
717720
_ => fail!("unknown impl item sort"),
718721
}
719722
true
@@ -733,6 +736,7 @@ pub fn get_trait_item_name_and_kind(intr: Rc<IdentInterner>,
733736
let explicit_self = get_explicit_self(doc);
734737
(name, TraitItemKind::from_explicit_self_category(explicit_self))
735738
}
739+
't' => (name, TypeTraitItemKind),
736740
c => {
737741
fail!("get_trait_item_name_and_kind(): unknown trait item kind \
738742
in metadata: `{}`", c)
@@ -758,13 +762,13 @@ pub fn get_impl_or_trait_item(intr: Rc<IdentInterner>,
758762
};
759763

760764
let name = item_name(&*intr, method_doc);
765+
let vis = item_visibility(method_doc);
761766

762767
match item_sort(method_doc) {
763768
'r' | 'p' => {
764769
let generics = doc_generics(method_doc, tcx, cdata,
765770
tag_method_ty_generics);
766771
let fty = doc_method_fty(method_doc, tcx, cdata);
767-
let vis = item_visibility(method_doc);
768772
let explicit_self = get_explicit_self(method_doc);
769773
let provided_source = get_provided_source(method_doc, cdata);
770774

@@ -777,6 +781,14 @@ pub fn get_impl_or_trait_item(intr: Rc<IdentInterner>,
777781
container,
778782
provided_source)))
779783
}
784+
't' => {
785+
ty::TypeTraitItem(Rc::new(ty::AssociatedType {
786+
ident: name,
787+
vis: vis,
788+
def_id: def_id,
789+
container: container,
790+
}))
791+
}
780792
_ => fail!("unknown impl/trait item sort"),
781793
}
782794
}
@@ -790,6 +802,7 @@ pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId)
790802
let def_id = item_def_id(mth, cdata);
791803
match item_sort(mth) {
792804
'r' | 'p' => result.push(ty::MethodTraitItemId(def_id)),
805+
't' => result.push(ty::TypeTraitItemId(def_id)),
793806
_ => fail!("unknown trait item sort"),
794807
}
795808
true
@@ -827,6 +840,7 @@ pub fn get_provided_trait_methods(intr: Rc<IdentInterner>,
827840
ty::MethodTraitItem(ref method) => {
828841
result.push((*method).clone())
829842
}
843+
ty::TypeTraitItem(_) => {}
830844
}
831845
}
832846
true
@@ -1394,3 +1408,12 @@ fn doc_generics(base_doc: rbml::Doc,
13941408

13951409
ty::Generics { types: types, regions: regions }
13961410
}
1411+
1412+
pub fn is_associated_type(cdata: Cmd, id: ast::NodeId) -> bool {
1413+
let items = reader::get_doc(rbml::Doc::new(cdata.data()), tag_items);
1414+
match maybe_find_item(id, items) {
1415+
None => false,
1416+
Some(item) => item_sort(item) == 't',
1417+
}
1418+
}
1419+

0 commit comments

Comments
 (0)