Skip to content

Commit 9f492fe

Browse files
committed
Switch to using predicates to drive checking. Correct various tests --
in most cases, just the error message changed, but in some cases we are reporting new errors that OUGHT to have been reported before but we're overlooked (mostly involving the `'static` bound on `Send`).
1 parent 2be6c4f commit 9f492fe

39 files changed

+1063
-869
lines changed

src/libcore/kinds.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
2020
/// Types able to be transferred across task boundaries.
2121
#[lang="send"]
22-
pub trait Send for Sized? {
22+
pub trait Send for Sized? : 'static {
2323
// empty.
2424
}
2525

src/librustc/metadata/common.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,3 +251,7 @@ pub const tag_type_param_def: uint = 0xa5;
251251

252252
pub const tag_item_generics: uint = 0xa6;
253253
pub const tag_method_ty_generics: uint = 0xa7;
254+
255+
pub const tag_predicate: uint = 0xa8;
256+
pub const tag_predicate_space: uint = 0xa9;
257+
pub const tag_predicate_data: uint = 0xb0;

src/librustc/metadata/decoder.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ use metadata::csearch;
2323
use metadata::cstore;
2424
use metadata::tydecode::{parse_ty_data, parse_region_data, parse_def_id,
2525
parse_type_param_def_data, parse_bounds_data,
26-
parse_bare_fn_ty_data, parse_trait_ref_data};
26+
parse_bare_fn_ty_data, parse_trait_ref_data,
27+
parse_predicate_data};
2728
use middle::def;
2829
use middle::lang_items;
2930
use middle::resolve::{TraitItemKind, TypeTraitItemKind};
@@ -1437,7 +1438,18 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc,
14371438
true
14381439
});
14391440

1440-
let predicates = subst::VecPerParamSpace::empty(); // TODO fix in later commit
1441+
let mut predicates = subst::VecPerParamSpace::empty();
1442+
reader::tagged_docs(doc, tag_predicate, |predicate_doc| {
1443+
let space_doc = reader::get_doc(predicate_doc, tag_predicate_space);
1444+
let space = subst::ParamSpace::from_uint(reader::doc_as_u8(space_doc) as uint);
1445+
1446+
let data_doc = reader::get_doc(predicate_doc, tag_predicate_data);
1447+
let data = parse_predicate_data(data_doc.data, data_doc.start, cdata.cnum, tcx,
1448+
|_, did| translate_def_id(cdata, did));
1449+
1450+
predicates.push(space, data);
1451+
true
1452+
});
14411453

14421454
ty::Generics { types: types, regions: regions, predicates: predicates }
14431455
}

src/librustc/metadata/encoder.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,18 @@ fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder,
803803
rbml_w.end_tag();
804804
}
805805

806+
for (space, _, predicate) in generics.predicates.iter_enumerated() {
807+
rbml_w.start_tag(tag_predicate);
808+
809+
rbml_w.wr_tagged_u8(tag_predicate_space, space as u8);
810+
811+
rbml_w.start_tag(tag_predicate_data);
812+
tyencode::enc_predicate(rbml_w.writer, ty_str_ctxt, predicate);
813+
rbml_w.end_tag();
814+
815+
rbml_w.end_tag();
816+
}
817+
806818
rbml_w.end_tag();
807819
}
808820

src/librustc/metadata/tydecode.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ fn parse_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did) -> Ty<'tcx> {
470470
st.tcx.rcache.borrow_mut().insert(key, tt);
471471
return tt;
472472
}
473-
'"' => {
473+
'\"' => {
474474
let _ = parse_def(st, TypeWithId, |x,y| conv(x,y));
475475
let inner = parse_ty(st, |x,y| conv(x,y));
476476
inner
@@ -646,6 +646,33 @@ pub fn parse_def_id(buf: &[u8]) -> ast::DefId {
646646
ast::DefId { krate: crate_num, node: def_num }
647647
}
648648

649+
pub fn parse_predicate_data<'tcx>(data: &[u8],
650+
start: uint,
651+
crate_num: ast::CrateNum,
652+
tcx: &ty::ctxt<'tcx>,
653+
conv: conv_did)
654+
-> ty::Predicate<'tcx>
655+
{
656+
let mut st = parse_state_from_data(data, crate_num, start, tcx);
657+
parse_predicate(&mut st, conv)
658+
}
659+
660+
pub fn parse_predicate<'a,'tcx>(st: &mut PState<'a, 'tcx>,
661+
conv: conv_did)
662+
-> ty::Predicate<'tcx>
663+
{
664+
match next(st) {
665+
't' => ty::Predicate::Trait(Rc::new(parse_trait_ref(st, conv))),
666+
'e' => ty::Predicate::Equate(parse_ty(st, |x,y| conv(x,y)),
667+
parse_ty(st, |x,y| conv(x,y))),
668+
'r' => ty::Predicate::RegionOutlives(parse_region(st, |x,y| conv(x,y)),
669+
parse_region(st, |x,y| conv(x,y))),
670+
'o' => ty::Predicate::TypeOutlives(parse_ty(st, |x,y| conv(x,y)),
671+
parse_region(st, |x,y| conv(x,y))),
672+
c => panic!("Encountered invalid character in metadata: {}", c)
673+
}
674+
}
675+
649676
pub fn parse_type_param_def_data<'tcx>(data: &[u8], start: uint,
650677
crate_num: ast::CrateNum, tcx: &ty::ctxt<'tcx>,
651678
conv: conv_did) -> ty::TypeParameterDef<'tcx>

src/librustc/metadata/tyencode.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,3 +413,30 @@ pub fn enc_type_param_def<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tc
413413
enc_bounds(w, cx, &v.bounds);
414414
enc_opt(w, v.default, |w, t| enc_ty(w, cx, t));
415415
}
416+
417+
pub fn enc_predicate<'a, 'tcx>(w: &mut SeekableMemWriter,
418+
cx: &ctxt<'a, 'tcx>,
419+
p: &ty::Predicate<'tcx>)
420+
{
421+
match *p {
422+
ty::Predicate::Trait(ref trait_ref) => {
423+
mywrite!(w, "t");
424+
enc_trait_ref(w, cx, &**trait_ref);
425+
}
426+
ty::Predicate::Equate(a, b) => {
427+
mywrite!(w, "e");
428+
enc_ty(w, cx, a);
429+
enc_ty(w, cx, b);
430+
}
431+
ty::Predicate::RegionOutlives(a, b) => {
432+
mywrite!(w, "r");
433+
enc_region(w, cx, a);
434+
enc_region(w, cx, b);
435+
}
436+
ty::Predicate::TypeOutlives(a, b) => {
437+
mywrite!(w, "o");
438+
enc_ty(w, cx, a);
439+
enc_region(w, cx, b);
440+
}
441+
}
442+
}

src/librustc/middle/check_static.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use middle::infer;
3131
use middle::traits;
3232
use middle::mem_categorization as mc;
3333
use middle::expr_use_visitor as euv;
34+
use util::common::ErrorReported;
3435
use util::nodemap::NodeSet;
3536

3637
use syntax::ast;
@@ -119,15 +120,17 @@ impl<'a, 'tcx> CheckStaticVisitor<'a, 'tcx> {
119120
let ty = ty::node_id_to_type(self.tcx, e.id);
120121
let infcx = infer::new_infer_ctxt(self.tcx);
121122
let mut fulfill_cx = traits::FulfillmentContext::new();
122-
let cause = traits::ObligationCause::dummy();
123-
let obligation = traits::obligation_for_builtin_bound(self.tcx, cause, ty,
124-
ty::BoundSync);
125-
fulfill_cx.register_obligation(self.tcx, obligation.unwrap());
126-
let env = ty::empty_parameter_environment();
127-
let result = fulfill_cx.select_all_or_error(&infcx, &env, self.tcx).is_ok();
128-
if !result {
129-
self.tcx.sess.span_err(e.span, "shared static items must have a \
130-
type which implements Sync");
123+
match traits::trait_ref_for_builtin_bound(self.tcx, ty::BoundSync, ty) {
124+
Ok(trait_ref) => {
125+
fulfill_cx.register_trait_ref(self.tcx, trait_ref,
126+
traits::ObligationCause::dummy());
127+
let env = ty::empty_parameter_environment();
128+
if !fulfill_cx.select_all_or_error(&infcx, &env, self.tcx).is_ok() {
129+
self.tcx.sess.span_err(e.span, "shared static items must have a \
130+
type which implements Sync");
131+
}
132+
}
133+
Err(ErrorReported) => { }
131134
}
132135
}
133136
}

0 commit comments

Comments
 (0)