Skip to content

Commit 2d90b91

Browse files
committed
auto merge of #19683 : nikomatsakis/rust/generalized-where-clauses, r=nrc
This patch does not itself enable generalized where clauses, but it lays the groundwork. Rather than storing a list of bounds per type parameter, the trait selection and other logic is now driven by a unified list of predicates. All predicate handling is now driven through a common interface. This also fixes a number of bugs where region predicates were being dropped on the floor. As a drive-by, this patch also fixes some bugs in the opt-out-copy feature flag. That said, this patch does not change the parser or AST in any way, so we still *generate* the list of predicates by walking a list of bounds (and we still *store* the bounds on the `TypeParameterDef` and so on). Those will get patched in a follow-up. The commits in this case are standalone; the first few are simple refactorings. r? @nick29581 cc @aturon
2 parents 8c66927 + 124e1e1 commit 2d90b91

Some content is hidden

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

47 files changed

+1440
-1080
lines changed

src/libcore/kinds.rs

+1-1
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/diagnostics.rs

-85
Original file line numberDiff line numberDiff line change
@@ -40,89 +40,8 @@ register_diagnostics!(
4040
E0019,
4141
E0020,
4242
E0022,
43-
E0023,
44-
E0024,
45-
E0025,
46-
E0026,
47-
E0027,
48-
E0029,
49-
E0030,
50-
E0031,
51-
E0033,
52-
E0034,
53-
E0035,
54-
E0036,
55-
E0038,
56-
E0040,
57-
E0044,
58-
E0045,
59-
E0046,
60-
E0049,
61-
E0050,
62-
E0051,
63-
E0052,
64-
E0053,
65-
E0054,
66-
E0055,
67-
E0056,
68-
E0057,
69-
E0059,
70-
E0060,
71-
E0061,
72-
E0062,
73-
E0063,
74-
E0066,
75-
E0067,
76-
E0068,
77-
E0069,
78-
E0070,
79-
E0071,
80-
E0072,
81-
E0073,
82-
E0074,
83-
E0075,
84-
E0076,
85-
E0077,
86-
E0079,
87-
E0080,
88-
E0081,
89-
E0082,
90-
E0083,
91-
E0084,
92-
E0085,
93-
E0086,
94-
E0087,
95-
E0088,
96-
E0089,
97-
E0090,
98-
E0091,
99-
E0092,
100-
E0093,
101-
E0094,
102-
E0100,
103-
E0101,
104-
E0102,
105-
E0103,
106-
E0104,
107-
E0106,
108-
E0107,
109-
E0108,
11043
E0109,
11144
E0110,
112-
E0116,
113-
E0117,
114-
E0118,
115-
E0119,
116-
E0120,
117-
E0121,
118-
E0122,
119-
E0124,
120-
E0127,
121-
E0128,
122-
E0129,
123-
E0130,
124-
E0131,
125-
E0132,
12645
E0133,
12746
E0134,
12847
E0135,
@@ -131,16 +50,12 @@ register_diagnostics!(
13150
E0138,
13251
E0139,
13352
E0140,
134-
E0141,
13553
E0152,
13654
E0153,
13755
E0157,
13856
E0158,
139-
E0159,
14057
E0161,
14158
E0162,
142-
E0163,
143-
E0164,
14459
E0165,
14560
E0166,
14661
E0167,

src/librustc/metadata/common.rs

+4
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/csearch.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ use middle::def;
2121
use middle::lang_items;
2222
use middle::resolve;
2323
use middle::ty;
24-
use middle::subst::VecPerParamSpace;
2524

2625
use rbml;
2726
use rbml::reader;
@@ -250,9 +249,8 @@ pub fn get_field_type<'tcx>(tcx: &ty::ctxt<'tcx>, class_id: ast::DefId,
250249
});
251250
let ty = decoder::item_type(def, the_field, tcx, &*cdata);
252251
ty::Polytype {
253-
generics: ty::Generics {types: VecPerParamSpace::empty(),
254-
regions: VecPerParamSpace::empty()},
255-
ty: ty
252+
generics: ty::Generics::empty(),
253+
ty: ty,
256254
}
257255
}
258256

src/librustc/metadata/decoder.rs

+16-2
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,20 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc,
14371438
true
14381439
});
14391440

1440-
ty::Generics { types: types, regions: regions }
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+
});
1453+
1454+
ty::Generics { types: types, regions: regions, predicates: predicates }
14411455
}
14421456

14431457
pub fn is_associated_type(cdata: Cmd, id: ast::NodeId) -> bool {

src/librustc/metadata/encoder.rs

+12
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

+28-1
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

+27
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/astencode.rs

+34-1
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,8 @@ trait rbml_writer_helpers<'tcx> {
830830
fn emit_tys<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, tys: &[Ty<'tcx>]);
831831
fn emit_type_param_def<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
832832
type_param_def: &ty::TypeParameterDef<'tcx>);
833+
fn emit_predicate<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
834+
predicate: &ty::Predicate<'tcx>);
833835
fn emit_trait_ref<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
834836
ty: &ty::TraitRef<'tcx>);
835837
fn emit_polytype<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
@@ -936,6 +938,15 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
936938
});
937939
}
938940

941+
fn emit_predicate<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
942+
predicate: &ty::Predicate<'tcx>) {
943+
self.emit_opaque(|this| {
944+
Ok(tyencode::enc_predicate(this.writer,
945+
&ecx.ty_str_ctxt(),
946+
predicate))
947+
});
948+
}
949+
939950
fn emit_polytype<'a>(&mut self,
940951
ecx: &e::EncodeContext<'a, 'tcx>,
941952
pty: ty::Polytype<'tcx>) {
@@ -953,6 +964,11 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
953964
Ok(encode_vec_per_param_space(
954965
this, &pty.generics.regions,
955966
|this, def| def.encode(this).unwrap()))
967+
});
968+
this.emit_struct_field("predicates", 2, |this| {
969+
Ok(encode_vec_per_param_space(
970+
this, &pty.generics.predicates,
971+
|this, def| this.emit_predicate(ecx, def)))
956972
})
957973
})
958974
});
@@ -1336,6 +1352,8 @@ trait rbml_decoder_decoder_helpers<'tcx> {
13361352
-> Rc<ty::TraitRef<'tcx>>;
13371353
fn read_type_param_def<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
13381354
-> ty::TypeParameterDef<'tcx>;
1355+
fn read_predicate<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
1356+
-> ty::Predicate<'tcx>;
13391357
fn read_polytype<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
13401358
-> ty::Polytype<'tcx>;
13411359
fn read_existential_bounds<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
@@ -1536,6 +1554,15 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
15361554
}).unwrap()
15371555
}
15381556

1557+
fn read_predicate<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
1558+
-> ty::Predicate<'tcx>
1559+
{
1560+
self.read_opaque(|this, doc| {
1561+
Ok(tydecode::parse_predicate_data(doc.data, doc.start, dcx.cdata.cnum, dcx.tcx,
1562+
|s, a| this.convert_def_id(dcx, s, a)))
1563+
}).unwrap()
1564+
}
1565+
15391566
fn read_polytype<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
15401567
-> ty::Polytype<'tcx> {
15411568
self.read_struct("Polytype", 2, |this| {
@@ -1553,7 +1580,13 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
15531580
this.read_struct_field("regions", 1, |this| {
15541581
Ok(this.read_vec_per_param_space(
15551582
|this| Decodable::decode(this).unwrap()))
1556-
}).unwrap()
1583+
}).unwrap(),
1584+
1585+
predicates:
1586+
this.read_struct_field("predicates", 2, |this| {
1587+
Ok(this.read_vec_per_param_space(
1588+
|this| this.read_predicate(dcx)))
1589+
}).unwrap(),
15571590
})
15581591
})
15591592
}).unwrap(),

src/librustc/middle/check_static.rs

+13-10
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@ 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;
3738
use syntax::print::pprust;
3839
use syntax::visit::Visitor;
39-
use syntax::codemap::{DUMMY_SP, Span};
40+
use syntax::codemap::Span;
4041
use syntax::visit;
4142

4243
#[deriving(Eq, PartialEq)]
@@ -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::misc(DUMMY_SP);
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)