Skip to content

Commit

Permalink
Switch to using predicates to drive checking. Correct various tests --
Browse files Browse the repository at this point in the history
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`).
  • Loading branch information
nikomatsakis committed Dec 13, 2014
1 parent 2be6c4f commit 9f492fe
Show file tree
Hide file tree
Showing 39 changed files with 1,063 additions and 869 deletions.
2 changes: 1 addition & 1 deletion src/libcore/kinds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

/// Types able to be transferred across task boundaries.
#[lang="send"]
pub trait Send for Sized? {
pub trait Send for Sized? : 'static {
// empty.
}

Expand Down
4 changes: 4 additions & 0 deletions src/librustc/metadata/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,3 +251,7 @@ pub const tag_type_param_def: uint = 0xa5;

pub const tag_item_generics: uint = 0xa6;
pub const tag_method_ty_generics: uint = 0xa7;

pub const tag_predicate: uint = 0xa8;
pub const tag_predicate_space: uint = 0xa9;
pub const tag_predicate_data: uint = 0xb0;
16 changes: 14 additions & 2 deletions src/librustc/metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ use metadata::csearch;
use metadata::cstore;
use metadata::tydecode::{parse_ty_data, parse_region_data, parse_def_id,
parse_type_param_def_data, parse_bounds_data,
parse_bare_fn_ty_data, parse_trait_ref_data};
parse_bare_fn_ty_data, parse_trait_ref_data,
parse_predicate_data};
use middle::def;
use middle::lang_items;
use middle::resolve::{TraitItemKind, TypeTraitItemKind};
Expand Down Expand Up @@ -1437,7 +1438,18 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc,
true
});

let predicates = subst::VecPerParamSpace::empty(); // TODO fix in later commit
let mut predicates = subst::VecPerParamSpace::empty();
reader::tagged_docs(doc, tag_predicate, |predicate_doc| {
let space_doc = reader::get_doc(predicate_doc, tag_predicate_space);
let space = subst::ParamSpace::from_uint(reader::doc_as_u8(space_doc) as uint);

let data_doc = reader::get_doc(predicate_doc, tag_predicate_data);
let data = parse_predicate_data(data_doc.data, data_doc.start, cdata.cnum, tcx,
|_, did| translate_def_id(cdata, did));

predicates.push(space, data);
true
});

ty::Generics { types: types, regions: regions, predicates: predicates }
}
Expand Down
12 changes: 12 additions & 0 deletions src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,18 @@ fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder,
rbml_w.end_tag();
}

for (space, _, predicate) in generics.predicates.iter_enumerated() {
rbml_w.start_tag(tag_predicate);

rbml_w.wr_tagged_u8(tag_predicate_space, space as u8);

rbml_w.start_tag(tag_predicate_data);
tyencode::enc_predicate(rbml_w.writer, ty_str_ctxt, predicate);
rbml_w.end_tag();

rbml_w.end_tag();
}

rbml_w.end_tag();
}

Expand Down
29 changes: 28 additions & 1 deletion src/librustc/metadata/tydecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ fn parse_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did) -> Ty<'tcx> {
st.tcx.rcache.borrow_mut().insert(key, tt);
return tt;
}
'"' => {
'\"' => {
let _ = parse_def(st, TypeWithId, |x,y| conv(x,y));
let inner = parse_ty(st, |x,y| conv(x,y));
inner
Expand Down Expand Up @@ -646,6 +646,33 @@ pub fn parse_def_id(buf: &[u8]) -> ast::DefId {
ast::DefId { krate: crate_num, node: def_num }
}

pub fn parse_predicate_data<'tcx>(data: &[u8],
start: uint,
crate_num: ast::CrateNum,
tcx: &ty::ctxt<'tcx>,
conv: conv_did)
-> ty::Predicate<'tcx>
{
let mut st = parse_state_from_data(data, crate_num, start, tcx);
parse_predicate(&mut st, conv)
}

pub fn parse_predicate<'a,'tcx>(st: &mut PState<'a, 'tcx>,
conv: conv_did)
-> ty::Predicate<'tcx>
{
match next(st) {
't' => ty::Predicate::Trait(Rc::new(parse_trait_ref(st, conv))),
'e' => ty::Predicate::Equate(parse_ty(st, |x,y| conv(x,y)),
parse_ty(st, |x,y| conv(x,y))),
'r' => ty::Predicate::RegionOutlives(parse_region(st, |x,y| conv(x,y)),
parse_region(st, |x,y| conv(x,y))),
'o' => ty::Predicate::TypeOutlives(parse_ty(st, |x,y| conv(x,y)),
parse_region(st, |x,y| conv(x,y))),
c => panic!("Encountered invalid character in metadata: {}", c)
}
}

pub fn parse_type_param_def_data<'tcx>(data: &[u8], start: uint,
crate_num: ast::CrateNum, tcx: &ty::ctxt<'tcx>,
conv: conv_did) -> ty::TypeParameterDef<'tcx>
Expand Down
27 changes: 27 additions & 0 deletions src/librustc/metadata/tyencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,3 +413,30 @@ pub fn enc_type_param_def<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tc
enc_bounds(w, cx, &v.bounds);
enc_opt(w, v.default, |w, t| enc_ty(w, cx, t));
}

pub fn enc_predicate<'a, 'tcx>(w: &mut SeekableMemWriter,
cx: &ctxt<'a, 'tcx>,
p: &ty::Predicate<'tcx>)
{
match *p {
ty::Predicate::Trait(ref trait_ref) => {
mywrite!(w, "t");
enc_trait_ref(w, cx, &**trait_ref);
}
ty::Predicate::Equate(a, b) => {
mywrite!(w, "e");
enc_ty(w, cx, a);
enc_ty(w, cx, b);
}
ty::Predicate::RegionOutlives(a, b) => {
mywrite!(w, "r");
enc_region(w, cx, a);
enc_region(w, cx, b);
}
ty::Predicate::TypeOutlives(a, b) => {
mywrite!(w, "o");
enc_ty(w, cx, a);
enc_region(w, cx, b);
}
}
}
21 changes: 12 additions & 9 deletions src/librustc/middle/check_static.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use middle::infer;
use middle::traits;
use middle::mem_categorization as mc;
use middle::expr_use_visitor as euv;
use util::common::ErrorReported;
use util::nodemap::NodeSet;

use syntax::ast;
Expand Down Expand Up @@ -119,15 +120,17 @@ impl<'a, 'tcx> CheckStaticVisitor<'a, 'tcx> {
let ty = ty::node_id_to_type(self.tcx, e.id);
let infcx = infer::new_infer_ctxt(self.tcx);
let mut fulfill_cx = traits::FulfillmentContext::new();
let cause = traits::ObligationCause::dummy();
let obligation = traits::obligation_for_builtin_bound(self.tcx, cause, ty,
ty::BoundSync);
fulfill_cx.register_obligation(self.tcx, obligation.unwrap());
let env = ty::empty_parameter_environment();
let result = fulfill_cx.select_all_or_error(&infcx, &env, self.tcx).is_ok();
if !result {
self.tcx.sess.span_err(e.span, "shared static items must have a \
type which implements Sync");
match traits::trait_ref_for_builtin_bound(self.tcx, ty::BoundSync, ty) {
Ok(trait_ref) => {
fulfill_cx.register_trait_ref(self.tcx, trait_ref,
traits::ObligationCause::dummy());
let env = ty::empty_parameter_environment();
if !fulfill_cx.select_all_or_error(&infcx, &env, self.tcx).is_ok() {
self.tcx.sess.span_err(e.span, "shared static items must have a \
type which implements Sync");
}
}
Err(ErrorReported) => { }
}
}
}
Expand Down
Loading

0 comments on commit 9f492fe

Please sign in to comment.