Skip to content

Commit

Permalink
librustc: Implement associated types behind a feature gate.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
pcwalton committed Sep 17, 2014
1 parent 8067f44 commit 78a8418
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
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
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
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
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
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',
}
}

5 comments on commit 78a8418

@bors
Copy link
Contributor

@bors bors commented on 78a8418 Sep 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from nikomatsakis
at pcwalton@78a8418

@bors
Copy link
Contributor

@bors bors commented on 78a8418 Sep 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging pcwalton/rust/associated-items = 78a8418 into auto

@bors
Copy link
Contributor

@bors bors commented on 78a8418 Sep 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pcwalton/rust/associated-items = 78a8418 merged ok, testing candidate = 9508faa

@bors
Copy link
Contributor

@bors bors commented on 78a8418 Sep 18, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on 78a8418 Sep 18, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 9508faa

Please sign in to comment.