Skip to content

Commit 28422f7

Browse files
committed
Functional changes for associated constants. Cross-crate usage of associated constants is not yet working.
1 parent 0c59543 commit 28422f7

Some content is hidden

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

43 files changed

+1388
-294
lines changed

src/grammar/parser-lalr.y

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -505,10 +505,20 @@ trait_items
505505
;
506506

507507
trait_item
508-
: trait_type
508+
: trait_const
509+
| trait_type
509510
| trait_method
510511
;
511512

513+
trait_const
514+
: maybe_outer_attrs CONST ident maybe_const_default ';' { $$ = mk_node("ConstTraitItem", 3, $1, $3, $4); }
515+
;
516+
517+
maybe_const_default
518+
: '=' expr { $$ = mk_node("ConstDefault", 1, $2); }
519+
| %empty { $$ = mk_none(); }
520+
;
521+
512522
trait_type
513523
: maybe_outer_attrs TYPE ty_param ';' { $$ = mk_node("TypeTraitItem", 2, $1, $3); }
514524
;
@@ -611,7 +621,16 @@ impl_items
611621
impl_item
612622
: impl_method
613623
| item_macro
614-
| trait_type
624+
| impl_const
625+
| impl_type
626+
;
627+
628+
impl_const
629+
: attrs_and_vis item_const { $$ = mk_node("ImplConst", 1, $1, $2); }
630+
;
631+
632+
impl_type
633+
: attrs_and_vis TYPE ident generic_params '=' ty_sum ';' { $$ = mk_node("ImplType", 4, $1, $3, $4, $6); }
615634
;
616635

617636
item_fn

src/librustc/metadata/csearch.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,13 @@ pub fn get_provided_trait_methods<'tcx>(tcx: &ty::ctxt<'tcx>,
175175
decoder::get_provided_trait_methods(cstore.intr.clone(), &*cdata, def.node, tcx)
176176
}
177177

178+
pub fn get_associated_consts<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId)
179+
-> Vec<Rc<ty::AssociatedConst<'tcx>>> {
180+
let cstore = &tcx.sess.cstore;
181+
let cdata = cstore.get_crate_data(def.krate);
182+
decoder::get_associated_consts(cstore.intr.clone(), &*cdata, def.node, tcx)
183+
}
184+
178185
pub fn get_type_name_if_impl(cstore: &cstore::CStore, def: ast::DefId)
179186
-> Option<ast::Name> {
180187
let cdata = cstore.get_crate_data(def.krate);

src/librustc/metadata/decoder.rs

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,25 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
306306
-> DefLike {
307307
let fam = item_family(item);
308308
match fam {
309-
Constant => DlDef(def::DefConst(did)),
309+
Constant => {
310+
// Check whether we have an associated const item.
311+
if item_sort(item) == Some('C') {
312+
// Check whether the associated const is from a trait or impl.
313+
// See the comment for methods below.
314+
let provenance = if reader::maybe_get_doc(
315+
item, tag_item_trait_parent_sort).is_some() {
316+
def::FromTrait(item_reqd_and_translated_parent_item(cnum,
317+
item))
318+
} else {
319+
def::FromImpl(item_reqd_and_translated_parent_item(cnum,
320+
item))
321+
};
322+
DlDef(def::DefAssociatedConst(did, provenance))
323+
} else {
324+
// Regular const item.
325+
DlDef(def::DefConst(did))
326+
}
327+
}
310328
ImmStatic => DlDef(def::DefStatic(did, false)),
311329
MutStatic => DlDef(def::DefStatic(did, true)),
312330
Struct => DlDef(def::DefStruct(did)),
@@ -827,6 +845,7 @@ pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId)
827845
tag_item_impl_item, |doc| {
828846
let def_id = item_def_id(doc, cdata);
829847
match item_sort(doc) {
848+
Some('C') => impl_items.push(ty::ConstTraitItemId(def_id)),
830849
Some('r') | Some('p') => {
831850
impl_items.push(ty::MethodTraitItemId(def_id))
832851
}
@@ -878,6 +897,18 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
878897
let vis = item_visibility(method_doc);
879898

880899
match item_sort(method_doc) {
900+
Some('C') => {
901+
let ty = doc_type(method_doc, tcx, cdata);
902+
let default = get_provided_source(method_doc, cdata);
903+
ty::ConstTraitItem(Rc::new(ty::AssociatedConst {
904+
name: name,
905+
ty: ty,
906+
vis: vis,
907+
def_id: def_id,
908+
container: container,
909+
default: default,
910+
}))
911+
}
881912
Some('r') | Some('p') => {
882913
let generics = doc_generics(method_doc, tcx, cdata, tag_method_ty_generics);
883914
let predicates = doc_predicates(method_doc, tcx, cdata, tag_method_ty_generics);
@@ -915,6 +946,7 @@ pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId)
915946
reader::tagged_docs(item, tag_item_trait_item, |mth| {
916947
let def_id = item_def_id(mth, cdata);
917948
match item_sort(mth) {
949+
Some('C') => result.push(ty::ConstTraitItemId(def_id)),
918950
Some('r') | Some('p') => {
919951
result.push(ty::MethodTraitItemId(def_id));
920952
}
@@ -962,6 +994,34 @@ pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>,
962994
return result;
963995
}
964996

997+
pub fn get_associated_consts<'tcx>(intr: Rc<IdentInterner>,
998+
cdata: Cmd,
999+
id: ast::NodeId,
1000+
tcx: &ty::ctxt<'tcx>)
1001+
-> Vec<Rc<ty::AssociatedConst<'tcx>>> {
1002+
let data = cdata.data();
1003+
let item = lookup_item(id, data);
1004+
let mut result = Vec::new();
1005+
1006+
reader::tagged_docs(item, tag_item_trait_item, |ac_id| {
1007+
let did = item_def_id(ac_id, cdata);
1008+
let ac_doc = lookup_item(did.node, data);
1009+
1010+
if item_sort(ac_doc) == Some('C') {
1011+
let trait_item = get_impl_or_trait_item(intr.clone(),
1012+
cdata,
1013+
did.node,
1014+
tcx);
1015+
if let ty::ConstTraitItem(ref ac) = trait_item {
1016+
result.push((*ac).clone())
1017+
}
1018+
}
1019+
true
1020+
});
1021+
1022+
return result;
1023+
}
1024+
9651025
pub fn get_type_name_if_impl(cdata: Cmd,
9661026
node_id: ast::NodeId) -> Option<ast::Name> {
9671027
let item = lookup_item(node_id, cdata.data());

src/librustc/metadata/encoder.rs

Lines changed: 75 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,43 @@ fn encode_method_ty_fields<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
800800
encode_provided_source(rbml_w, method_ty.provided_source);
801801
}
802802

803+
fn encode_info_for_associated_const(ecx: &EncodeContext,
804+
rbml_w: &mut Encoder,
805+
associated_const: &ty::AssociatedConst,
806+
impl_path: PathElems,
807+
parent_id: NodeId,
808+
impl_item_opt: Option<&ast::ImplItem>) {
809+
debug!("encode_info_for_associated_const({:?},{:?})",
810+
associated_const.def_id,
811+
token::get_name(associated_const.name));
812+
813+
rbml_w.start_tag(tag_items_data_item);
814+
815+
encode_def_id(rbml_w, associated_const.def_id);
816+
encode_name(rbml_w, associated_const.name);
817+
encode_visibility(rbml_w, associated_const.vis);
818+
encode_family(rbml_w, 'C');
819+
encode_provided_source(rbml_w, associated_const.default);
820+
821+
encode_parent_item(rbml_w, local_def(parent_id));
822+
encode_item_sort(rbml_w, 'C');
823+
824+
encode_bounds_and_type_for_item(rbml_w, ecx, associated_const.def_id.local_id());
825+
826+
let stab = stability::lookup(ecx.tcx, associated_const.def_id);
827+
encode_stability(rbml_w, stab);
828+
829+
let elem = ast_map::PathName(associated_const.name);
830+
encode_path(rbml_w, impl_path.chain(Some(elem).into_iter()));
831+
832+
if let Some(ii) = impl_item_opt {
833+
encode_attributes(rbml_w, &ii.attrs);
834+
encode_inlined_item(ecx, rbml_w, IIImplItemRef(local_def(parent_id), ii));
835+
}
836+
837+
rbml_w.end_tag();
838+
}
839+
803840
fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
804841
rbml_w: &mut Encoder,
805842
m: &ty::Method<'tcx>,
@@ -1193,7 +1230,10 @@ fn encode_info_for_item(ecx: &EncodeContext,
11931230
for &item_def_id in items {
11941231
rbml_w.start_tag(tag_item_impl_item);
11951232
match item_def_id {
1196-
ty::ConstTraitItemId(_) => {}
1233+
ty::ConstTraitItemId(item_def_id) => {
1234+
encode_def_id(rbml_w, item_def_id);
1235+
encode_item_sort(rbml_w, 'C');
1236+
}
11971237
ty::MethodTraitItemId(item_def_id) => {
11981238
encode_def_id(rbml_w, item_def_id);
11991239
encode_item_sort(rbml_w, 'r');
@@ -1231,7 +1271,14 @@ fn encode_info_for_item(ecx: &EncodeContext,
12311271
});
12321272

12331273
match ty::impl_or_trait_item(tcx, trait_item_def_id.def_id()) {
1234-
ty::ConstTraitItem(_) => {}
1274+
ty::ConstTraitItem(ref associated_const) => {
1275+
encode_info_for_associated_const(ecx,
1276+
rbml_w,
1277+
&*associated_const,
1278+
path.clone(),
1279+
item.id,
1280+
ast_item)
1281+
}
12351282
ty::MethodTraitItem(ref method_type) => {
12361283
encode_info_for_method(ecx,
12371284
rbml_w,
@@ -1275,7 +1322,10 @@ fn encode_info_for_item(ecx: &EncodeContext,
12751322
for &method_def_id in &*ty::trait_item_def_ids(tcx, def_id) {
12761323
rbml_w.start_tag(tag_item_trait_item);
12771324
match method_def_id {
1278-
ty::ConstTraitItemId(_) => {}
1325+
ty::ConstTraitItemId(const_def_id) => {
1326+
encode_def_id(rbml_w, const_def_id);
1327+
encode_item_sort(rbml_w, 'C');
1328+
}
12791329
ty::MethodTraitItemId(method_def_id) => {
12801330
encode_def_id(rbml_w, method_def_id);
12811331
encode_item_sort(rbml_w, 'r');
@@ -1321,7 +1371,23 @@ fn encode_info_for_item(ecx: &EncodeContext,
13211371
ty::impl_or_trait_item(tcx, item_def_id.def_id());
13221372
let is_nonstatic_method;
13231373
match trait_item_type {
1324-
ty::ConstTraitItem(_) => {
1374+
ty::ConstTraitItem(associated_const) => {
1375+
encode_name(rbml_w, associated_const.name);
1376+
encode_def_id(rbml_w, associated_const.def_id);
1377+
encode_visibility(rbml_w, associated_const.vis);
1378+
1379+
encode_provided_source(rbml_w, associated_const.default);
1380+
1381+
let elem = ast_map::PathName(associated_const.name);
1382+
encode_path(rbml_w,
1383+
path.clone().chain(Some(elem).into_iter()));
1384+
1385+
encode_item_sort(rbml_w, 'C');
1386+
encode_family(rbml_w, 'C');
1387+
1388+
encode_bounds_and_type_for_item(rbml_w, ecx,
1389+
associated_const.def_id.local_id());
1390+
13251391
is_nonstatic_method = false;
13261392
}
13271393
ty::MethodTraitItem(method_ty) => {
@@ -1368,7 +1434,10 @@ fn encode_info_for_item(ecx: &EncodeContext,
13681434
let trait_item = &*ms[i];
13691435
encode_attributes(rbml_w, &trait_item.attrs);
13701436
match trait_item.node {
1371-
ast::ConstTraitItem(_, _) => {}
1437+
ast::ConstTraitItem(_, _) => {
1438+
encode_inlined_item(ecx, rbml_w,
1439+
IITraitItemRef(def_id, trait_item));
1440+
}
13721441
ast::MethodTraitItem(ref sig, ref body) => {
13731442
// If this is a static method, we've already
13741443
// encoded this.
@@ -1388,9 +1457,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
13881457
encode_method_argument_names(rbml_w, &sig.decl);
13891458
}
13901459

1391-
ast::TypeTraitItem(..) => {
1392-
encode_item_sort(rbml_w, 't');
1393-
}
1460+
ast::TypeTraitItem(..) => {}
13941461
}
13951462

13961463
rbml_w.end_tag();

src/librustc/middle/check_const.rs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,28 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
223223
}
224224
}
225225

226+
fn visit_trait_item(&mut self, t: &'v ast::TraitItem) {
227+
match t.node {
228+
ast::ConstTraitItem(_, ref default) => {
229+
if let Some(ref expr) = *default {
230+
self.global_expr(Mode::Const, &*expr);
231+
} else {
232+
visit::walk_trait_item(self, t);
233+
}
234+
}
235+
_ => self.with_mode(Mode::Var, |v| visit::walk_trait_item(v, t)),
236+
}
237+
}
238+
239+
fn visit_impl_item(&mut self, i: &'v ast::ImplItem) {
240+
match i.node {
241+
ast::ConstImplItem(_, ref expr) => {
242+
self.global_expr(Mode::Const, &*expr);
243+
}
244+
_ => self.with_mode(Mode::Var, |v| visit::walk_impl_item(v, i)),
245+
}
246+
}
247+
226248
fn visit_fn(&mut self,
227249
fk: visit::FnKind<'v>,
228250
fd: &'v ast::FnDecl,
@@ -468,13 +490,16 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
468490
Mode::Var => v.add_qualif(NOT_CONST)
469491
}
470492
}
471-
Some(def::DefConst(did)) => {
472-
if let Some(expr) = const_eval::lookup_const_by_id(v.tcx, did) {
493+
Some(def::DefConst(did)) |
494+
Some(def::DefAssociatedConst(did, _)) => {
495+
if let Some(expr) = const_eval::lookup_const_by_id(v.tcx, did,
496+
Some(e.id)) {
473497
let inner = v.global_expr(Mode::Const, expr);
474498
v.add_qualif(inner);
475499
} else {
476-
v.tcx.sess.span_bug(e.span, "DefConst doesn't point \
477-
to an ItemConst");
500+
v.tcx.sess.span_bug(e.span,
501+
"DefConst or DefAssociatedConst \
502+
doesn't point to a constant");
478503
}
479504
}
480505
def => {

src/librustc/middle/check_match.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,8 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
442442
ast::PatIdent(..) | ast::PatEnum(..) => {
443443
let def = self.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def());
444444
match def {
445-
Some(DefConst(did)) => match lookup_const_by_id(self.tcx, did) {
445+
Some(DefAssociatedConst(did, _)) |
446+
Some(DefConst(did)) => match lookup_const_by_id(self.tcx, did, Some(pat.id)) {
446447
Some(const_expr) => {
447448
const_expr_to_pat(self.tcx, const_expr, pat.span).map(|new_pat| {
448449

@@ -746,7 +747,7 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
746747
match pat.node {
747748
ast::PatIdent(..) =>
748749
match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
749-
Some(DefConst(..)) =>
750+
Some(DefConst(..)) | Some(DefAssociatedConst(..)) =>
750751
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
751752
been rewritten"),
752753
Some(DefStruct(_)) => vec!(Single),
@@ -755,15 +756,15 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
755756
},
756757
ast::PatEnum(..) =>
757758
match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
758-
Some(DefConst(..)) =>
759+
Some(DefConst(..)) | Some(DefAssociatedConst(..)) =>
759760
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
760761
been rewritten"),
761762
Some(DefVariant(_, id, _)) => vec!(Variant(id)),
762763
_ => vec!(Single)
763764
},
764765
ast::PatStruct(..) =>
765766
match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
766-
Some(DefConst(..)) =>
767+
Some(DefConst(..)) | Some(DefAssociatedConst(..)) =>
767768
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
768769
been rewritten"),
769770
Some(DefVariant(_, id, _)) => vec!(Variant(id)),
@@ -861,7 +862,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
861862
ast::PatIdent(_, _, _) => {
862863
let opt_def = cx.tcx.def_map.borrow().get(&pat_id).map(|d| d.full_def());
863864
match opt_def {
864-
Some(DefConst(..)) =>
865+
Some(DefConst(..)) | Some(DefAssociatedConst(..)) =>
865866
cx.tcx.sess.span_bug(pat_span, "const pattern should've \
866867
been rewritten"),
867868
Some(DefVariant(_, id, _)) => if *constructor == Variant(id) {
@@ -876,7 +877,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
876877
ast::PatEnum(_, ref args) => {
877878
let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
878879
match def {
879-
DefConst(..) =>
880+
DefConst(..) | DefAssociatedConst(..) =>
880881
cx.tcx.sess.span_bug(pat_span, "const pattern should've \
881882
been rewritten"),
882883
DefVariant(_, id, _) if *constructor != Variant(id) => None,
@@ -894,7 +895,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
894895
// Is this a struct or an enum variant?
895896
let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
896897
let class_id = match def {
897-
DefConst(..) =>
898+
DefConst(..) | DefAssociatedConst(..) =>
898899
cx.tcx.sess.span_bug(pat_span, "const pattern should've \
899900
been rewritten"),
900901
DefVariant(_, variant_id, _) => if *constructor == Variant(variant_id) {

0 commit comments

Comments
 (0)