Skip to content

Commit 9508faa

Browse files
committed
auto merge of #16377 : pcwalton/rust/associated-items, r=nikomatsakis
This is waiting on an RFC, but this basic functionality should be straightforward. The implementation essentially desugars during type collection and AST type conversion time into the parameter scheme we have now. r? @nikomatsakis
2 parents 8067f44 + 78a8418 commit 9508faa

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

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

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
}

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> {

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+

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)