Skip to content

Commit eb4d39e

Browse files
committed
libstd: Remove "dual impls" from the language and enforce coherence rules. r=brson
"Dual impls" are impls that are both type implementations and trait implementations. They can lead to ambiguity and so this patch removes them from the language. This also enforces coherence rules. Without this patch, records can implement traits not defined in the current crate. This patch fixes this, and updates all of rustc to adhere to the new enforcement. Most of this patch is fixing rustc to obey the coherence rules, which involves converting a bunch of records to structs.
1 parent f1e78c6 commit eb4d39e

Some content is hidden

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

77 files changed

+704
-837
lines changed

src/libcore/gc.rs

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ with destructors.
4242
#[allow(structural_records)];
4343

4444
use cast;
45+
use container::{Container, Mutable, Map, Set};
4546
use io;
4647
use libc::{size_t, uintptr_t};
4748
use option::{None, Option, Some};

src/libcore/hashmap.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
use cmp::Eq;
1818
use hash::Hash;
19-
use prelude::*;
2019
use to_bytes::IterBytes;
2120

2221
/// Open addressing with linear probing.
@@ -464,6 +463,7 @@ pub mod linear {
464463

465464
#[test]
466465
pub mod test {
466+
use container::{Container, Mutable, Map, Set};
467467
use option::{None, Some};
468468
use hashmap::linear::LinearMap;
469469
use hashmap::linear;

src/libcore/num.rs

+5
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ pub trait Num {
2323
static pure fn from_int(n: int) -> self;
2424
}
2525

26+
pub trait IntConvertible {
27+
pure fn to_int(&self) -> int;
28+
static pure fn from_int(n: int) -> self;
29+
}
30+
2631
pub trait Zero {
2732
static pure fn zero() -> self;
2833
}

src/libcore/pipes.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,9 @@ use either::{Either, Left, Right};
9696
use kinds::Owned;
9797
use libc;
9898
use option;
99-
use option::unwrap;
99+
use option::{None, Option, Some, unwrap};
100100
use pipes;
101101
use ptr;
102-
use prelude::*;
103102
use private;
104103
use task;
105104
use vec;

src/libcore/prelude.rs

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ pub use vec::{ImmutableEqVector, ImmutableCopyableVector};
3535
pub use vec::{OwnedVector, OwnedCopyableVector};
3636
pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
3737
pub use iter::{CopyableOrderedIter, CopyableNonstrictIter, Times};
38+
pub use container::{Container, Mutable, Map, Set};
39+
pub use pipes::{GenericChan, GenericPort};
3840

3941
pub use num::Num;
4042
pub use ptr::Ptr;

src/libcore/private/weak_task.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use option::{Some, None, swap_unwrap};
2222
use private::at_exit::at_exit;
2323
use private::global::global_data_clone_create;
2424
use private::finally::Finally;
25-
use pipes::{Port, Chan, SharedChan, stream};
25+
use pipes::{Port, Chan, SharedChan, GenericSmartChan, stream};
2626
use task::{Task, task, spawn};
2727
use task::rt::{task_id, get_task_id};
2828
use hashmap::linear::LinearMap;

src/libcore/task/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use iter;
4545
use libc;
4646
use option;
4747
use result::Result;
48-
use pipes::{stream, Chan, Port, SharedChan};
48+
use pipes::{stream, Chan, GenericChan, GenericPort, Port, SharedChan};
4949
use pipes;
5050
use prelude::*;
5151
use ptr;

src/libcore/task/spawn.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,10 @@
7474
#[warn(deprecated_mode)];
7575

7676
use cast;
77+
use container::Map;
78+
use oldcomm;
7779
use option;
78-
use pipes::{stream, Chan, Port};
80+
use pipes::{Chan, GenericChan, GenericPort, Port};
7981
use pipes;
8082
use prelude::*;
8183
use private;

src/librustc/metadata/encoder.rs

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ use core::to_bytes::IterBytes;
3737
use core::uint;
3838
use core::vec;
3939
use std::map::HashMap;
40+
use std::serialize::Encodable;
4041
use std::{ebml, map};
4142
use std;
4243
use syntax::ast::*;

src/librustc/metadata/tydecode.rs

+13-10
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
use core::prelude::*;
1818

1919
use middle::ty;
20-
use middle::ty::{FnTyBase, FnMeta, FnSig};
20+
use middle::ty::{FnTyBase, FnMeta, FnSig, arg, creader_cache_key, field};
21+
use middle::ty::{substs};
2122

2223
use core::io;
2324
use core::str;
@@ -174,9 +175,11 @@ fn parse_substs(st: @pstate, conv: conv_did) -> ty::substs {
174175
while peek(st) != ']' { params.push(parse_ty(st, conv)); }
175176
st.pos = st.pos + 1u;
176177

177-
return {self_r: self_r,
178-
self_ty: self_ty,
179-
tps: params};
178+
return substs {
179+
self_r: self_r,
180+
self_ty: self_ty,
181+
tps: params
182+
};
180183
}
181184

182185
fn parse_bound_region(st: @pstate) -> ty::bound_region {
@@ -308,7 +311,7 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
308311
let mut fields: ~[ty::field] = ~[];
309312
while peek(st) != ']' {
310313
let name = st.tcx.sess.ident_of(parse_str(st, '='));
311-
fields.push({ident: name, mt: parse_mt(st, conv)});
314+
fields.push(ty::field { ident: name, mt: parse_mt(st, conv) });
312315
}
313316
st.pos = st.pos + 1u;
314317
return ty::mk_rec(st.tcx, fields);
@@ -333,12 +336,13 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
333336
assert (next(st) == ':');
334337
let len = parse_hex(st);
335338
assert (next(st) == '#');
336-
match st.tcx.rcache.find({cnum: st.crate, pos: pos, len: len}) {
339+
let key = creader_cache_key { cnum: st.crate, pos: pos, len: len };
340+
match st.tcx.rcache.find(key) {
337341
Some(tt) => return tt,
338342
None => {
339343
let ps = @{pos: pos ,.. copy *st};
340344
let tt = parse_ty(ps, conv);
341-
st.tcx.rcache.insert({cnum: st.crate, pos: pos, len: len}, tt);
345+
st.tcx.rcache.insert(key, tt);
342346
return tt;
343347
}
344348
}
@@ -421,8 +425,7 @@ fn parse_onceness(c: char) -> ast::Onceness {
421425
}
422426

423427
fn parse_arg(st: @pstate, conv: conv_did) -> ty::arg {
424-
{mode: parse_mode(st),
425-
ty: parse_ty(st, conv)}
428+
ty::arg { mode: parse_mode(st), ty: parse_ty(st, conv) }
426429
}
427430

428431
fn parse_mode(st: @pstate) -> ast::mode {
@@ -446,7 +449,7 @@ fn parse_ty_fn(st: @pstate, conv: conv_did) -> ty::FnTy {
446449
let mut inputs: ~[ty::arg] = ~[];
447450
while peek(st) != ']' {
448451
let mode = parse_mode(st);
449-
inputs.push({mode: mode, ty: parse_ty(st, conv)});
452+
inputs.push(ty::arg { mode: mode, ty: parse_ty(st, conv) });
450453
}
451454
st.pos += 1u; // eat the ']'
452455
let ret_ty = parse_ty(st, conv);

src/librustc/metadata/tyencode.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313

1414
use core::prelude::*;
1515

16+
use middle::ty::{Vid, param_ty};
1617
use middle::ty;
17-
use middle::ty::Vid;
1818

1919
use core::io::WriterUtil;
2020
use core::io;
@@ -301,7 +301,7 @@ fn enc_sty(w: io::Writer, cx: @ctxt, +st: ty::sty) {
301301
ty::ty_infer(_) => {
302302
cx.diag.handler().bug(~"Cannot encode inference variable types");
303303
}
304-
ty::ty_param({idx: id, def_id: did}) => {
304+
ty::ty_param(param_ty {idx: id, def_id: did}) => {
305305
w.write_char('p');
306306
w.write_str((cx.ds)(did));
307307
w.write_char('|');

src/librustc/middle/borrowck/check_loans.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
use core::prelude::*;
2121

2222
use middle::borrowck::{Loan, bckerr, borrowck_ctxt, cmt, inherent_mutability};
23-
use middle::borrowck::{req_maps, save_and_restore};
23+
use middle::borrowck::{req_maps, root_map_key, save_and_restore};
2424
use middle::mem_categorization::{cat_arg, cat_binding, cat_comp, cat_deref};
2525
use middle::mem_categorization::{cat_local, cat_rvalue, cat_self};
2626
use middle::mem_categorization::{cat_special, gc_ptr, loan_path, lp_arg};
@@ -396,7 +396,10 @@ impl check_loan_ctxt {
396396

397397
match ptr_kind {
398398
gc_ptr(ast::m_mutbl) => {
399-
let key = { id: base.id, derefs: deref_count };
399+
let key = root_map_key {
400+
id: base.id,
401+
derefs: deref_count
402+
};
400403
self.bccx.write_guard_map.insert(key, ());
401404
}
402405
_ => {}

src/librustc/middle/borrowck/gather_loans.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
use core::prelude::*;
2020

2121
use middle::borrowck::preserve::{preserve_condition, pc_ok, pc_if_pure};
22-
use middle::borrowck::{Loan, bckres, borrowck_ctxt, err_mutbl, req_maps};
22+
use middle::borrowck::{Loan, bckerr, bckres, borrowck_ctxt, err_mutbl};
23+
use middle::borrowck::{req_maps};
2324
use middle::mem_categorization::{cat_binding, cat_discr, cmt, comp_variant};
2425
use middle::mem_categorization::{mem_categorization_ctxt};
2526
use middle::mem_categorization::{opt_deref_kind};
@@ -452,8 +453,7 @@ impl gather_loan_ctxt {
452453
debug!("required is const or they are the same");
453454
Ok(pc_ok)
454455
} else {
455-
let e = {cmt: cmt,
456-
code: err_mutbl(req_mutbl)};
456+
let e = bckerr { cmt: cmt, code: err_mutbl(req_mutbl) };
457457
if req_mutbl == m_imm {
458458
// if this is an @mut box, then it's generally OK to borrow as
459459
// &imm; this will result in a write guard

src/librustc/middle/borrowck/loan.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ XXX --- much more needed, don't have time to write this all up now
4343

4444
use core::prelude::*;
4545

46-
use middle::borrowck::{Loan, bckres, borrowck_ctxt, cmt, err_mutbl};
46+
use middle::borrowck::{Loan, bckerr, bckres, borrowck_ctxt, cmt, err_mutbl};
4747
use middle::borrowck::{err_out_of_scope};
4848
use middle::mem_categorization::{cat_arg, cat_binding, cat_discr, cat_comp};
4949
use middle::mem_categorization::{cat_deref, cat_discr, cat_local, cat_self};
@@ -309,8 +309,10 @@ impl LoanContext {
309309
// We do not allow non-mutable data to be loaned
310310
// out as mutable under any circumstances.
311311
if cmt.mutbl != m_mutbl {
312-
return Err({cmt:cmt,
313-
code:err_mutbl(req_mutbl)});
312+
return Err(bckerr {
313+
cmt:cmt,
314+
code:err_mutbl(req_mutbl)
315+
});
314316
}
315317
}
316318
m_const | m_imm => {
@@ -332,9 +334,10 @@ impl LoanContext {
332334
} else {
333335
// The loan being requested lives longer than the data
334336
// being loaned out!
335-
return Err({cmt:cmt,
336-
code:err_out_of_scope(scope_ub,
337-
self.scope_region)});
337+
return Err(bckerr {
338+
cmt:cmt,
339+
code:err_out_of_scope(scope_ub, self.scope_region)
340+
});
338341
}
339342
}
340343
}

src/librustc/middle/borrowck/mod.rs

+10-18
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,11 @@ type root_map = HashMap<root_map_key, RootInfo>;
344344
// if you have an expression `x.f` and x has type ~@T, we could add an
345345
// entry {id:x, derefs:0} to refer to `x` itself, `{id:x, derefs:1}`
346346
// to refer to the deref of the unique pointer, and so on.
347-
type root_map_key = {id: ast::node_id, derefs: uint};
347+
#[deriving_eq]
348+
struct root_map_key {
349+
id: ast::node_id,
350+
derefs: uint
351+
}
348352

349353
// set of ids of local vars / formal arguments that are modified / moved.
350354
// this is used in trans for optimization purposes.
@@ -411,13 +415,10 @@ impl bckerr_code : cmp::Eq {
411415

412416
// Combination of an error code and the categorization of the expression
413417
// that caused it
414-
type bckerr = {cmt: cmt, code: bckerr_code};
415-
416-
impl bckerr : cmp::Eq {
417-
pure fn eq(&self, other: &bckerr) -> bool {
418-
(*self).cmt == (*other).cmt && (*self).code == (*other).code
419-
}
420-
pure fn ne(&self, other: &bckerr) -> bool { !(*self).eq(other) }
418+
#[deriving_eq]
419+
struct bckerr {
420+
cmt: cmt,
421+
code: bckerr_code
421422
}
422423

423424
// shorthand for something that fails with `bckerr` or succeeds with `T`
@@ -446,15 +447,6 @@ fn save_and_restore<T:Copy,U>(save_and_restore_t: &mut T, f: fn() -> U) -> U {
446447

447448
/// Creates and returns a new root_map
448449
449-
impl root_map_key : cmp::Eq {
450-
pure fn eq(&self, other: &root_map_key) -> bool {
451-
(*self).id == (*other).id && (*self).derefs == (*other).derefs
452-
}
453-
pure fn ne(&self, other: &root_map_key) -> bool {
454-
! ((*self) == (*other))
455-
}
456-
}
457-
458450
impl root_map_key : to_bytes::IterBytes {
459451
pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
460452
to_bytes::iter_bytes_2(&self.id, &self.derefs, lsb0, f);
@@ -501,7 +493,7 @@ impl borrowck_ctxt {
501493
}
502494

503495
fn cat_discr(cmt: cmt, match_id: ast::node_id) -> cmt {
504-
return @{cat:cat_discr(cmt, match_id),.. *cmt};
496+
return @cmt_ { cat: cat_discr(cmt, match_id),.. *cmt };
505497
}
506498

507499
fn mc_ctxt() -> mem_categorization_ctxt {

src/librustc/middle/borrowck/preserve.rs

+17-12
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use core::prelude::*;
1818
use middle::borrowck::{RootInfo, bckerr, bckerr_code, bckres, borrowck_ctxt};
1919
use middle::borrowck::{cmt, err_mut_uniq, err_mut_variant};
2020
use middle::borrowck::{err_out_of_root_scope, err_out_of_scope};
21-
use middle::borrowck::{err_root_not_permitted};
21+
use middle::borrowck::{err_root_not_permitted, root_map_key};
2222
use middle::mem_categorization::{cat_arg, cat_binding, cat_comp, cat_deref};
2323
use middle::mem_categorization::{cat_discr, cat_local, cat_self, cat_special};
2424
use middle::mem_categorization::{cat_stack_upvar, comp_field, comp_index};
@@ -291,7 +291,7 @@ priv impl &preserve_ctxt {
291291
Ok(pc_ok) => {
292292
match cmt_base.mutbl {
293293
m_mutbl | m_const => {
294-
Ok(pc_if_pure({cmt:cmt, code:code}))
294+
Ok(pc_if_pure(bckerr { cmt: cmt, code: code }))
295295
}
296296
m_imm => {
297297
Ok(pc_ok)
@@ -318,8 +318,10 @@ priv impl &preserve_ctxt {
318318
if self.bccx.is_subregion_of(self.scope_region, scope_ub) {
319319
Ok(pc_ok)
320320
} else {
321-
Err({cmt:cmt, code:err_out_of_scope(scope_ub,
322-
self.scope_region)})
321+
Err(bckerr {
322+
cmt:cmt,
323+
code:err_out_of_scope(scope_ub, self.scope_region)
324+
})
323325
}
324326
}
325327

@@ -345,7 +347,7 @@ priv impl &preserve_ctxt {
345347
// would be sort of pointless to avoid rooting the inner
346348
// box by rooting an outer box, as it would just keep more
347349
// memory live than necessary, so we set root_ub to none.
348-
return Err({cmt:cmt, code:err_root_not_permitted});
350+
return Err(bckerr { cmt: cmt, code: err_root_not_permitted });
349351
}
350352

351353
let root_region = ty::re_scope(self.root_ub);
@@ -359,7 +361,7 @@ priv impl &preserve_ctxt {
359361
derefs, scope_id, self.root_ub);
360362
if self.bccx.is_subregion_of(self.scope_region, root_region) {
361363
debug!("Elected to root");
362-
let rk = {id: base.id, derefs: derefs};
364+
let rk = root_map_key { id: base.id, derefs: derefs };
363365
// This code could potentially lead cause boxes to be frozen
364366
// for longer than necessarily at runtime. It prevents an
365367
// ICE in trans; the fundamental problem is that it's hard
@@ -389,17 +391,20 @@ priv impl &preserve_ctxt {
389391
return Ok(pc_ok);
390392
} else {
391393
debug!("Unable to root");
392-
return Err({cmt:cmt,
393-
code:err_out_of_root_scope(root_region,
394-
self.scope_region)});
394+
return Err(bckerr {
395+
cmt: cmt,
396+
code: err_out_of_root_scope(root_region,
397+
self.scope_region)
398+
});
395399
}
396400
}
397401

398402
// we won't be able to root long enough
399403
_ => {
400-
return Err({cmt:cmt,
401-
code:err_out_of_root_scope(root_region,
402-
self.scope_region)});
404+
return Err(bckerr {
405+
cmt:cmt,
406+
code:err_out_of_root_scope(root_region, self.scope_region)
407+
});
403408
}
404409

405410
}

0 commit comments

Comments
 (0)