Skip to content

Commit

Permalink
auto merge of #16377 : pcwalton/rust/associated-items, r=nikomatsakis
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Sep 17, 2014
2 parents 8067f44 + 78a8418 commit 9508faa
Show file tree
Hide file tree
Showing 67 changed files with 3,032 additions and 551 deletions.
2 changes: 2 additions & 0 deletions src/doc/rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -2557,6 +2557,8 @@ The currently implemented features of the reference compiler are:

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

* `associated_types` - Allows type aliases in traits. Experimental.

If a feature is promoted to a language feature, then all existing programs will
start to receive compilation warnings about #[feature] directives which enabled
the new feature (because the directive is no longer necessary). However, if
Expand Down
21 changes: 14 additions & 7 deletions src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,17 @@ fn method_context(cx: &Context, m: &ast::Method) -> MethodContext {
}
}
}
ty::TypeTraitItem(typedef) => {
match typedef.container {
ty::TraitContainer(..) => TraitDefaultImpl,
ty::ImplContainer(cid) => {
match ty::impl_trait_ref(cx.tcx, cid) {
Some(..) => TraitImpl,
None => PlainImpl
}
}
}
}
}
}
}
Expand Down Expand Up @@ -1511,13 +1522,9 @@ impl LintPass for Stability {
method_num: index,
..
}) => {
match ty::trait_item(cx.tcx,
trait_ref.def_id,
index) {
ty::MethodTraitItem(method) => {
method.def_id
}
}
ty::trait_item(cx.tcx,
trait_ref.def_id,
index).def_id()
}
}
}
Expand Down
21 changes: 21 additions & 0 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
//! for all lint attributes.

use middle::privacy::ExportedItems;
use middle::subst;
use middle::ty;
use middle::typeck::astconv::AstConv;
use middle::typeck::infer;
Expand Down Expand Up @@ -491,6 +492,26 @@ impl<'a, 'tcx> AstConv<'tcx> for Context<'a, 'tcx>{
fn ty_infer(&self, _span: Span) -> ty::t {
infer::new_infer_ctxt(self.tcx).next_ty_var()
}

fn associated_types_of_trait_are_valid(&self, _: ty::t, _: ast::DefId)
-> bool {
// FIXME(pcwalton): This is wrong.
true
}

fn associated_type_binding(&self,
_: Span,
_: Option<ty::t>,
trait_id: ast::DefId,
associated_type_id: ast::DefId)
-> ty::t {
// FIXME(pcwalton): This is wrong.
let trait_def = self.get_trait_def(trait_id);
let index = ty::associated_type_parameter_index(self.tcx,
&*trait_def,
associated_type_id);
ty::mk_param(self.tcx, subst::TypeSpace, index, associated_type_id)
}
}

impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
Expand Down
6 changes: 6 additions & 0 deletions src/librustc/metadata/csearch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,3 +349,9 @@ pub fn get_stability(cstore: &cstore::CStore,
let cdata = cstore.get_crate_data(def.krate);
decoder::get_stability(&*cdata, def.node)
}

pub fn is_associated_type(cstore: &cstore::CStore, def: ast::DefId) -> bool {
let cdata = cstore.get_crate_data(def.krate);
decoder::is_associated_type(&*cdata, def.node)
}

27 changes: 25 additions & 2 deletions src/librustc/metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use metadata::tydecode::{parse_ty_data, parse_region_data, parse_def_id,
parse_bare_fn_ty_data, parse_trait_ref_data};
use middle::def;
use middle::lang_items;
use middle::resolve::TraitItemKind;
use middle::resolve::{TraitItemKind, TypeTraitItemKind};
use middle::subst;
use middle::ty::{ImplContainer, TraitContainer};
use middle::ty;
Expand Down Expand Up @@ -167,6 +167,8 @@ fn item_visibility(item: rbml::Doc) -> ast::Visibility {
}

fn item_sort(item: rbml::Doc) -> char {
// NB(pcwalton): The default of 'r' here is relied upon in
// `is_associated_type` below.
let mut ret = 'r';
reader::tagged_docs(item, tag_item_trait_item_sort, |doc| {
ret = doc.as_str_slice().as_bytes()[0] as char;
Expand Down Expand Up @@ -714,6 +716,7 @@ pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId)
let def_id = item_def_id(doc, cdata);
match item_sort(doc) {
'r' | 'p' => impl_items.push(ty::MethodTraitItemId(def_id)),
't' => impl_items.push(ty::TypeTraitItemId(def_id)),
_ => fail!("unknown impl item sort"),
}
true
Expand All @@ -733,6 +736,7 @@ pub fn get_trait_item_name_and_kind(intr: Rc<IdentInterner>,
let explicit_self = get_explicit_self(doc);
(name, TraitItemKind::from_explicit_self_category(explicit_self))
}
't' => (name, TypeTraitItemKind),
c => {
fail!("get_trait_item_name_and_kind(): unknown trait item kind \
in metadata: `{}`", c)
Expand All @@ -758,13 +762,13 @@ pub fn get_impl_or_trait_item(intr: Rc<IdentInterner>,
};

let name = item_name(&*intr, method_doc);
let vis = item_visibility(method_doc);

match item_sort(method_doc) {
'r' | 'p' => {
let generics = doc_generics(method_doc, tcx, cdata,
tag_method_ty_generics);
let fty = doc_method_fty(method_doc, tcx, cdata);
let vis = item_visibility(method_doc);
let explicit_self = get_explicit_self(method_doc);
let provided_source = get_provided_source(method_doc, cdata);

Expand All @@ -777,6 +781,14 @@ pub fn get_impl_or_trait_item(intr: Rc<IdentInterner>,
container,
provided_source)))
}
't' => {
ty::TypeTraitItem(Rc::new(ty::AssociatedType {
ident: name,
vis: vis,
def_id: def_id,
container: container,
}))
}
_ => fail!("unknown impl/trait item sort"),
}
}
Expand All @@ -790,6 +802,7 @@ pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId)
let def_id = item_def_id(mth, cdata);
match item_sort(mth) {
'r' | 'p' => result.push(ty::MethodTraitItemId(def_id)),
't' => result.push(ty::TypeTraitItemId(def_id)),
_ => fail!("unknown trait item sort"),
}
true
Expand Down Expand Up @@ -827,6 +840,7 @@ pub fn get_provided_trait_methods(intr: Rc<IdentInterner>,
ty::MethodTraitItem(ref method) => {
result.push((*method).clone())
}
ty::TypeTraitItem(_) => {}
}
}
true
Expand Down Expand Up @@ -1394,3 +1408,12 @@ fn doc_generics(base_doc: rbml::Doc,

ty::Generics { types: types, regions: regions }
}

pub fn is_associated_type(cdata: Cmd, id: ast::NodeId) -> bool {
let items = reader::get_doc(rbml::Doc::new(cdata.data()), tag_items);
match maybe_find_item(id, items) {
None => false,
Some(item) => item_sort(item) == 't',
}
}

Loading

0 comments on commit 9508faa

Please sign in to comment.