From 62d27b082cbc94b3617f662ee6d4f897a75a8afa Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 25 Jan 2013 16:57:39 -0800 Subject: [PATCH 1/4] libstd: Remove "dual impls" from the language and enforce coherence rules. "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. --- src/libcore/gc.rs | 1 + src/libcore/hashmap.rs | 2 +- src/libcore/num.rs | 5 + src/libcore/pipes.rs | 3 +- src/libcore/prelude.rs | 2 + src/libcore/private/weak_task.rs | 2 +- src/libcore/task/mod.rs | 2 +- src/libcore/task/spawn.rs | 4 +- src/librustc/metadata/encoder.rs | 1 + src/librustc/metadata/tydecode.rs | 23 +- src/librustc/metadata/tyencode.rs | 4 +- src/librustc/middle/borrowck/check_loans.rs | 7 +- src/librustc/middle/borrowck/gather_loans.rs | 6 +- src/librustc/middle/borrowck/loan.rs | 15 +- src/librustc/middle/borrowck/mod.rs | 28 +- src/librustc/middle/borrowck/preserve.rs | 29 +- src/librustc/middle/mem_categorization.rs | 220 +++++++++----- src/librustc/middle/region.rs | 19 +- src/librustc/middle/trans/_match.rs | 3 +- src/librustc/middle/trans/base.rs | 10 +- src/librustc/middle/trans/common.rs | 9 +- src/librustc/middle/trans/datum.rs | 4 +- src/librustc/middle/trans/expr.rs | 3 +- src/librustc/middle/trans/foreign.rs | 6 +- src/librustc/middle/trans/machine.rs | 13 +- src/librustc/middle/trans/meth.rs | 7 +- src/librustc/middle/ty.rs | 131 ++++---- src/librustc/middle/typeck/astconv.rs | 9 +- src/librustc/middle/typeck/check/method.rs | 48 ++- src/librustc/middle/typeck/check/mod.rs | 42 +-- src/librustc/middle/typeck/check/vtable.rs | 8 +- src/librustc/middle/typeck/check/writeback.rs | 3 +- src/librustc/middle/typeck/coherence.rs | 129 ++++---- src/librustc/middle/typeck/collect.rs | 33 +- src/librustc/middle/typeck/infer/combine.rs | 14 +- src/librustc/middle/typeck/infer/mod.rs | 2 +- src/librustc/util/ppaux.rs | 9 +- src/librustdoc/astsrv.rs | 6 +- src/librustdoc/attr_pass.rs | 18 +- src/librustdoc/config.rs | 14 +- src/librustdoc/desc_to_brief_pass.rs | 10 +- src/librustdoc/doc.rs | 283 +++--------------- src/librustdoc/extract.rs | 33 +- src/librustdoc/fold.rs | 30 +- src/librustdoc/markdown_index_pass.rs | 10 +- src/librustdoc/page_pass.rs | 6 +- src/librustdoc/path_pass.rs | 6 +- src/librustdoc/prune_hidden_pass.rs | 2 +- src/librustdoc/prune_private_pass.rs | 2 +- src/librustdoc/sectionalize_pass.rs | 14 +- src/librustdoc/sort_pass.rs | 2 +- src/librustdoc/text_pass.rs | 14 +- src/librustdoc/tystr_pass.rs | 18 +- src/libstd/bigint.rs | 49 ++- src/libstd/deque.rs | 58 +--- src/libstd/ebml.rs | 1 + src/libstd/json.rs | 1 + src/libstd/map.rs | 6 +- src/libstd/smallintmap.rs | 8 +- src/libsyntax/ast_map.rs | 2 +- src/libsyntax/ast_util.rs | 2 +- src/libsyntax/codemap.rs | 2 +- src/libsyntax/diagnostic.rs | 2 +- src/libsyntax/ext/pipes/ast_builder.rs | 2 +- src/libsyntax/ext/pipes/mod.rs | 1 + src/libsyntax/ext/pipes/pipec.rs | 5 +- src/libsyntax/ext/pipes/proto.rs | 2 +- src/libsyntax/ext/quote.rs | 2 +- src/libsyntax/ext/source_util.rs | 2 +- src/libsyntax/parse/comments.rs | 2 +- src/libsyntax/parse/lexer.rs | 2 +- src/test/auxiliary/issue_2242_b.rs | 19 -- src/test/compile-fail/drop-on-non-struct.rs | 1 + src/test/compile-fail/map-types.rs | 9 +- src/test/run-pass/auto-encode.rs | 11 +- .../class-impl-very-parameterized-trait.rs | 2 +- src/test/run-pass/issue-2242-d.rs | 26 -- 77 files changed, 704 insertions(+), 837 deletions(-) delete mode 100644 src/test/auxiliary/issue_2242_b.rs delete mode 100644 src/test/run-pass/issue-2242-d.rs diff --git a/src/libcore/gc.rs b/src/libcore/gc.rs index 698e264b57a65..181a9d0888d43 100644 --- a/src/libcore/gc.rs +++ b/src/libcore/gc.rs @@ -40,6 +40,7 @@ with destructors. #[forbid(deprecated_pattern)]; use cast; +use container::{Container, Mutable, Map, Set}; use io; use libc::{size_t, uintptr_t}; use option::{None, Option, Some}; diff --git a/src/libcore/hashmap.rs b/src/libcore/hashmap.rs index ab1c9832d460e..c3af7a99692e5 100644 --- a/src/libcore/hashmap.rs +++ b/src/libcore/hashmap.rs @@ -16,7 +16,6 @@ use cmp::Eq; use hash::Hash; -use prelude::*; use to_bytes::IterBytes; /// Open addressing with linear probing. @@ -479,6 +478,7 @@ pub mod linear { #[test] pub mod test { + use container::{Container, Mutable, Map, Set}; use option::{None, Some}; use hashmap::linear::LinearMap; use hashmap::linear; diff --git a/src/libcore/num.rs b/src/libcore/num.rs index 4c2daa458a48d..6eb22e53a2413 100644 --- a/src/libcore/num.rs +++ b/src/libcore/num.rs @@ -23,6 +23,11 @@ pub trait Num { static pure fn from_int(n: int) -> self; } +pub trait IntConvertible { + pure fn to_int(&self) -> int; + static pure fn from_int(n: int) -> self; +} + pub trait Zero { static pure fn zero() -> self; } diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index cecc954cdf3bc..9142c11360a0d 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -93,10 +93,9 @@ use either::{Either, Left, Right}; use kinds::Owned; use libc; use option; -use option::unwrap; +use option::{None, Option, Some, unwrap}; use pipes; use ptr; -use prelude::*; use private; use task; use vec; diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index 72aa828ff12a7..d3813d1ae852e 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -35,6 +35,8 @@ pub use vec::{ImmutableEqVector, ImmutableCopyableVector}; pub use vec::{OwnedVector, OwnedCopyableVector}; pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter}; pub use iter::{CopyableOrderedIter, CopyableNonstrictIter, Times}; +pub use container::{Container, Mutable, Map, Set}; +pub use pipes::{GenericChan, GenericPort}; pub use num::Num; pub use ptr::Ptr; diff --git a/src/libcore/private/weak_task.rs b/src/libcore/private/weak_task.rs index 25a03ff960f46..573a3e54b444b 100644 --- a/src/libcore/private/weak_task.rs +++ b/src/libcore/private/weak_task.rs @@ -22,7 +22,7 @@ use option::{Some, None, swap_unwrap}; use private::at_exit::at_exit; use private::global::global_data_clone_create; use private::finally::Finally; -use pipes::{Port, Chan, SharedChan, stream}; +use pipes::{Port, Chan, SharedChan, GenericSmartChan, stream}; use task::{Task, task, spawn}; use task::rt::{task_id, get_task_id}; use hashmap::linear::LinearMap; diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs index aa82309c78aec..9ddafee693898 100644 --- a/src/libcore/task/mod.rs +++ b/src/libcore/task/mod.rs @@ -45,7 +45,7 @@ use iter; use libc; use option; use result::Result; -use pipes::{stream, Chan, Port, SharedChan}; +use pipes::{stream, Chan, GenericChan, GenericPort, Port, SharedChan}; use pipes; use prelude::*; use ptr; diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs index a5ab4af40bef7..0a2f6634214e6 100644 --- a/src/libcore/task/spawn.rs +++ b/src/libcore/task/spawn.rs @@ -74,8 +74,10 @@ #[warn(deprecated_mode)]; use cast; +use container::Map; +use oldcomm; use option; -use pipes::{stream, Chan, Port}; +use pipes::{Chan, GenericChan, GenericPort, Port}; use pipes; use prelude::*; use private; diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 79ce755137efc..399184ea8a586 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -37,6 +37,7 @@ use core::to_bytes::IterBytes; use core::uint; use core::vec; use std::map::HashMap; +use std::serialize::Encodable; use std::{ebml, map}; use std; use syntax::ast::*; diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 590dd9f7ea7e0..787a1d3c906c2 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -17,7 +17,8 @@ use core::prelude::*; use middle::ty; -use middle::ty::{FnTyBase, FnMeta, FnSig}; +use middle::ty::{FnTyBase, FnMeta, FnSig, arg, creader_cache_key, field}; +use middle::ty::{substs}; use core::io; use core::str; @@ -174,9 +175,11 @@ fn parse_substs(st: @pstate, conv: conv_did) -> ty::substs { while peek(st) != ']' { params.push(parse_ty(st, conv)); } st.pos = st.pos + 1u; - return {self_r: self_r, - self_ty: self_ty, - tps: params}; + return substs { + self_r: self_r, + self_ty: self_ty, + tps: params + }; } fn parse_bound_region(st: @pstate) -> ty::bound_region { @@ -308,7 +311,7 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t { let mut fields: ~[ty::field] = ~[]; while peek(st) != ']' { let name = st.tcx.sess.ident_of(parse_str(st, '=')); - fields.push({ident: name, mt: parse_mt(st, conv)}); + fields.push(ty::field { ident: name, mt: parse_mt(st, conv) }); } st.pos = st.pos + 1u; return ty::mk_rec(st.tcx, fields); @@ -333,12 +336,13 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t { assert (next(st) == ':'); let len = parse_hex(st); assert (next(st) == '#'); - match st.tcx.rcache.find({cnum: st.crate, pos: pos, len: len}) { + let key = creader_cache_key { cnum: st.crate, pos: pos, len: len }; + match st.tcx.rcache.find(key) { Some(tt) => return tt, None => { let ps = @{pos: pos ,.. copy *st}; let tt = parse_ty(ps, conv); - st.tcx.rcache.insert({cnum: st.crate, pos: pos, len: len}, tt); + st.tcx.rcache.insert(key, tt); return tt; } } @@ -421,8 +425,7 @@ fn parse_onceness(c: char) -> ast::Onceness { } fn parse_arg(st: @pstate, conv: conv_did) -> ty::arg { - {mode: parse_mode(st), - ty: parse_ty(st, conv)} + ty::arg { mode: parse_mode(st), ty: parse_ty(st, conv) } } fn parse_mode(st: @pstate) -> ast::mode { @@ -446,7 +449,7 @@ fn parse_ty_fn(st: @pstate, conv: conv_did) -> ty::FnTy { let mut inputs: ~[ty::arg] = ~[]; while peek(st) != ']' { let mode = parse_mode(st); - inputs.push({mode: mode, ty: parse_ty(st, conv)}); + inputs.push(ty::arg { mode: mode, ty: parse_ty(st, conv) }); } st.pos += 1u; // eat the ']' let ret_ty = parse_ty(st, conv); diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index d318f00ad6752..04e833d812bd7 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -13,8 +13,8 @@ use core::prelude::*; +use middle::ty::{Vid, param_ty}; use middle::ty; -use middle::ty::Vid; use core::io::WriterUtil; use core::io; @@ -301,7 +301,7 @@ fn enc_sty(w: io::Writer, cx: @ctxt, +st: ty::sty) { ty::ty_infer(_) => { cx.diag.handler().bug(~"Cannot encode inference variable types"); } - ty::ty_param({idx: id, def_id: did}) => { + ty::ty_param(param_ty {idx: id, def_id: did}) => { w.write_char('p'); w.write_str((cx.ds)(did)); w.write_char('|'); diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index ff5854322f456..bdb889b68f116 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -20,7 +20,7 @@ use core::prelude::*; use middle::borrowck::{Loan, bckerr, borrowck_ctxt, cmt, inherent_mutability}; -use middle::borrowck::{req_maps, save_and_restore}; +use middle::borrowck::{req_maps, root_map_key, save_and_restore}; use middle::mem_categorization::{cat_arg, cat_binding, cat_comp, cat_deref}; use middle::mem_categorization::{cat_local, cat_rvalue, cat_self}; use middle::mem_categorization::{cat_special, gc_ptr, loan_path, lp_arg}; @@ -396,7 +396,10 @@ impl check_loan_ctxt { match ptr_kind { gc_ptr(ast::m_mutbl) => { - let key = { id: base.id, derefs: deref_count }; + let key = root_map_key { + id: base.id, + derefs: deref_count + }; self.bccx.write_guard_map.insert(key, ()); } _ => {} diff --git a/src/librustc/middle/borrowck/gather_loans.rs b/src/librustc/middle/borrowck/gather_loans.rs index 0fff0c66a3846..6f913f99e11fd 100644 --- a/src/librustc/middle/borrowck/gather_loans.rs +++ b/src/librustc/middle/borrowck/gather_loans.rs @@ -19,7 +19,8 @@ use core::prelude::*; use middle::borrowck::preserve::{preserve_condition, pc_ok, pc_if_pure}; -use middle::borrowck::{Loan, bckres, borrowck_ctxt, err_mutbl, req_maps}; +use middle::borrowck::{Loan, bckerr, bckres, borrowck_ctxt, err_mutbl}; +use middle::borrowck::{req_maps}; use middle::mem_categorization::{cat_binding, cat_discr, cmt, comp_variant}; use middle::mem_categorization::{mem_categorization_ctxt}; use middle::mem_categorization::{opt_deref_kind}; @@ -452,8 +453,7 @@ impl gather_loan_ctxt { debug!("required is const or they are the same"); Ok(pc_ok) } else { - let e = {cmt: cmt, - code: err_mutbl(req_mutbl)}; + let e = bckerr { cmt: cmt, code: err_mutbl(req_mutbl) }; if req_mutbl == m_imm { // if this is an @mut box, then it's generally OK to borrow as // &imm; this will result in a write guard diff --git a/src/librustc/middle/borrowck/loan.rs b/src/librustc/middle/borrowck/loan.rs index d3dc75aad7f91..48cc0502f6c87 100644 --- a/src/librustc/middle/borrowck/loan.rs +++ b/src/librustc/middle/borrowck/loan.rs @@ -43,7 +43,7 @@ XXX --- much more needed, don't have time to write this all up now use core::prelude::*; -use middle::borrowck::{Loan, bckres, borrowck_ctxt, cmt, err_mutbl}; +use middle::borrowck::{Loan, bckerr, bckres, borrowck_ctxt, cmt, err_mutbl}; use middle::borrowck::{err_out_of_scope}; use middle::mem_categorization::{cat_arg, cat_binding, cat_discr, cat_comp}; use middle::mem_categorization::{cat_deref, cat_discr, cat_local, cat_self}; @@ -309,8 +309,10 @@ impl LoanContext { // We do not allow non-mutable data to be loaned // out as mutable under any circumstances. if cmt.mutbl != m_mutbl { - return Err({cmt:cmt, - code:err_mutbl(req_mutbl)}); + return Err(bckerr { + cmt:cmt, + code:err_mutbl(req_mutbl) + }); } } m_const | m_imm => { @@ -332,9 +334,10 @@ impl LoanContext { } else { // The loan being requested lives longer than the data // being loaned out! - return Err({cmt:cmt, - code:err_out_of_scope(scope_ub, - self.scope_region)}); + return Err(bckerr { + cmt:cmt, + code:err_out_of_scope(scope_ub, self.scope_region) + }); } } } diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index a01c04a8abf15..2afdcc9d47d53 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -344,7 +344,11 @@ type root_map = HashMap; // if you have an expression `x.f` and x has type ~@T, we could add an // entry {id:x, derefs:0} to refer to `x` itself, `{id:x, derefs:1}` // to refer to the deref of the unique pointer, and so on. -type root_map_key = {id: ast::node_id, derefs: uint}; +#[deriving_eq] +struct root_map_key { + id: ast::node_id, + derefs: uint +} // set of ids of local vars / formal arguments that are modified / moved. // this is used in trans for optimization purposes. @@ -411,13 +415,10 @@ impl bckerr_code : cmp::Eq { // Combination of an error code and the categorization of the expression // that caused it -type bckerr = {cmt: cmt, code: bckerr_code}; - -impl bckerr : cmp::Eq { - pure fn eq(&self, other: &bckerr) -> bool { - (*self).cmt == (*other).cmt && (*self).code == (*other).code - } - pure fn ne(&self, other: &bckerr) -> bool { !(*self).eq(other) } +#[deriving_eq] +struct bckerr { + cmt: cmt, + code: bckerr_code } // shorthand for something that fails with `bckerr` or succeeds with `T` @@ -446,15 +447,6 @@ fn save_and_restore(save_and_restore_t: &mut T, f: fn() -> U) -> U { /// Creates and returns a new root_map -impl root_map_key : cmp::Eq { - pure fn eq(&self, other: &root_map_key) -> bool { - (*self).id == (*other).id && (*self).derefs == (*other).derefs - } - pure fn ne(&self, other: &root_map_key) -> bool { - ! ((*self) == (*other)) - } -} - impl root_map_key : to_bytes::IterBytes { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.id, &self.derefs, lsb0, f); @@ -501,7 +493,7 @@ impl borrowck_ctxt { } fn cat_discr(cmt: cmt, match_id: ast::node_id) -> cmt { - return @{cat:cat_discr(cmt, match_id),.. *cmt}; + return @cmt_ { cat: cat_discr(cmt, match_id),.. *cmt }; } fn mc_ctxt() -> mem_categorization_ctxt { diff --git a/src/librustc/middle/borrowck/preserve.rs b/src/librustc/middle/borrowck/preserve.rs index 5916588a9a2bb..5edfd294d8477 100644 --- a/src/librustc/middle/borrowck/preserve.rs +++ b/src/librustc/middle/borrowck/preserve.rs @@ -18,7 +18,7 @@ use core::prelude::*; use middle::borrowck::{RootInfo, bckerr, bckerr_code, bckres, borrowck_ctxt}; use middle::borrowck::{cmt, err_mut_uniq, err_mut_variant}; use middle::borrowck::{err_out_of_root_scope, err_out_of_scope}; -use middle::borrowck::{err_root_not_permitted}; +use middle::borrowck::{err_root_not_permitted, root_map_key}; use middle::mem_categorization::{cat_arg, cat_binding, cat_comp, cat_deref}; use middle::mem_categorization::{cat_discr, cat_local, cat_self, cat_special}; use middle::mem_categorization::{cat_stack_upvar, comp_field, comp_index}; @@ -291,7 +291,7 @@ priv impl &preserve_ctxt { Ok(pc_ok) => { match cmt_base.mutbl { m_mutbl | m_const => { - Ok(pc_if_pure({cmt:cmt, code:code})) + Ok(pc_if_pure(bckerr { cmt: cmt, code: code })) } m_imm => { Ok(pc_ok) @@ -318,8 +318,10 @@ priv impl &preserve_ctxt { if self.bccx.is_subregion_of(self.scope_region, scope_ub) { Ok(pc_ok) } else { - Err({cmt:cmt, code:err_out_of_scope(scope_ub, - self.scope_region)}) + Err(bckerr { + cmt:cmt, + code:err_out_of_scope(scope_ub, self.scope_region) + }) } } @@ -345,7 +347,7 @@ priv impl &preserve_ctxt { // would be sort of pointless to avoid rooting the inner // box by rooting an outer box, as it would just keep more // memory live than necessary, so we set root_ub to none. - return Err({cmt:cmt, code:err_root_not_permitted}); + return Err(bckerr { cmt: cmt, code: err_root_not_permitted }); } let root_region = ty::re_scope(self.root_ub); @@ -359,7 +361,7 @@ priv impl &preserve_ctxt { derefs, scope_id, self.root_ub); if self.bccx.is_subregion_of(self.scope_region, root_region) { debug!("Elected to root"); - let rk = {id: base.id, derefs: derefs}; + let rk = root_map_key { id: base.id, derefs: derefs }; // This code could potentially lead cause boxes to be frozen // for longer than necessarily at runtime. It prevents an // ICE in trans; the fundamental problem is that it's hard @@ -389,17 +391,20 @@ priv impl &preserve_ctxt { return Ok(pc_ok); } else { debug!("Unable to root"); - return Err({cmt:cmt, - code:err_out_of_root_scope(root_region, - self.scope_region)}); + return Err(bckerr { + cmt: cmt, + code: err_out_of_root_scope(root_region, + self.scope_region) + }); } } // we won't be able to root long enough _ => { - return Err({cmt:cmt, - code:err_out_of_root_scope(root_region, - self.scope_region)}); + return Err(bckerr { + cmt:cmt, + code:err_out_of_root_scope(root_region, self.scope_region) + }); } } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 7c1e96e5c0e44..9ea03440ad6b4 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -113,27 +113,18 @@ enum special_kind { // which the value is stored. // // note: cmt stands for "categorized mutable type". -type cmt_ = {id: ast::node_id, // id of expr/pat producing this value - span: span, // span of same expr/pat - cat: categorization, // categorization of expr - lp: Option<@loan_path>, // loan path for expr, if any - mutbl: ast::mutability, // mutability of expr as lvalue - ty: ty::t}; // type of the expr +#[deriving_eq] +struct cmt_ { + id: ast::node_id, // id of expr/pat producing this value + span: span, // span of same expr/pat + cat: categorization, // categorization of expr + lp: Option<@loan_path>, // loan path for expr, if any + mutbl: ast::mutability, // mutability of expr as lvalue + ty: ty::t // type of the expr +} type cmt = @cmt_; -impl cmt_ : cmp::Eq { - pure fn eq(&self, other: &cmt_) -> bool { - (*self).id == (*other).id && - (*self).span == (*other).span && - (*self).cat == (*other).cat && - (*self).lp == (*other).lp && - (*self).mutbl == (*other).mutbl && - (*self).ty == (*other).ty - } - pure fn ne(&self, other: &cmt_) -> bool { !(*self).eq(other) } -} - // a loan path is like a category, but it exists only when the data is // interior to the stack frame. loan paths are used as the key to a // map indicating what is borrowed at any point in time. @@ -423,9 +414,14 @@ impl &mem_categorization_ctxt { ast::def_ty_param(*) | ast::def_struct(*) | ast::def_typaram_binder(*) | ast::def_region(_) | ast::def_label(_) | ast::def_self_ty(*) => { - @{id:id, span:span, - cat:cat_special(sk_static_item), lp:None, - mutbl:m_imm, ty:expr_ty} + @cmt_ { + id:id, + span:span, + cat:cat_special(sk_static_item), + lp:None, + mutbl:m_imm, + ty:expr_ty + } } ast::def_arg(vid, mode, mutbl) => { @@ -451,9 +447,14 @@ impl &mem_categorization_ctxt { None } }; - @{id:id, span:span, - cat:cat_arg(vid), lp:lp, - mutbl:m, ty:expr_ty} + @cmt_ { + id:id, + span:span, + cat:cat_arg(vid), + lp:lp, + mutbl:m, + ty:expr_ty + } } ast::def_self(self_id, is_implicit) => { @@ -466,9 +467,14 @@ impl &mem_categorization_ctxt { loan_path = Some(@lp_self); }; - @{id:id, span:span, - cat:cat, lp:loan_path, - mutbl:m_imm, ty:expr_ty} + @cmt_ { + id:id, + span:span, + cat:cat, + lp:loan_path, + mutbl:m_imm, + ty:expr_ty + } } ast::def_upvar(_, inner, fn_node_id, _) => { @@ -477,15 +483,25 @@ impl &mem_categorization_ctxt { match proto { ast::ProtoBorrowed => { let upcmt = self.cat_def(id, span, expr_ty, *inner); - @{id:id, span:span, - cat:cat_stack_upvar(upcmt), lp:upcmt.lp, - mutbl:upcmt.mutbl, ty:upcmt.ty} + @cmt_ { + id:id, + span:span, + cat:cat_stack_upvar(upcmt), + lp:upcmt.lp, + mutbl:upcmt.mutbl, + ty:upcmt.ty + } } ast::ProtoUniq | ast::ProtoBox => { // FIXME #2152 allow mutation of moved upvars - @{id:id, span:span, - cat:cat_special(sk_heap_upvar), lp:None, - mutbl:m_imm, ty:expr_ty} + @cmt_ { + id:id, + span:span, + cat:cat_special(sk_heap_upvar), + lp:None, + mutbl:m_imm, + ty:expr_ty + } } ast::ProtoBare => { self.tcx.sess.span_bug( @@ -497,16 +513,26 @@ impl &mem_categorization_ctxt { ast::def_local(vid, mutbl) => { let m = if mutbl {m_mutbl} else {m_imm}; - @{id:id, span:span, - cat:cat_local(vid), lp:Some(@lp_local(vid)), - mutbl:m, ty:expr_ty} + @cmt_ { + id:id, + span:span, + cat:cat_local(vid), + lp:Some(@lp_local(vid)), + mutbl:m, + ty:expr_ty + } } ast::def_binding(vid, _) => { // by-value/by-ref bindings are local variables - @{id:id, span:span, - cat:cat_local(vid), lp:Some(@lp_local(vid)), - mutbl:m_imm, ty:expr_ty} + @cmt_ { + id:id, + span:span, + cat:cat_local(vid), + lp:Some(@lp_local(vid)), + mutbl:m_imm, + ty:expr_ty + } } } } @@ -514,17 +540,25 @@ impl &mem_categorization_ctxt { fn cat_variant(arg: N, enum_did: ast::def_id, cmt: cmt) -> cmt { - @{id: arg.id(), span: arg.span(), - cat: cat_comp(cmt, comp_variant(enum_did)), - lp: cmt.lp.map(|l| @lp_comp(*l, comp_variant(enum_did)) ), - mutbl: cmt.mutbl, // imm iff in an immutable context - ty: self.tcx.ty(arg)} + @cmt_ { + id: arg.id(), + span: arg.span(), + cat: cat_comp(cmt, comp_variant(enum_did)), + lp: cmt.lp.map(|l| @lp_comp(*l, comp_variant(enum_did)) ), + mutbl: cmt.mutbl, // imm iff in an immutable context + ty: self.tcx.ty(arg) + } } fn cat_rvalue(elt: N, expr_ty: ty::t) -> cmt { - @{id:elt.id(), span:elt.span(), - cat:cat_rvalue, lp:None, - mutbl:m_imm, ty:expr_ty} + @cmt_ { + id:elt.id(), + span:elt.span(), + cat:cat_rvalue, + lp:None, + mutbl:m_imm, + ty:expr_ty + } } /// inherited mutability: used in cases where the mutability of a @@ -559,9 +593,14 @@ impl &mem_categorization_ctxt { let m = self.inherited_mutability(base_cmt.mutbl, f_mutbl); let f_comp = comp_field(f_name, f_mutbl); let lp = base_cmt.lp.map(|lp| @lp_comp(*lp, f_comp) ); - @{id: node.id(), span: node.span(), - cat: cat_comp(base_cmt, f_comp), lp:lp, - mutbl: m, ty: self.tcx.ty(node)} + @cmt_ { + id: node.id(), + span: node.span(), + cat: cat_comp(base_cmt, f_comp), + lp:lp, + mutbl: m, + ty: self.tcx.ty(node) + } } fn cat_deref_fn(node: N, @@ -628,17 +667,27 @@ impl &mem_categorization_ctxt { } }; - @{id:node.id(), span:node.span(), - cat:cat_deref(base_cmt, deref_cnt, ptr), lp:lp, - mutbl:m, ty:mt.ty} + @cmt_ { + id:node.id(), + span:node.span(), + cat:cat_deref(base_cmt, deref_cnt, ptr), + lp:lp, + mutbl:m, + ty:mt.ty + } } deref_comp(comp) => { let lp = base_cmt.lp.map(|l| @lp_comp(*l, comp) ); let m = self.inherited_mutability(base_cmt.mutbl, mt.mutbl); - @{id:node.id(), span:node.span(), - cat:cat_comp(base_cmt, comp), lp:lp, - mutbl:m, ty:mt.ty} + @cmt_ { + id:node.id(), + span:node.span(), + cat:cat_comp(base_cmt, comp), + lp:lp, + mutbl:m, + ty:mt.ty + } } } } @@ -675,9 +724,14 @@ impl &mem_categorization_ctxt { }; // (c) the deref is explicit in the resulting cmt - let deref_cmt = @{id:elt.id(), span:elt.span(), - cat:cat_deref(base_cmt, 0u, ptr), lp:deref_lp, - mutbl:m, ty:mt.ty}; + let deref_cmt = @cmt_ { + id:elt.id(), + span:elt.span(), + cat:cat_deref(base_cmt, 0u, ptr), + lp:deref_lp, + mutbl:m, + ty:mt.ty + }; comp(elt, deref_cmt, base_cmt.ty, m, mt.ty) } @@ -695,32 +749,48 @@ impl &mem_categorization_ctxt { { let comp = comp_index(vect, mutbl); let index_lp = of_cmt.lp.map(|lp| @lp_comp(*lp, comp) ); - @{id:elt.id(), span:elt.span(), - cat:cat_comp(of_cmt, comp), lp:index_lp, - mutbl:mutbl, ty:ty} + @cmt_ { + id:elt.id(), + span:elt.span(), + cat:cat_comp(of_cmt, comp), + lp:index_lp, + mutbl:mutbl, + ty:ty + } } } fn cat_tuple_elt(elt: N, cmt: cmt) -> cmt { - @{id: elt.id(), span: elt.span(), - cat: cat_comp(cmt, comp_tuple), - lp: cmt.lp.map(|l| @lp_comp(*l, comp_tuple) ), - mutbl: cmt.mutbl, // imm iff in an immutable context - ty: self.tcx.ty(elt)} + @cmt_ { + id: elt.id(), + span: elt.span(), + cat: cat_comp(cmt, comp_tuple), + lp: cmt.lp.map(|l| @lp_comp(*l, comp_tuple) ), + mutbl: cmt.mutbl, // imm iff in an immutable context + ty: self.tcx.ty(elt) + } } fn cat_anon_struct_field(elt: N, cmt: cmt) -> cmt { - @{id: elt.id(), span: elt.span(), - cat: cat_comp(cmt, comp_anon_field), - lp: cmt.lp.map(|l| @lp_comp(*l, comp_anon_field)), - mutbl: cmt.mutbl, // imm iff in an immutable context - ty: self.tcx.ty(elt)} + @cmt_ { + id: elt.id(), + span: elt.span(), + cat: cat_comp(cmt, comp_anon_field), + lp: cmt.lp.map(|l| @lp_comp(*l, comp_anon_field)), + mutbl: cmt.mutbl, // imm iff in an immutable context + ty: self.tcx.ty(elt) + } } fn cat_method_ref(expr: @ast::expr, expr_ty: ty::t) -> cmt { - @{id:expr.id, span:expr.span, - cat:cat_special(sk_method), lp:None, - mutbl:m_imm, ty:expr_ty} + @cmt_ { + id:expr.id, + span:expr.span, + cat:cat_special(sk_method), + lp:None, + mutbl:m_imm, + ty:expr_ty + } } fn cat_pattern(cmt: cmt, pat: @ast::pat, op: fn(cmt, @ast::pat)) { diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index dd355f6df702c..ac3a16b07a0b1 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -397,17 +397,15 @@ fn resolve_crate(sess: Session, def_map: resolve::DefMap, // dependencies until a fixed point is reached. type region_paramd_items = HashMap; -type region_dep = {ambient_variance: region_variance, id: ast::node_id}; -type dep_map = HashMap>; -impl region_dep : cmp::Eq { - pure fn eq(&self, other: ®ion_dep) -> bool { - (*self).ambient_variance == (*other).ambient_variance && - (*self).id == (*other).id - } - pure fn ne(&self, other: ®ion_dep) -> bool { !(*self).eq(other) } +#[deriving_eq] +struct region_dep { + ambient_variance: region_variance, + id: ast::node_id } +type dep_map = HashMap>; + type determine_rp_ctxt_ = { sess: Session, ast_map: ast_map::map, @@ -511,7 +509,10 @@ impl determine_rp_ctxt { vec } }; - let dep = {ambient_variance: self.ambient_variance, id: self.item_id}; + let dep = region_dep { + ambient_variance: self.ambient_variance, + id: self.item_id + }; if !vec.contains(&dep) { vec.push(dep); } } diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index db266464860c3..084f0ba421e08 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -910,7 +910,8 @@ fn root_pats_as_necessary(bcx: block, for vec::each(m) |br| { let pat_id = br.pats[col].id; - match bcx.ccx().maps.root_map.find({id:pat_id, derefs:0u}) { + let key = root_map_key {id: pat_id, derefs: 0u }; + match bcx.ccx().maps.root_map.find(key) { None => (), Some(root_info) => { // Note: the scope_id will always be the id of the match. See diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 3bf1547a7d942..f4814b4657b97 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -61,6 +61,7 @@ use middle::trans::reachable; use middle::trans::shape::*; use middle::trans::tvec; use middle::trans::type_of::*; +use middle::ty::arg; use util::common::indenter; use util::ppaux::{ty_to_str, ty_to_short_str}; use util::ppaux; @@ -2198,9 +2199,12 @@ fn create_main_wrapper(ccx: @crate_ctxt, _sp: span, main_llfn: ValueRef) { fn create_main(ccx: @crate_ctxt, main_llfn: ValueRef) -> ValueRef { let unit_ty = ty::mk_estr(ccx.tcx, ty::vstore_uniq); let vecarg_ty: ty::arg = - {mode: ast::expl(ast::by_val), - ty: ty::mk_evec(ccx.tcx, ty::mt {ty: unit_ty, mutbl: ast::m_imm}, - ty::vstore_uniq)}; + arg { + mode: ast::expl(ast::by_val), + ty: ty::mk_evec(ccx.tcx, + ty::mt {ty: unit_ty, mutbl: ast::m_imm}, + ty::vstore_uniq) + }; let nt = ty::mk_nil(ccx.tcx); let llfty = type_of_fn(ccx, ~[vecarg_ty], nt); let llfdecl = decl_fn(ccx.llmod, ~"_rust_main", diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 0128876a898f5..3babfbd8285fd 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -39,6 +39,7 @@ use middle::trans::reachable; use middle::trans::shape; use middle::trans::type_of; use middle::trans::type_use; +use middle::ty::substs; use middle::ty; use middle::typeck; use util::ppaux::{expr_repr, ty_to_str}; @@ -1459,9 +1460,11 @@ fn find_vtable(tcx: ty::ctxt, ps: ¶m_substs, } fn dummy_substs(+tps: ~[ty::t]) -> ty::substs { - {self_r: Some(ty::re_bound(ty::br_self)), - self_ty: None, - tps: tps} + substs { + self_r: Some(ty::re_bound(ty::br_self)), + self_ty: None, + tps: tps + } } fn struct_field(index: uint) -> [uint * 3] { diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index 8c024b364c328..94145be2a1e31 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -98,7 +98,7 @@ use core::prelude::*; use lib::llvm::ValueRef; -use middle::borrowck::RootInfo; +use middle::borrowck::{RootInfo, root_map_key}; use middle::trans::base::*; use middle::trans::build::*; use middle::trans::common::*; @@ -652,7 +652,7 @@ impl Datum { // root the autoderef'd value, if necessary: // // (Note: root'd values are always boxes) - let key = {id:expr_id, derefs:derefs}; + let key = root_map_key { id: expr_id, derefs: derefs }; let bcx = match ccx.maps.root_map.find(key) { None => bcx, Some(root_info) => self.root(bcx, root_info) diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index ea9ddc2e5d0c7..24d8e94abbdba 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -114,6 +114,7 @@ lvalues are *never* stored by value. use core::prelude::*; use lib::llvm::ValueRef; +use middle::borrowck::root_map_key; use middle::resolve; use middle::trans::base::*; use middle::trans::callee::{AutorefArg, DoAutorefArg, DontAutorefArg}; @@ -757,7 +758,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { // If the lvalue must remain rooted, create a scratch datum, copy // the lvalue in there, and then arrange for it to be cleaned up // at the end of the scope with id `scope_id`: - let root_key = {id:expr.id, derefs:0u}; + let root_key = root_map_key { id: expr.id, derefs: 0u }; for bcx.ccx().maps.root_map.find(root_key).each |&root_info| { bcx = unrooted_datum.root(bcx, root_info); } diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index ac641222b3c29..317a64ea52875 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -31,7 +31,7 @@ use middle::trans::machine; use middle::trans::shape; use middle::trans::type_of::*; use middle::trans::type_of; -use middle::ty::{FnTyBase, FnMeta, FnSig}; +use middle::ty::{FnTyBase, FnMeta, FnSig, arg}; use util::ppaux::ty_to_str; use core::libc::c_uint; @@ -546,8 +546,8 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item, onceness: ast::Many, region: ty::re_bound(ty::br_anon(0)), bounds: @~[]}, - sig: FnSig {inputs: ~[{mode: ast::expl(ast::by_val), - ty: star_u8}], + sig: FnSig {inputs: ~[arg {mode: ast::expl(ast::by_val), + ty: star_u8}], output: ty::mk_nil(bcx.tcx())} }); let datum = Datum {val: get_param(decl, first_real_arg), diff --git a/src/librustc/middle/trans/machine.rs b/src/librustc/middle/trans/machine.rs index 5c0498d5a1470..7af3b7a06834a 100644 --- a/src/librustc/middle/trans/machine.rs +++ b/src/librustc/middle/trans/machine.rs @@ -13,6 +13,7 @@ use middle::trans::common::*; use middle::trans::type_of; +use middle::ty::field; use middle::ty; use syntax::parse::token::special_idents; @@ -44,13 +45,17 @@ pub fn simplify_type(tcx: ty::ctxt, typ: ty::t) -> ty::t { ty::ty_struct(did, ref substs) => { let simpl_fields = (if ty::ty_dtor(tcx, did).is_present() { // remember the drop flag - ~[{ident: special_idents::dtor, - mt: ty::mt {ty: ty::mk_u8(tcx), mutbl: ast::m_mutbl}}] } + ~[field { + ident: special_idents::dtor, + mt: ty::mt {ty: ty::mk_u8(tcx), mutbl: ast::m_mutbl} + }] } else { ~[] }) + do ty::lookup_struct_fields(tcx, did).map |f| { let t = ty::lookup_field_type(tcx, did, f.id, substs); - {ident: f.ident, - mt: ty::mt {ty: simplify_type(tcx, t), mutbl: ast::m_const}} + field { + ident: f.ident, + mt: ty::mt {ty: simplify_type(tcx, t), mutbl: ast::m_const + }} }; ty::mk_rec(tcx, simpl_fields) } diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 7eccf97f76c31..a90c25abf3dd6 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -28,6 +28,7 @@ use middle::trans::glue; use middle::trans::inline; use middle::trans::monomorphize; use middle::trans::type_of::*; +use middle::ty::arg; use middle::typeck; use util::ppaux::{ty_to_str, tys_to_str}; @@ -154,8 +155,10 @@ fn trans_self_arg(bcx: block, let mut temp_cleanups = ~[]; // Compute the mode and type of self. - let self_arg = {mode: mentry.self_arg.mode, - ty: monomorphize_type(bcx, mentry.self_arg.ty)}; + let self_arg = arg { + mode: mentry.self_arg.mode, + ty: monomorphize_type(bcx, mentry.self_arg.ty) + }; let result = trans_arg_expr(bcx, self_arg, base, &mut temp_cleanups, None, DontAutorefArg); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 0726104788cda..8f1873f628f05 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -242,14 +242,23 @@ export AutoRefKind, AutoPtr, AutoBorrowVec, AutoBorrowVecRef, AutoBorrowFn; export iter_bound_traits_and_supertraits; export count_traits_and_supertraits; export IntVarValue, IntType, UintType; +export creader_cache_key; // Data types // Note: after typeck, you should use resolved_mode() to convert this mode // into an rmode, which will take into account the results of mode inference. -type arg = {mode: ast::mode, ty: t}; +#[deriving_eq] +struct arg { + mode: ast::mode, + ty: t +} -type field = {ident: ast::ident, mt: mt}; +#[deriving_eq] +struct field { + ident: ast::ident, + mt: mt +} type param_bounds = @~[param_bound]; @@ -292,35 +301,38 @@ pub enum ValueMode { // Contains information needed to resolve types and (in the future) look up // the types of AST nodes. -type creader_cache_key = {cnum: int, pos: uint, len: uint}; -type creader_cache = HashMap; - -impl creader_cache_key : cmp::Eq { - pure fn eq(&self, other: &creader_cache_key) -> bool { - (*self).cnum == (*other).cnum && - (*self).pos == (*other).pos && - (*self).len == (*other).len - } - pure fn ne(&self, other: &creader_cache_key) -> bool { - !((*self) == (*other)) - } +#[deriving_eq] +struct creader_cache_key { + cnum: int, + pos: uint, + len: uint } +type creader_cache = HashMap; + impl creader_cache_key : to_bytes::IterBytes { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_3(&self.cnum, &self.pos, &self.len, lsb0, f); } } -type intern_key = {sty: *sty, o_def_id: Option}; +struct intern_key { + sty: *sty, + o_def_id: Option +} +// NB: Do not replace this with #[deriving_eq]. The automatically-derived +// implementation will not recurse through sty and you will get stack +// exhaustion. impl intern_key : cmp::Eq { pure fn eq(&self, other: &intern_key) -> bool { unsafe { *self.sty == *other.sty && self.o_def_id == other.o_def_id } } - pure fn ne(&self, other: &intern_key) -> bool { !(*self).eq(other) } + pure fn ne(&self, other: &intern_key) -> bool { + !self.eq(other) + } } impl intern_key : to_bytes::IterBytes { @@ -569,13 +581,10 @@ impl FnTyBase : to_bytes::IterBytes { type FnTy = FnTyBase; -type param_ty = {idx: uint, def_id: def_id}; - -impl param_ty : cmp::Eq { - pure fn eq(&self, other: ¶m_ty) -> bool { - (*self).idx == (*other).idx && (*self).def_id == (*other).def_id - } - pure fn ne(&self, other: ¶m_ty) -> bool { !(*self).eq(other) } +#[deriving_eq] +struct param_ty { + idx: uint, + def_id: def_id } impl param_ty : to_bytes::IterBytes { @@ -661,11 +670,12 @@ type opt_region = Option; * - `self_ty` is the type to which `self` should be remapped, if any. The * `self` type is rather funny in that it can only appear on traits and is * always substituted away to the implementing type for a trait. */ -type substs = { +#[deriving_eq] +struct substs { self_r: opt_region, self_ty: Option, tps: ~[t] -}; +} // NB: If you change this, you'll probably want to change the corresponding // AST structure in libsyntax/ast.rs as well. @@ -1044,7 +1054,7 @@ fn mk_t(cx: ctxt, +st: sty) -> t { mk_t_with_id(cx, st, None) } // Interns a type/name combination, stores the resulting box in cx.interner, // and returns the box as cast to an unsafe ptr (see comments for t above). fn mk_t_with_id(cx: ctxt, +st: sty, o_def_id: Option) -> t { - let key = {sty: to_unsafe_ptr(&st), o_def_id: o_def_id}; + let key = intern_key { sty: to_unsafe_ptr(&st), o_def_id: o_def_id }; match cx.interner.find(key) { Some(t) => unsafe { return cast::reinterpret_cast(&t); }, _ => () @@ -1103,7 +1113,7 @@ fn mk_t_with_id(cx: ctxt, +st: sty, o_def_id: Option) -> t { let t = @{sty: move st, id: cx.next_id, flags: flags, o_def_id: o_def_id}; - let key = {sty: to_unsafe_ptr(&t.sty), o_def_id: o_def_id}; + let key = intern_key {sty: to_unsafe_ptr(&t.sty), o_def_id: o_def_id}; cx.interner.insert(move key, t); cx.next_id += 1u; @@ -1236,7 +1246,7 @@ fn mk_infer(cx: ctxt, +it: InferTy) -> t { mk_t(cx, ty_infer(it)) } fn mk_self(cx: ctxt) -> t { mk_t(cx, ty_self) } fn mk_param(cx: ctxt, n: uint, k: def_id) -> t { - mk_t(cx, ty_param({idx: n, def_id: k})) + mk_t(cx, ty_param(param_ty { idx: n, def_id: k })) } fn mk_type(cx: ctxt) -> t { mk_t(cx, ty_type) } @@ -1352,7 +1362,7 @@ fn fold_sty_to_ty(tcx: ty::ctxt, sty: &sty, foldop: fn(t) -> t) -> t { fn fold_sig(sig: &FnSig, fldop: fn(t) -> t) -> FnSig { let args = do sig.inputs.map |arg| { - { mode: arg.mode, ty: fldop(arg.ty) } + arg { mode: arg.mode, ty: fldop(arg.ty) } }; FnSig { @@ -1363,9 +1373,9 @@ fn fold_sig(sig: &FnSig, fldop: fn(t) -> t) -> FnSig { fn fold_sty(sty: &sty, fldop: fn(t) -> t) -> sty { fn fold_substs(substs: &substs, fldop: fn(t) -> t) -> substs { - {self_r: substs.self_r, - self_ty: substs.self_ty.map(|t| fldop(*t)), - tps: substs.tps.map(|t| fldop(*t))} + substs {self_r: substs.self_r, + self_ty: substs.self_ty.map(|t| fldop(*t)), + tps: substs.tps.map(|t| fldop(*t))} } match /*bad*/copy *sty { @@ -1393,8 +1403,8 @@ fn fold_sty(sty: &sty, fldop: fn(t) -> t) -> sty { ty_rec(fields) => { let new_fields = do vec::map(fields) |fl| { let new_ty = fldop(fl.mt.ty); - let new_mt = mt {ty: new_ty, mutbl: fl.mt.mutbl}; - {ident: fl.ident, mt: new_mt} + let new_mt = mt { ty: new_ty, mutbl: fl.mt.mutbl }; + field { ident: fl.ident, mt: new_mt } }; ty_rec(new_fields) } @@ -1451,11 +1461,13 @@ fn fold_regions_and_ty( fn fold_substs( substs: &substs, fldr: fn(r: Region) -> Region, - fldt: fn(t: t) -> t) -> substs - { - {self_r: substs.self_r.map(|r| fldr(*r)), - self_ty: substs.self_ty.map(|t| fldt(*t)), - tps: substs.tps.map(|t| fldt(*t))} + fldt: fn(t: t) -> t) + -> substs { + substs { + self_r: substs.self_r.map(|r| fldr(*r)), + self_ty: substs.self_ty.map(|t| fldt(*t)), + tps: substs.tps.map(|t| fldt(*t)) + } } let tb = ty::get(ty); @@ -1671,7 +1683,7 @@ fn subst(cx: ctxt, // Performs substitutions on a set of substitutions (result = sup(sub)) to // yield a new set of substitutions. This is used in trait inheritance. fn subst_substs(cx: ctxt, sup: &substs, sub: &substs) -> substs { - { + substs { self_r: sup.self_r, self_ty: sup.self_ty.map(|typ| subst(cx, sub, *typ)), tps: sup.tps.map(|typ| subst(cx, sub, *typ)) @@ -4152,7 +4164,7 @@ fn struct_item_fields(cx:ctxt, do lookup_struct_fields(cx, did).map |f| { // consider all instance vars mut, because the // constructor may mutate all vars - { + field { ident: f.ident, mt: mt { ty: lookup_field_type(cx, did, f.id, substs), @@ -4281,9 +4293,11 @@ fn normalize_ty(cx: ctxt, t: t) -> t { Some(_) => // Use re_static since trans doesn't care about regions mk_enum(cx, did, - {self_r: Some(ty::re_static), - self_ty: None, - tps: /*bad*/copy (*r).tps}), + substs { + self_r: Some(ty::re_static), + self_ty: None, + tps: /*bad*/copy (*r).tps + }), None => t }, @@ -4292,9 +4306,9 @@ fn normalize_ty(cx: ctxt, t: t) -> t { match (*r).self_r { Some(_) => // Ditto. - mk_struct(cx, did, {self_r: Some(ty::re_static), - self_ty: None, - tps: /*bad*/copy (*r).tps}), + mk_struct(cx, did, substs {self_r: Some(ty::re_static), + self_ty: None, + tps: /*bad*/copy (*r).tps}), None => t }, @@ -4414,20 +4428,6 @@ impl mt : cmp::Eq { pure fn ne(&self, other: &mt) -> bool { !(*self).eq(other) } } -impl arg : cmp::Eq { - pure fn eq(&self, other: &arg) -> bool { - (*self).mode == (*other).mode && (*self).ty == (*other).ty - } - pure fn ne(&self, other: &arg) -> bool { !(*self).eq(other) } -} - -impl field : cmp::Eq { - pure fn eq(&self, other: &field) -> bool { - (*self).ident == (*other).ident && (*self).mt == (*other).mt - } - pure fn ne(&self, other: &field) -> bool { !(*self).eq(other) } -} - impl vstore : cmp::Eq { pure fn eq(&self, other: &vstore) -> bool { match (*self) { @@ -4536,15 +4536,6 @@ impl bound_region : cmp::Eq { pure fn ne(&self, other: &bound_region) -> bool { !(*self).eq(other) } } -impl substs : cmp::Eq { - pure fn eq(&self, other: &substs) -> bool { - (*self).self_r == (*other).self_r && - (*self).self_ty == (*other).self_ty && - (*self).tps == (*other).tps - } - pure fn ne(&self, other: &substs) -> bool { !(*self).eq(other) } -} - impl sty : cmp::Eq { pure fn eq(&self, other: &sty) -> bool { match (/*bad*/copy *self) { diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 7e1c5f54134e1..e845904956d95 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -55,7 +55,8 @@ use core::prelude::*; use middle::pat_util::pat_id_map; -use middle::ty::{FnTyBase, FnMeta, FnSig, ty_param_substs_and_ty}; +use middle::ty::{FnTyBase, FnMeta, FnSig, arg, field, substs}; +use middle::ty::{ty_param_substs_and_ty}; use middle::ty; use middle::typeck::check::fn_ctxt; use middle::typeck::collect; @@ -151,7 +152,7 @@ fn ast_path_to_substs_and_ty( } let tps = path.types.map(|a_t| ast_ty_to_ty(self, rscope, *a_t)); - let substs = {self_r:self_r, self_ty:None, tps:tps}; + let substs = substs {self_r:self_r, self_ty:None, tps:tps}; let ty = ty::subst(tcx, &substs, decl_ty); {substs: substs, ty: ty} } @@ -315,7 +316,7 @@ fn ast_ty_to_ty( ast::ty_rec(ref fields) => { let flds = do (*fields).map |f| { let tm = ast_mt_to_mt(self, rscope, f.node.mt); - {ident: f.node.ident, mt: tm} + field {ident: f.node.ident, mt: tm} }; ty::mk_rec(tcx, flds) } @@ -447,7 +448,7 @@ fn ty_of_arg( } }; - {mode: mode, ty: ty} + arg {mode: mode, ty: ty} } type expected_tys = Option<{inputs: ~[ty::arg], diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 86f58edd6c8a8..543adbd53aac8 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -295,7 +295,11 @@ impl LookupContext { let self_did = self.fcx.self_info.expect( ~"self_impl_def_id is undefined (`self` may not \ be in scope here").def_id; - let substs = {self_r: None, self_ty: None, tps: ~[]}; + let substs = substs { + self_r: None, + self_ty: None, + tps: ~[] + }; self.push_inherent_candidates_from_self( self_ty, self_did, &substs); } @@ -392,7 +396,10 @@ impl LookupContext { // impl or class (where the self type is not permitted), // or from a trait type (in which case methods that refer // to self are not permitted). - let init_substs = {self_ty: Some(rcvr_ty), ..init_substs}; + let init_substs = substs { + self_ty: Some(rcvr_ty), + ..init_substs + }; worklist.push((init_trait_ty, init_substs)); @@ -416,7 +423,10 @@ impl LookupContext { &init_substs); // Again replacing the self type - let new_substs = {self_ty: Some(rcvr_ty), ..new_substs}; + let new_substs = substs { + self_ty: Some(rcvr_ty), + ..new_substs + }; worklist.push((supertrait.tpt.ty, new_substs)); } @@ -506,7 +516,10 @@ impl LookupContext { // `trait_ty` for `self` here, because it allows the compiler // to soldier on. An error will be reported should this // candidate be selected if the method refers to `self`. - let rcvr_substs = {self_ty: Some(self_ty), ../*bad*/copy *substs}; + let rcvr_substs = substs { + self_ty: Some(self_ty), + ../*bad*/copy *substs + }; let (rcvr_ty, rcvr_substs) = self.create_rcvr_ty_and_substs_for_method(method.self_ty, @@ -537,7 +550,10 @@ impl LookupContext { } let method = &methods[index]; - let rcvr_substs = { self_ty: Some(self_ty), ../*bad*/copy *substs }; + let rcvr_substs = substs { + self_ty: Some(self_ty), + ../*bad*/copy *substs + }; let (rcvr_ty, rcvr_substs) = self.create_rcvr_ty_and_substs_for_method( method.self_ty, @@ -628,7 +644,11 @@ impl LookupContext { candidate"); // XXX: Needs to support generics. - let dummy_substs = { self_r: None, self_ty: None, tps: ~[] }; + let dummy_substs = substs { + self_r: None, + self_ty: None, + tps: ~[] + }; let (impl_ty, impl_substs) = self.create_rcvr_ty_and_substs_for_method( provided_method_info.method_info.self_type, @@ -673,11 +693,13 @@ impl LookupContext { move self_substs } sty_region(_) => { - {self_r: - Some(self.infcx().next_region_var( - self.expr.span, - self.expr.id)), - ..self_substs} + substs { + self_r: + Some(self.infcx().next_region_var( + self.expr.span, + self.expr.id)), + ..self_substs + } } } }; @@ -1058,7 +1080,7 @@ impl LookupContext { // Construct the full set of type parameters for the method, // which is equal to the class tps + the method tps. - let all_substs = { + let all_substs = substs { tps: vec::append(/*bad*/copy candidate.rcvr_substs.tps, m_substs), ../*bad*/copy candidate.rcvr_substs @@ -1066,7 +1088,7 @@ impl LookupContext { self.fcx.write_ty_substs(self.callee_id, fty, all_substs); method_map_entry { - self_arg: { + self_arg: arg { mode: ast::expl(candidate.self_mode), ty: candidate.rcvr_ty, }, diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index cf13fcb86e818..3d5f6e9d303d9 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -84,7 +84,7 @@ use middle::pat_util::pat_id_map; use middle::pat_util; use middle::ty::{TyVid, Vid, FnTyBase, FnMeta, FnSig, VariantInfo_, field}; use middle::ty::{ty_param_bounds_and_ty, ty_param_substs_and_ty}; -use middle::ty::{re_bound, br_cap_avoid}; +use middle::ty::{re_bound, br_cap_avoid, substs, arg, param_ty}; use middle::ty; use middle::typeck::astconv::{ast_conv, ast_path_to_ty}; use middle::typeck::astconv::{ast_region_to_region, ast_ty_to_ty}; @@ -1059,9 +1059,11 @@ pub fn impl_self_ty(vcx: &VtableContext, {n_tps: ts.len(), region_param: region_param, raw_ty: ty::mk_struct(tcx, local_def(class_id), - {self_r: rscope::bound_self_region(region_param), - self_ty: None, - tps: ty::ty_params_to_tys(tcx, /*bad*/copy *ts)})} + substs { + self_r: rscope::bound_self_region(region_param), + self_ty: None, + tps: ty::ty_params_to_tys(tcx, /*bad*/copy *ts) + })} } _ => { tcx.sess.bug(~"impl_self_ty: unbound item or item that \ doesn't have a self_ty"); } @@ -1081,7 +1083,7 @@ pub fn impl_self_ty(vcx: &VtableContext, }; let tps = vcx.infcx.next_ty_vars(n_tps); - let substs = {self_r: self_r, self_ty: None, tps: tps}; + let substs = substs { self_r: self_r, self_ty: None, tps: tps }; let substd_ty = ty::subst(tcx, &substs, raw_ty); {substs: substs, ty: substd_ty} } @@ -1814,7 +1816,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, let self_region = bound_self_region(region_parameterized); - raw_type = ty::mk_struct(tcx, class_id, { + raw_type = ty::mk_struct(tcx, class_id, substs { self_r: self_region, self_ty: None, tps: ty::ty_params_to_tys( @@ -1840,7 +1842,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, span, ty::re_scope(id)); let type_parameters = fcx.infcx().next_ty_vars(type_parameter_count); - let substitutions = { + let substitutions = substs { self_r: self_region, self_ty: None, tps: type_parameters @@ -1897,7 +1899,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, let self_region = bound_self_region(region_parameterized); - raw_type = ty::mk_enum(tcx, enum_id, { + raw_type = ty::mk_enum(tcx, enum_id, substs { self_r: self_region, self_ty: None, tps: ty::ty_params_to_tys( @@ -1923,7 +1925,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, span, ty::re_scope(id)); let type_parameters = fcx.infcx().next_ty_vars(type_parameter_count); - let substitutions = { + let substitutions = substs { self_r: self_region, self_ty: None, tps: type_parameters @@ -2434,7 +2436,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, let expr_mt = ty::mt {ty: expr_t, mutbl: f.node.mutbl}; // for the most precise error message, // should be f.node.expr.span, not f.span - respan(f.node.expr.span, {ident: f.node.ident, mt: expr_mt}) + respan(f.node.expr.span, field {ident: f.node.ident, mt: expr_mt}) }); match base { None => { @@ -2951,7 +2953,7 @@ fn instantiate_path(fcx: @fn_ctxt, pth.types.map(|aty| fcx.to_ty(*aty)) }; - let substs = {self_r: self_r, self_ty: None, tps: tps}; + let substs = substs { self_r: self_r, self_ty: None, tps: tps }; fcx.write_ty_substs(node_id, tpt.ty, substs); debug!("<<<"); @@ -3050,7 +3052,7 @@ fn check_bounds_are_used(ccx: @crate_ctxt, |_r| {}, |t| { match ty::get(t).sty { - ty::ty_param({idx, _}) => { + ty::ty_param(param_ty {idx, _}) => { debug!("Found use of ty param #%u", idx); tps_used[idx] = true; } @@ -3073,7 +3075,7 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) { ty::mk_param(ccx.tcx, n, local_def(0)) } fn arg(m: ast::rmode, ty: ty::t) -> ty::arg { - {mode: ast::expl(m), ty: ty} + arg {mode: ast::expl(m), ty: ty} } let tcx = ccx.tcx; let (n_tps, inputs, output) = match ccx.tcx.sess.str_of(it.ident) { @@ -3136,12 +3138,14 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) { onceness: ast::Once, region: ty::re_bound(ty::br_anon(0)), bounds: @~[]}, - sig: FnSig {inputs: ~[{mode: ast::expl(ast::by_val), - ty: ty::mk_imm_ptr( - ccx.tcx, - ty::mk_mach_uint(ccx.tcx, ast::ty_u8)) - }], - output: ty::mk_nil(ccx.tcx)} + sig: FnSig { + inputs: ~[arg { + mode: ast::expl(ast::by_val), + ty: ty::mk_imm_ptr( + ccx.tcx, + ty::mk_mach_uint(ccx.tcx, ast::ty_u8)) + }], + output: ty::mk_nil(ccx.tcx)} }); (0u, ~[arg(ast::by_ref, fty)], ty::mk_nil(tcx)) } diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index 9d309d4996bdd..9f6cc6835b715 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -11,6 +11,7 @@ use core::prelude::*; use middle::resolve; +use middle::ty::{param_ty, substs}; use middle::ty; use middle::typeck::check::{fn_ctxt, impl_self_ty}; use middle::typeck::check::{structurally_resolved_type}; @@ -103,7 +104,10 @@ fn lookup_vtables(vcx: &VtableContext, ppaux::ty_to_str(tcx, trait_ty), ty::substs_to_str(tcx, substs)); - let new_substs = {self_ty: Some(*ty), ../*bad*/copy *substs}; + let new_substs = substs { + self_ty: Some(*ty), + ../*bad*/copy *substs + }; let trait_ty = ty::subst(tcx, &new_substs, trait_ty); debug!("after subst: %?", @@ -189,7 +193,7 @@ fn lookup_vtable(vcx: &VtableContext, }; match ty::get(ty).sty { - ty::ty_param({idx: n, def_id: did}) => { + ty::ty_param(param_ty {idx: n, def_id: did}) => { let mut n_bound = 0; let bounds = tcx.ty_param_bounds.get(did.node); for ty::iter_bound_traits_and_supertraits( diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs index e5dc91b7f179a..c5374af2dd060 100644 --- a/src/librustc/middle/typeck/check/writeback.rs +++ b/src/librustc/middle/typeck/check/writeback.rs @@ -15,6 +15,7 @@ use core::prelude::*; use middle::pat_util; +use middle::ty::arg; use middle::ty; use middle::typeck::check::{fn_ctxt, self_info}; use middle::typeck::infer::{force_all, resolve_all, resolve_region}; @@ -65,7 +66,7 @@ fn resolve_method_map_entry(fcx: @fn_ctxt, sp: span, id: ast::node_id) fcx.ccx.method_map.insert( id, method_map_entry { - self_arg: {mode: mme.self_arg.mode, ty: *t}, + self_arg: arg {mode: mme.self_arg.mode, ty: *t}, .. *mme } ); diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index b0c98cfa2b17e..4cd2eaaf003c9 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -25,8 +25,8 @@ use metadata::decoder::{dl_def, dl_field, dl_impl}; use middle::resolve::{Impl, MethodInfo}; use middle::ty::{ProvidedMethodSource, ProvidedMethodInfo, bound_copy, get}; use middle::ty::{kind_can_be_copied, lookup_item_type, param_bounds, subst}; -use middle::ty::{t, ty_bool, ty_bot, ty_box, ty_enum, ty_err, ty_estr}; -use middle::ty::{ty_evec, ty_float, ty_fn, ty_infer, ty_int, ty_nil}; +use middle::ty::{substs, t, ty_bool, ty_bot, ty_box, ty_enum, ty_err}; +use middle::ty::{ty_estr, ty_evec, ty_float, ty_fn, ty_infer, ty_int, ty_nil}; use middle::ty::{ty_opaque_box, ty_param, ty_param_bounds_and_ty, ty_ptr}; use middle::ty::{ty_rec, ty_rptr, ty_self, ty_struct, ty_trait, ty_tup}; use middle::ty::{ty_type, ty_uint, ty_uniq}; @@ -34,6 +34,7 @@ use middle::ty::{ty_opaque_closure_ptr, ty_unboxed_vec, type_kind_ext}; use middle::ty::{type_is_ty_var}; use middle::ty; use middle::typeck::crate_ctxt; +use middle::typeck::infer::combine::Combine; use middle::typeck::infer::{InferCtxt, can_mk_subty}; use middle::typeck::infer::{new_infer_ctxt, resolve_ivar}; use middle::typeck::infer::{resolve_nested_tvar, resolve_type}; @@ -286,8 +287,8 @@ impl CoherenceChecker { } // Add the implementation to the mapping from implementation to base - // type def ID, if there is a base type for this implementation. - + // type def ID, if there is a base type for this implementation and + // the implementation does not have any associated traits. match get_base_type_def_id(self.inference_context, item.span, self_type.ty) { @@ -296,16 +297,19 @@ impl CoherenceChecker { } Some(base_type_def_id) => { // XXX: Gather up default methods? - let implementation; - match implementation_opt { - None => { - implementation = self.create_impl_from_item(item); - } - Some(copy existing_implementation) => { - implementation = existing_implementation; + if associated_traits.len() == 0 { + let implementation; + match implementation_opt { + None => { + implementation = self.create_impl_from_item(item); + } + Some(copy existing_implementation) => { + implementation = existing_implementation; + } } + self.add_inherent_method(base_type_def_id, + implementation); } - self.add_inherent_method(base_type_def_id, implementation); self.base_type_def_ids.insert(local_def(item.id), base_type_def_id); @@ -510,7 +514,7 @@ impl CoherenceChecker { let type_parameters = self.inference_context.next_ty_vars(bounds_count); - let substitutions = { + let substitutions = substs { self_r: self_region, self_ty: None, tps: type_parameters @@ -520,7 +524,8 @@ impl CoherenceChecker { polytype.ty); // Get our type parameters back. - let { self_r: _, self_ty: _, tps: type_parameters } = substitutions; + let substs { self_r: _, self_ty: _, tps: type_parameters } = + substitutions; UniversalQuantificationResult { monotype: monotype, @@ -597,6 +602,7 @@ impl CoherenceChecker { visit_mod(module_, item.span, item.id, (), visitor); } item_impl(_, opt_trait, _, _) => { + let mut ok = false; match self.base_type_def_ids.find( local_def(item.id)) { @@ -611,57 +617,50 @@ impl CoherenceChecker { // Record that this implementation is OK. self.privileged_implementations.insert (item.id, ()); - } else { - // This implementation is not in scope of - // its base type. This still might be OK - // if the traits are defined in the same - // crate. - - match opt_trait { - None => { - // There is no trait to implement, so - // this is an error. - - let session = - self.crate_context.tcx.sess; - session.span_err(item.span, - ~"cannot implement \ - inherent methods \ - for a type outside \ - the crate the type \ - was defined in; \ - define and \ - implement a trait \ - or new type \ - instead"); - } - _ => () - } - - do opt_trait.iter() |trait_ref| { - // This is OK if and only if the - // trait was defined in this - // crate. - - let trait_def_id = - self.trait_ref_to_trait_def_id( - *trait_ref); - - if trait_def_id.crate != local_crate { - let session = - self.crate_context.tcx.sess; - session.span_err(item.span, - ~"cannot \ - provide an \ - extension \ - implementa\ - tion \ - for a trait \ - not defined \ - in this \ - crate"); - } - } + ok = true; + } + } + } + + if !ok { + // This implementation is not in scope of its base + // type. This still might be OK if the trait is + // defined in the same crate. + + match opt_trait { + None => { + // There is no trait to implement, so + // this is an error. + + let session = self.crate_context.tcx.sess; + session.span_err(item.span, + ~"cannot implement \ + inherent methods for a \ + type outside the crate \ + the type was defined \ + in; define and \ + implement a trait or \ + new type instead"); + } + _ => () + } + + do opt_trait.iter() |trait_ref| { + // This is OK if and only if the trait was + // defined in this crate. + + let trait_def_id = + self.trait_ref_to_trait_def_id( + *trait_ref); + + if trait_def_id.crate != local_crate { + let session = self.crate_context.tcx.sess; + session.span_err(item.span, + ~"cannot provide an \ + extension \ + implementation for a \ + trait not defined in \ + this crate"); } } } diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index ba34846ca97ce..ce0c7a94c7cc0 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -33,8 +33,8 @@ are represented as `ty_param()` instances. use core::prelude::*; use metadata::csearch; -use middle::ty::{FnMeta, FnSig, FnTyBase, InstantiatedTraitRef}; -use middle::ty::{ty_param_substs_and_ty}; +use middle::ty::{FnMeta, FnSig, FnTyBase, InstantiatedTraitRef, arg}; +use middle::ty::{substs, ty_param_substs_and_ty}; use middle::ty; use middle::typeck::astconv::{ast_conv, ty_of_fn_decl, ty_of_arg}; use middle::typeck::astconv::{ast_ty_to_ty}; @@ -75,7 +75,11 @@ fn collect_item_types(ccx: @crate_ctxt, crate: @ast::crate) { for m.items.each |intrinsic_item| { let def_id = ast::def_id { crate: ast::local_crate, node: intrinsic_item.id }; - let substs = {self_r: None, self_ty: None, tps: ~[]}; + let substs = substs { + self_r: None, + self_ty: None, + tps: ~[] + }; match intrinsic_item.node { ast::item_trait(*) => { @@ -164,7 +168,7 @@ fn get_enum_variant_types(ccx: @crate_ctxt, let rs = type_rscope(rp); let args = args.map(|va| { let arg_ty = ccx.to_ty(rs, va.ty); - {mode: ast::expl(ast::by_copy), ty: arg_ty} + arg { mode: ast::expl(ast::by_copy), ty: arg_ty } }); result_ty = Some(ty::mk_fn(tcx, FnTyBase { meta: FnMeta {purity: ast::pure_fn, @@ -195,8 +199,9 @@ fn get_enum_variant_types(ccx: @crate_ctxt, variant.node.id); // Compute the ctor arg types from the struct fields let struct_fields = do struct_def.fields.map |struct_field| { - {mode: ast::expl(ast::by_val), - ty: ty::node_id_to_type(ccx.tcx, (*struct_field).node.id) + arg { + mode: ast::expl(ast::by_val), + ty: ty::node_id_to_type(ccx.tcx, struct_field.node.id) } }; result_ty = Some(ty::mk_fn(tcx, FnTyBase { @@ -265,8 +270,11 @@ fn ensure_trait_methods(ccx: @crate_ctxt, id: ast::node_id, trait_ty: ty::t) { ty::mk_param(ccx.tcx, i + 1, dummy_defid) }; - let substs = { self_r: None, self_ty: Some(self_param), - tps: non_shifted_trait_tps + shifted_method_tps }; + let substs = substs { + self_r: None, + self_ty: Some(self_param), + tps: non_shifted_trait_tps + shifted_method_tps + }; let ty = ty::subst(ccx.tcx, &substs, ty::mk_fn(ccx.tcx, /*bad*/copy m.fty)); @@ -462,7 +470,7 @@ fn compare_impl_method(tcx: ty::ctxt, }; let trait_tps = trait_substs.tps.map( |t| replace_bound_self(tcx, *t, dummy_self_r)); - let substs = { + let substs = substs { self_r: Some(dummy_self_r), self_ty: Some(self_ty), tps: vec::append(trait_tps, dummy_tps) @@ -705,7 +713,7 @@ fn convert_struct(ccx: @crate_ctxt, }, sig: FnSig { inputs: do struct_def.fields.map |field| { - { + arg { mode: ast::expl(ast::by_copy), ty: ccx.tcx.tcache.get (local_def(field.node.id)).ty @@ -1002,5 +1010,8 @@ fn mk_substs(ccx: @crate_ctxt, -> {bounds: @~[ty::param_bounds], substs: ty::substs} { let {bounds, params} = mk_ty_params(ccx, atps); let self_r = rscope::bound_self_region(rp); - {bounds: bounds, substs: {self_r: self_r, self_ty: None, tps: params}} + { + bounds: bounds, + substs: substs { self_r: self_r, self_ty: None, tps: params } + } } diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index e9946ae7c13e6..d1c57a21a3b2f 100644 --- a/src/librustc/middle/typeck/infer/combine.rs +++ b/src/librustc/middle/typeck/infer/combine.rs @@ -57,7 +57,7 @@ use core::prelude::*; use middle::ty::{FloatVar, FnTyBase, FnMeta, FnSig, IntVar, TyVar}; -use middle::ty::{IntType, UintType}; +use middle::ty::{IntType, UintType, arg, substs}; use middle::ty; use middle::typeck::infer::glb::Glb; use middle::typeck::infer::lub::Lub; @@ -233,7 +233,11 @@ fn super_substs( do relate_region_param(self, did, a.self_r, b.self_r).chain |self_r| { - Ok({self_r: self_r, self_ty: self_ty, tps: /*bad*/copy tps}) + Ok(substs { + self_r: self_r, + self_ty: self_ty, + tps: /*bad*/copy tps + }) } } } @@ -295,7 +299,7 @@ fn super_flds( if a.ident == b.ident { self.mts(a.mt, b.mt) - .chain(|mt| Ok({ident: a.ident, mt: mt}) ) + .chain(|mt| Ok(ty::field {ident: a.ident, mt: mt}) ) .chain_err(|e| Err(ty::terr_in_field(@e, a.ident)) ) } else { Err(ty::terr_record_fields( @@ -317,7 +321,7 @@ fn super_args( do self.modes(a.mode, b.mode).chain |m| { do self.contratys(a.ty, b.ty).chain |t| { - Ok({mode: m, ty: t}) + Ok(arg {mode: m, ty: t}) } } } @@ -587,4 +591,4 @@ fn super_tys( if_ok!(self.infcx().simple_var_t(vid_is_expected, vid, val)); Ok(ty::mk_mach_float(tcx, val)) } -} \ No newline at end of file +} diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index cac5fa5feb1c1..cab40ce21b154 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -255,7 +255,7 @@ use middle::ty::IntVarValue; use middle::ty; use middle::typeck::check::regionmanip::{replace_bound_regions_in_fn_sig}; use middle::typeck::infer::coercion::Coerce; -use middle::typeck::infer::combine::{CombineFields, eq_tys}; +use middle::typeck::infer::combine::{Combine, CombineFields, eq_tys}; use middle::typeck::infer::glb::Glb; use middle::typeck::infer::lub::Lub; use middle::typeck::infer::region_inference::{RegionVarBindings}; diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index ac079f8f04450..fb9e0f36c2f25 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -17,7 +17,7 @@ use middle::ty::{bound_copy, bound_const, bound_durable, bound_owned, use middle::ty::{bound_region, br_anon, br_named, br_self, br_cap_avoid, br_fresh}; use middle::ty::{ctxt, field, method}; -use middle::ty::{mt, t, param_bound}; +use middle::ty::{mt, t, param_bound, param_ty}; use middle::ty::{re_bound, re_free, re_scope, re_infer, re_static, Region}; use middle::ty::{ReSkolemized, ReVar}; use middle::ty::{ty_bool, ty_bot, ty_box, ty_struct, ty_enum}; @@ -292,9 +292,8 @@ fn fn_sig_to_str(cx: ctxt, typ: &ty::FnSig) -> ~str { } fn ty_to_str(cx: ctxt, typ: t) -> ~str { - fn fn_input_to_str(cx: ctxt, input: {mode: ast::mode, ty: t}) -> - ~str { - let {mode, ty} = input; + fn fn_input_to_str(cx: ctxt, input: ty::arg) -> ~str { + let ty::arg {mode: mode, ty: ty} = input; let modestr = match canon_mode(cx, mode) { ast::infer(_) => ~"", ast::expl(m) => { @@ -423,7 +422,7 @@ fn ty_to_str(cx: ctxt, typ: t) -> ~str { } ty_infer(infer_ty) => infer_ty.to_str(), ty_err => ~"[type error]", - ty_param({idx: id, _}) => { + ty_param(param_ty {idx: id, _}) => { ~"'" + str::from_bytes(~[('a' as u8) + (id as u8)]) } ty_self => ~"self", diff --git a/src/librustdoc/astsrv.rs b/src/librustdoc/astsrv.rs index 99cf301f18248..bc332615eaa0e 100644 --- a/src/librustdoc/astsrv.rs +++ b/src/librustdoc/astsrv.rs @@ -155,9 +155,9 @@ fn build_error_handlers( codemap: @codemap::CodeMap ) -> ErrorHandlers { - type DiagnosticHandler = { + struct DiagnosticHandler { inner: diagnostic::handler, - }; + } impl DiagnosticHandler: diagnostic::handler { fn fatal(msg: &str) -> ! { self.inner.fatal(msg) } @@ -182,7 +182,7 @@ fn build_error_handlers( diagnostic::emit(cmsp, msg, lvl); }; let inner_handler = diagnostic::mk_handler(Some(emitter)); - let handler = { + let handler = DiagnosticHandler { inner: inner_handler, }; let span_handler = diagnostic::mk_span_handler( diff --git a/src/librustdoc/attr_pass.rs b/src/librustdoc/attr_pass.rs index 1ab3ce2d6f368..39a893a4076cb 100644 --- a/src/librustdoc/attr_pass.rs +++ b/src/librustdoc/attr_pass.rs @@ -69,9 +69,9 @@ fn fold_crate( attr_parser::parse_crate(attrs) }; - { - topmod: doc::ModDoc_({ - item: { + doc::CrateDoc { + topmod: doc::ModDoc_(doc::ModDoc_ { + item: doc::ItemDoc { name: option::get_or_default(attrs.name, doc.topmod.name()), .. doc.topmod.item }, @@ -103,7 +103,7 @@ fn fold_item( parse_item_attrs(srv, doc.id, attr_parser::parse_desc) }; - { + doc::ItemDoc { desc: desc, .. doc } @@ -162,7 +162,7 @@ fn fold_enum( let doc_id = doc.id(); let doc = fold::default_seq_fold_enum(fold, doc); - { + doc::EnumDoc { variants: do par::map(doc.variants) |variant| { let variant = *variant; let desc = do astsrv::exec(srv) |ctxt| { @@ -182,7 +182,7 @@ fn fold_enum( } }; - { + doc::VariantDoc { desc: desc, .. variant } @@ -211,7 +211,7 @@ fn fold_trait( let srv = fold.ctxt; let doc = fold::default_seq_fold_trait(fold, doc); - { + doc::TraitDoc { methods: merge_method_attrs(srv, doc.id(), doc.methods), .. doc } @@ -256,7 +256,7 @@ fn merge_method_attrs( assert doc.name == attrs.first(); let desc = attrs.second(); - { + doc::MethodDoc { desc: desc, ..*doc } @@ -287,7 +287,7 @@ fn fold_impl( let srv = fold.ctxt; let doc = fold::default_seq_fold_impl(fold, doc); - { + doc::ImplDoc { methods: merge_method_attrs(srv, doc.id(), doc.methods), .. doc } diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index ebd5c047df372..0ad048d49bb4c 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -50,13 +50,13 @@ impl OutputStyle : cmp::Eq { } /// The configuration for a rustdoc session -pub type Config = { +pub struct Config { input_crate: Path, output_dir: Path, output_format: OutputFormat, output_style: OutputStyle, pandoc_cmd: Option<~str> -}; +} pub impl Config: Clone { fn clone(&self) -> Config { copy *self } @@ -95,7 +95,7 @@ pub fn usage() { } pub fn default_config(input_crate: &Path) -> Config { - { + Config { input_crate: *input_crate, output_dir: Path("."), output_format: PandocHtml, @@ -155,7 +155,7 @@ fn config_from_opts( let result = do result::chain(result) |config| { let output_dir = getopts::opt_maybe_str(matches, opt_output_dir()); let output_dir = output_dir.map(|s| Path(*s)); - result::Ok({ + result::Ok(Config { output_dir: output_dir.get_or_default(config.output_dir), .. config }) @@ -168,7 +168,7 @@ fn config_from_opts( do result::chain(parse_output_format(*output_format)) |output_format| { - result::Ok({ + result::Ok(Config { output_format: output_format, .. config }) @@ -182,7 +182,7 @@ fn config_from_opts( |output_style| { do result::chain(parse_output_style(*output_style)) |output_style| { - result::Ok({ + result::Ok(Config { output_style: output_style, .. config }) @@ -195,7 +195,7 @@ fn config_from_opts( let pandoc_cmd = maybe_find_pandoc( &config, pandoc_cmd, move program_output.take()); do result::chain(pandoc_cmd) |pandoc_cmd| { - result::Ok({ + result::Ok(Config { pandoc_cmd: pandoc_cmd, .. config }) diff --git a/src/librustdoc/desc_to_brief_pass.rs b/src/librustdoc/desc_to_brief_pass.rs index f53e0058b63be..93f4be10a5c36 100644 --- a/src/librustdoc/desc_to_brief_pass.rs +++ b/src/librustdoc/desc_to_brief_pass.rs @@ -51,7 +51,7 @@ pub fn run( fn fold_item(fold: &fold::Fold<()>, +doc: doc::ItemDoc) -> doc::ItemDoc { let doc = fold::default_seq_fold_item(fold, doc); - { + doc::ItemDoc { brief: extract(doc.desc), .. doc } @@ -60,8 +60,8 @@ fn fold_item(fold: &fold::Fold<()>, +doc: doc::ItemDoc) -> doc::ItemDoc { fn fold_trait(fold: &fold::Fold<()>, +doc: doc::TraitDoc) -> doc::TraitDoc { let doc =fold::default_seq_fold_trait(fold, doc); - { - methods: par::map(doc.methods, |doc| { + doc::TraitDoc { + methods: par::map(doc.methods, |doc| doc::MethodDoc { brief: extract(doc.desc), .. *doc }), @@ -72,8 +72,8 @@ fn fold_trait(fold: &fold::Fold<()>, +doc: doc::TraitDoc) -> doc::TraitDoc { fn fold_impl(fold: &fold::Fold<()>, +doc: doc::ImplDoc) -> doc::ImplDoc { let doc =fold::default_seq_fold_impl(fold, doc); - { - methods: par::map(doc.methods, |doc| { + doc::ImplDoc { + methods: par::map(doc.methods, |doc| doc::MethodDoc { brief: extract(doc.desc), .. *doc }), diff --git a/src/librustdoc/doc.rs b/src/librustdoc/doc.rs index 18742720b90c9..247694fb26a50 100644 --- a/src/librustdoc/doc.rs +++ b/src/librustdoc/doc.rs @@ -21,94 +21,47 @@ use core::vec; pub type AstId = int; -pub type Doc_ = { +#[deriving_eq] +pub struct Doc_ { pages: ~[Page] -}; - -impl Doc_ : cmp::Eq { - pure fn eq(&self, other: &Doc_) -> bool { - (*self).pages == (*other).pages - } - pure fn ne(&self, other: &Doc_) -> bool { !(*self).eq(other) } } +#[deriving_eq] pub enum Doc { Doc_(Doc_) } -impl Doc : cmp::Eq { - pure fn eq(&self, other: &Doc) -> bool { *(*self) == *(*other) } - pure fn ne(&self, other: &Doc) -> bool { *(*self) != *(*other) } -} - +#[deriving_eq] pub enum Page { CratePage(CrateDoc), ItemPage(ItemTag) } -impl Page : cmp::Eq { - pure fn eq(&self, other: &Page) -> bool { - match (*self) { - CratePage(e0a) => { - match (*other) { - CratePage(e0b) => e0a == e0b, - _ => false - } - } - ItemPage(e0a) => { - match (*other) { - ItemPage(e0b) => e0a == e0b, - _ => false - } - } - } - } - pure fn ne(&self, other: &Page) -> bool { !(*self).eq(other) } -} - +#[deriving_eq] pub enum Implementation { Required, Provided, } -impl Implementation : cmp::Eq { - pure fn eq(&self, other: &Implementation) -> bool { - ((*self) as uint) == ((*other) as uint) - } - pure fn ne(&self, other: &Implementation) -> bool { !(*self).eq(other) } -} - - /** * Most rustdocs can be parsed into 'sections' according to their markdown * headers */ -pub type Section = { +#[deriving_eq] +pub struct Section { header: ~str, body: ~str -}; - -impl Section : cmp::Eq { - pure fn eq(&self, other: &Section) -> bool { - (*self).header == (*other).header && (*self).body == (*other).body - } - pure fn ne(&self, other: &Section) -> bool { !(*self).eq(other) } } // FIXME (#2596): We currently give topmod the name of the crate. There // would probably be fewer special cases if the crate had its own name // and topmod's name was the empty string. -pub type CrateDoc = { - topmod: ModDoc, -}; - -impl CrateDoc : cmp::Eq { - pure fn eq(&self, other: &CrateDoc) -> bool { - (*self).topmod == (*other).topmod - } - pure fn ne(&self, other: &CrateDoc) -> bool { !(*self).eq(other) } +#[deriving_eq] +pub struct CrateDoc { + topmod: ModDoc } +#[deriving_eq] pub enum ItemTag { ModTag(ModDoc), NmodTag(NmodDoc), @@ -121,69 +74,8 @@ pub enum ItemTag { StructTag(StructDoc) } -impl ItemTag : cmp::Eq { - pure fn eq(&self, other: &ItemTag) -> bool { - match (*self) { - ModTag(e0a) => { - match (*other) { - ModTag(e0b) => e0a == e0b, - _ => false - } - } - NmodTag(e0a) => { - match (*other) { - NmodTag(e0b) => e0a == e0b, - _ => false - } - } - ConstTag(e0a) => { - match (*other) { - ConstTag(e0b) => e0a == e0b, - _ => false - } - } - FnTag(e0a) => { - match (*other) { - FnTag(e0b) => e0a == e0b, - _ => false - } - } - EnumTag(e0a) => { - match (*other) { - EnumTag(e0b) => e0a == e0b, - _ => false - } - } - TraitTag(e0a) => { - match (*other) { - TraitTag(e0b) => e0a == e0b, - _ => false - } - } - ImplTag(e0a) => { - match (*other) { - ImplTag(e0b) => e0a == e0b, - _ => false - } - } - TyTag(e0a) => { - match (*other) { - TyTag(e0b) => e0a == e0b, - _ => false - } - } - StructTag(e0a) => { - match (*other) { - StructTag(e0b) => e0a == e0b, - _ => false - } - } - } - } - pure fn ne(&self, other: &ItemTag) -> bool { !(*self).eq(other) } -} - -pub type ItemDoc = { +#[deriving_eq] +pub struct ItemDoc { id: AstId, name: ~str, path: ~[~str], @@ -192,179 +84,86 @@ pub type ItemDoc = { sections: ~[Section], // Indicates that this node is a reexport of a different item reexport: bool -}; - -impl ItemDoc : cmp::Eq { - pure fn eq(&self, other: &ItemDoc) -> bool { - (*self).id == (*other).id && - (*self).name == (*other).name && - (*self).path == (*other).path && - (*self).brief == (*other).brief && - (*self).desc == (*other).desc && - (*self).sections == (*other).sections && - (*self).reexport == (*other).reexport - } - pure fn ne(&self, other: &ItemDoc) -> bool { !(*self).eq(other) } } -pub type SimpleItemDoc = { +#[deriving_eq] +pub struct SimpleItemDoc { item: ItemDoc, sig: Option<~str> -}; - -impl SimpleItemDoc : cmp::Eq { - pure fn eq(&self, other: &SimpleItemDoc) -> bool { - (*self).item == (*other).item && (*self).sig == (*other).sig - } - pure fn ne(&self, other: &SimpleItemDoc) -> bool { !(*self).eq(other) } } -pub type ModDoc_ = { +#[deriving_eq] +pub struct ModDoc_ { item: ItemDoc, items: ~[ItemTag], index: Option -}; - -impl ModDoc_ : cmp::Eq { - pure fn eq(&self, other: &ModDoc_) -> bool { - (*self).item == (*other).item && - (*self).items == (*other).items && - (*self).index == (*other).index - } - pure fn ne(&self, other: &ModDoc_) -> bool { !(*self).eq(other) } } +#[deriving_eq] pub enum ModDoc { ModDoc_(ModDoc_) } -impl ModDoc : cmp::Eq { - pure fn eq(&self, other: &ModDoc) -> bool { *(*self) == *(*other) } - pure fn ne(&self, other: &ModDoc) -> bool { *(*self) != *(*other) } -} - -pub type NmodDoc = { +#[deriving_eq] +pub struct NmodDoc { item: ItemDoc, fns: ~[FnDoc], index: Option -}; - -impl NmodDoc : cmp::Eq { - pure fn eq(&self, other: &NmodDoc) -> bool { - (*self).item == (*other).item && - (*self).fns == (*other).fns && - (*self).index == (*other).index - } - pure fn ne(&self, other: &NmodDoc) -> bool { !(*self).eq(other) } } pub type ConstDoc = SimpleItemDoc; pub type FnDoc = SimpleItemDoc; -pub type EnumDoc = { +#[deriving_eq] +pub struct EnumDoc { item: ItemDoc, variants: ~[VariantDoc] -}; - -impl EnumDoc : cmp::Eq { - pure fn eq(&self, other: &EnumDoc) -> bool { - (*self).item == (*other).item && (*self).variants == (*other).variants - } - pure fn ne(&self, other: &EnumDoc) -> bool { !(*self).eq(other) } } -pub type VariantDoc = { +#[deriving_eq] +pub struct VariantDoc { name: ~str, desc: Option<~str>, sig: Option<~str> -}; - -impl VariantDoc : cmp::Eq { - pure fn eq(&self, other: &VariantDoc) -> bool { - (*self).name == (*other).name && - (*self).desc == (*other).desc && - (*self).sig == (*other).sig - } - pure fn ne(&self, other: &VariantDoc) -> bool { !(*self).eq(other) } } -pub type TraitDoc = { +#[deriving_eq] +pub struct TraitDoc { item: ItemDoc, methods: ~[MethodDoc] -}; - -impl TraitDoc : cmp::Eq { - pure fn eq(&self, other: &TraitDoc) -> bool { - (*self).item == (*other).item && (*self).methods == (*other).methods - } - pure fn ne(&self, other: &TraitDoc) -> bool { !(*self).eq(other) } } -pub type MethodDoc = { +#[deriving_eq] +pub struct MethodDoc { name: ~str, brief: Option<~str>, desc: Option<~str>, sections: ~[Section], sig: Option<~str>, implementation: Implementation, -}; - -impl MethodDoc : cmp::Eq { - pure fn eq(&self, other: &MethodDoc) -> bool { - (*self).name == (*other).name && - (*self).brief == (*other).brief && - (*self).desc == (*other).desc && - (*self).sections == (*other).sections && - (*self).sig == (*other).sig && - (*self).implementation == (*other).implementation - } - pure fn ne(&self, other: &MethodDoc) -> bool { !(*self).eq(other) } } -pub type ImplDoc = { +#[deriving_eq] +pub struct ImplDoc { item: ItemDoc, trait_types: ~[~str], self_ty: Option<~str>, methods: ~[MethodDoc] -}; - -impl ImplDoc : cmp::Eq { - pure fn eq(&self, other: &ImplDoc) -> bool { - (*self).item == (*other).item && - (*self).trait_types == (*other).trait_types && - (*self).self_ty == (*other).self_ty && - (*self).methods == (*other).methods - } - pure fn ne(&self, other: &ImplDoc) -> bool { !(*self).eq(other) } } pub type TyDoc = SimpleItemDoc; -pub type StructDoc = { +#[deriving_eq] +pub struct StructDoc { item: ItemDoc, fields: ~[~str], sig: Option<~str> -}; - -impl StructDoc : cmp::Eq { - pure fn eq(&self, other: &StructDoc) -> bool { - return (*self).item == other.item - && (*self).fields == other.fields - && (*self).sig == other.sig; - } - pure fn ne(&self, other: &StructDoc) -> bool { !(*self).eq(other) } } -pub type Index = { +#[deriving_eq] +pub struct Index { entries: ~[IndexEntry] -}; - -impl Index : cmp::Eq { - pure fn eq(&self, other: &Index) -> bool { - (*self).entries == (*other).entries - } - pure fn ne(&self, other: &Index) -> bool { !(*self).eq(other) } } /** @@ -377,21 +176,12 @@ impl Index : cmp::Eq { * * brief - The brief description * * link - A format-specific string representing the link target */ -pub type IndexEntry = { +#[deriving_eq] +pub struct IndexEntry { kind: ~str, name: ~str, brief: Option<~str>, link: ~str -}; - -impl IndexEntry : cmp::Eq { - pure fn eq(&self, other: &IndexEntry) -> bool { - (*self).kind == (*other).kind && - (*self).name == (*other).name && - (*self).brief == (*other).brief && - (*self).link == (*other).link - } - pure fn ne(&self, other: &IndexEntry) -> bool { !(*self).eq(other) } } impl Doc { @@ -411,7 +201,6 @@ impl Doc { /// Some helper methods on ModDoc, mostly for testing impl ModDoc { - fn mods() -> ~[ModDoc] { do vec::filter_map(self.items) |itemtag| { match *itemtag { diff --git a/src/librustdoc/extract.rs b/src/librustdoc/extract.rs index 444949cfb7f0c..93226cb5ed8c8 100644 --- a/src/librustdoc/extract.rs +++ b/src/librustdoc/extract.rs @@ -57,9 +57,9 @@ pub fn extract( crate: @ast::crate, +default_name: ~str ) -> doc::Doc { - doc::Doc_({ + doc::Doc_(doc::Doc_ { pages: ~[ - doc::CratePage({ + doc::CratePage(doc::CrateDoc { topmod: top_moddoc_from_crate(crate, default_name), }) ] @@ -75,7 +75,7 @@ fn top_moddoc_from_crate( } fn mk_itemdoc(id: ast::node_id, +name: ~str) -> doc::ItemDoc { - { + doc::ItemDoc { id: id, name: name, path: ~[], @@ -90,7 +90,7 @@ fn moddoc_from_mod( +itemdoc: doc::ItemDoc, module_: ast::_mod ) -> doc::ModDoc { - doc::ModDoc_({ + doc::ModDoc_(doc::ModDoc_ { item: itemdoc, items: do vec::filter_map(module_.items) |item| { let ItemDoc = mk_itemdoc(item.id, to_str(item.ident)); @@ -161,7 +161,7 @@ fn nmoddoc_from_mod( ast::foreign_item_const(*) => {} // XXX: Not implemented. } } - { + doc:: NmodDoc { item: itemdoc, fns: fns, index: None @@ -169,14 +169,14 @@ fn nmoddoc_from_mod( } fn fndoc_from_fn(+itemdoc: doc::ItemDoc) -> doc::FnDoc { - { + doc::SimpleItemDoc { item: itemdoc, sig: None } } fn constdoc_from_const(+itemdoc: doc::ItemDoc) -> doc::ConstDoc { - { + doc::SimpleItemDoc { item: itemdoc, sig: None } @@ -193,7 +193,7 @@ fn enumdoc_from_enum( +itemdoc: doc::ItemDoc, +variants: ~[ast::variant] ) -> doc::EnumDoc { - { + doc::EnumDoc { item: itemdoc, variants: variantdocs_from_variants(variants) } @@ -206,8 +206,7 @@ fn variantdocs_from_variants( } fn variantdoc_from_variant(variant: &ast::variant) -> doc::VariantDoc { - - { + doc::VariantDoc { name: to_str(variant.node.name), desc: None, sig: None @@ -231,12 +230,12 @@ fn traitdoc_from_trait( +itemdoc: doc::ItemDoc, +methods: ~[ast::trait_method] ) -> doc::TraitDoc { - { + doc::TraitDoc { item: itemdoc, methods: do vec::map(methods) |method| { match *method { ast::required(ty_m) => { - { + doc::MethodDoc { name: to_str(ty_m.ident), brief: None, desc: None, @@ -246,7 +245,7 @@ fn traitdoc_from_trait( } } ast::provided(m) => { - { + doc::MethodDoc { name: to_str(m.ident), brief: None, desc: None, @@ -276,12 +275,12 @@ fn impldoc_from_impl( +itemdoc: doc::ItemDoc, methods: ~[@ast::method] ) -> doc::ImplDoc { - { + doc::ImplDoc { item: itemdoc, trait_types: ~[], self_ty: None, methods: do vec::map(methods) |method| { - { + doc::MethodDoc { name: to_str(method.ident), brief: None, desc: None, @@ -302,7 +301,7 @@ fn should_extract_impl_methods() { fn tydoc_from_ty( +itemdoc: doc::ItemDoc ) -> doc::TyDoc { - { + doc::SimpleItemDoc { item: itemdoc, sig: None } @@ -318,7 +317,7 @@ fn structdoc_from_struct( +itemdoc: doc::ItemDoc, struct_def: @ast::struct_def ) -> doc::StructDoc { - { + doc::StructDoc { item: itemdoc, fields: do struct_def.fields.map |field| { match field.node.kind { diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index 29c53e0af2555..f352ed7f7e7c3 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -158,7 +158,7 @@ pub fn default_par_fold(+ctxt: T) -> Fold { } pub fn default_seq_fold_doc(fold: &Fold, +doc: doc::Doc) -> doc::Doc { - doc::Doc_({ + doc::Doc_(doc::Doc_ { pages: do vec::map(doc.pages) |page| { match *page { doc::CratePage(doc) => { @@ -177,7 +177,7 @@ pub fn default_seq_fold_crate( fold: &Fold, +doc: doc::CrateDoc ) -> doc::CrateDoc { - { + doc::CrateDoc { topmod: (fold.fold_mod)(fold, doc.topmod) } } @@ -194,7 +194,7 @@ pub fn default_any_fold_mod( +doc: doc::ModDoc ) -> doc::ModDoc { let fold_copy = fold.clone(); - doc::ModDoc_({ + doc::ModDoc_(doc::ModDoc_ { item: (fold.fold_item)(fold, doc.item), items: par::map(doc.items, |ItemTag, move fold_copy| { fold_ItemTag(&fold_copy, *ItemTag) @@ -207,7 +207,7 @@ pub fn default_seq_fold_mod( fold: &Fold, +doc: doc::ModDoc ) -> doc::ModDoc { - doc::ModDoc_({ + doc::ModDoc_(doc::ModDoc_ { item: (fold.fold_item)(fold, doc.item), items: vec::map(doc.items, |ItemTag| { fold_ItemTag(fold, *ItemTag) @@ -221,7 +221,7 @@ pub fn default_par_fold_mod( +doc: doc::ModDoc ) -> doc::ModDoc { let fold_copy = fold.clone(); - doc::ModDoc_({ + doc::ModDoc_(doc::ModDoc_ { item: (fold.fold_item)(fold, doc.item), items: par::map(doc.items, |ItemTag, move fold_copy| { fold_ItemTag(&fold_copy, *ItemTag) @@ -235,7 +235,7 @@ pub fn default_any_fold_nmod( +doc: doc::NmodDoc ) -> doc::NmodDoc { let fold_copy = fold.clone(); - { + doc::NmodDoc { item: (fold.fold_item)(fold, doc.item), fns: par::map(doc.fns, |FnDoc, move fold_copy| { (fold_copy.fold_fn)(&fold_copy, *FnDoc) @@ -248,7 +248,7 @@ pub fn default_seq_fold_nmod( fold: &Fold, +doc: doc::NmodDoc ) -> doc::NmodDoc { - { + doc::NmodDoc { item: (fold.fold_item)(fold, doc.item), fns: vec::map(doc.fns, |FnDoc| { (fold.fold_fn)(fold, *FnDoc) @@ -262,7 +262,7 @@ pub fn default_par_fold_nmod( +doc: doc::NmodDoc ) -> doc::NmodDoc { let fold_copy = fold.clone(); - { + doc::NmodDoc { item: (fold.fold_item)(fold, doc.item), fns: par::map(doc.fns, |FnDoc, move fold_copy| { (fold_copy.fold_fn)(&fold_copy, *FnDoc) @@ -307,7 +307,7 @@ pub fn default_seq_fold_fn( fold: &Fold, +doc: doc::FnDoc ) -> doc::FnDoc { - { + doc::SimpleItemDoc { item: (fold.fold_item)(fold, doc.item), .. doc } @@ -317,7 +317,7 @@ pub fn default_seq_fold_const( fold: &Fold, +doc: doc::ConstDoc ) -> doc::ConstDoc { - { + doc::SimpleItemDoc { item: (fold.fold_item)(fold, doc.item), .. doc } @@ -327,7 +327,7 @@ pub fn default_seq_fold_enum( fold: &Fold, +doc: doc::EnumDoc ) -> doc::EnumDoc { - { + doc::EnumDoc { item: (fold.fold_item)(fold, doc.item), .. doc } @@ -337,7 +337,7 @@ pub fn default_seq_fold_trait( fold: &Fold, +doc: doc::TraitDoc ) -> doc::TraitDoc { - { + doc::TraitDoc { item: (fold.fold_item)(fold, doc.item), .. doc } @@ -347,7 +347,7 @@ pub fn default_seq_fold_impl( fold: &Fold, +doc: doc::ImplDoc ) -> doc::ImplDoc { - { + doc::ImplDoc { item: (fold.fold_item)(fold, doc.item), .. doc } @@ -357,7 +357,7 @@ pub fn default_seq_fold_type( fold: &Fold, +doc: doc::TyDoc ) -> doc::TyDoc { - { + doc::SimpleItemDoc { item: (fold.fold_item)(fold, doc.item), .. doc } @@ -367,7 +367,7 @@ pub fn default_seq_fold_struct( fold: &Fold, +doc: doc::StructDoc ) -> doc::StructDoc { - { + doc::StructDoc { item: (fold.fold_item)(fold, doc.item), .. doc } diff --git a/src/librustdoc/markdown_index_pass.rs b/src/librustdoc/markdown_index_pass.rs index 1f4e1be62fc3b..b0b4278a91e0a 100644 --- a/src/librustdoc/markdown_index_pass.rs +++ b/src/librustdoc/markdown_index_pass.rs @@ -54,7 +54,7 @@ fn fold_mod( let doc = fold::default_any_fold_mod(fold, doc); - doc::ModDoc_({ + doc::ModDoc_(doc::ModDoc_ { index: Some(build_mod_index(doc, fold.ctxt)), .. *doc }) @@ -67,7 +67,7 @@ fn fold_nmod( let doc = fold::default_any_fold_nmod(fold, doc); - { + doc::NmodDoc { index: Some(build_nmod_index(doc, fold.ctxt)), .. doc } @@ -77,7 +77,7 @@ fn build_mod_index( +doc: doc::ModDoc, +config: config::Config ) -> doc::Index { - { + doc::Index { entries: par::map(doc.items, |doc| { item_to_entry(*doc, config) }) @@ -88,7 +88,7 @@ fn build_nmod_index( +doc: doc::NmodDoc, +config: config::Config ) -> doc::Index { - { + doc::Index { entries: par::map(doc.fns, |doc| { item_to_entry(doc::FnTag(*doc), config) }) @@ -109,7 +109,7 @@ fn item_to_entry( } }; - { + doc::IndexEntry { kind: markdown_pass::header_kind(doc), name: markdown_pass::header_name(doc), brief: doc.brief(), diff --git a/src/librustdoc/page_pass.rs b/src/librustdoc/page_pass.rs index 2629d45635e0b..d121d7e847893 100644 --- a/src/librustdoc/page_pass.rs +++ b/src/librustdoc/page_pass.rs @@ -76,7 +76,7 @@ fn make_doc_from_pages(page_port: PagePort) -> doc::Doc { break; } } - doc::Doc_({ + doc::Doc_(doc::Doc_ { pages: pages }) } @@ -100,7 +100,7 @@ fn fold_crate( let doc = fold::default_seq_fold_crate(fold, doc); - let page = doc::CratePage({ + let page = doc::CratePage(doc::CrateDoc { topmod: strip_mod(doc.topmod), .. doc }); @@ -128,7 +128,7 @@ fn fold_mod( } fn strip_mod(doc: doc::ModDoc) -> doc::ModDoc { - doc::ModDoc_({ + doc::ModDoc_(doc::ModDoc_ { items: do doc.items.filtered |item| { match *item { doc::ModTag(_) => false, diff --git a/src/librustdoc/path_pass.rs b/src/librustdoc/path_pass.rs index 48ed187877126..bc69ea7ed5a8d 100644 --- a/src/librustdoc/path_pass.rs +++ b/src/librustdoc/path_pass.rs @@ -54,7 +54,7 @@ fn run(srv: astsrv::Srv, +doc: doc::Doc) -> doc::Doc { } fn fold_item(fold: &fold::Fold, +doc: doc::ItemDoc) -> doc::ItemDoc { - { + doc::ItemDoc { path: fold.ctxt.path, .. doc } @@ -68,7 +68,7 @@ fn fold_mod(fold: &fold::Fold, +doc: doc::ModDoc) -> doc::ModDoc { let doc = fold::default_any_fold_mod(fold, doc); if !is_topmod { fold.ctxt.path.pop(); } - doc::ModDoc_({ + doc::ModDoc_(doc::ModDoc_ { item: (fold.fold_item)(fold, doc.item), .. *doc }) @@ -79,7 +79,7 @@ fn fold_nmod(fold: &fold::Fold, +doc: doc::NmodDoc) -> doc::NmodDoc { let doc = fold::default_seq_fold_nmod(fold, doc); fold.ctxt.path.pop(); - { + doc::NmodDoc { item: (fold.fold_item)(fold, doc.item), .. doc } diff --git a/src/librustdoc/prune_hidden_pass.rs b/src/librustdoc/prune_hidden_pass.rs index 3a924e3bddf69..c3d31d4a5b0ad 100644 --- a/src/librustdoc/prune_hidden_pass.rs +++ b/src/librustdoc/prune_hidden_pass.rs @@ -42,7 +42,7 @@ fn fold_mod( ) -> doc::ModDoc { let doc = fold::default_any_fold_mod(fold, doc); - doc::ModDoc_({ + doc::ModDoc_(doc::ModDoc_ { items: do doc.items.filtered |ItemTag| { !is_hidden(fold.ctxt, ItemTag.item()) }, diff --git a/src/librustdoc/prune_private_pass.rs b/src/librustdoc/prune_private_pass.rs index 3b11437acebaf..a18530a74603a 100644 --- a/src/librustdoc/prune_private_pass.rs +++ b/src/librustdoc/prune_private_pass.rs @@ -48,7 +48,7 @@ fn fold_mod( ) -> doc::ModDoc { let doc = fold::default_any_fold_mod(fold, doc); - doc::ModDoc_({ + doc::ModDoc_(doc::ModDoc_ { items: doc.items.filtered(|ItemTag| { is_visible(fold.ctxt, ItemTag.item()) }), diff --git a/src/librustdoc/sectionalize_pass.rs b/src/librustdoc/sectionalize_pass.rs index eeadd82371fd9..706aecf49b95b 100644 --- a/src/librustdoc/sectionalize_pass.rs +++ b/src/librustdoc/sectionalize_pass.rs @@ -46,7 +46,7 @@ fn fold_item(fold: &fold::Fold<()>, +doc: doc::ItemDoc) -> doc::ItemDoc { let doc = fold::default_seq_fold_item(fold, doc); let (desc, sections) = sectionalize(doc.desc); - { + doc::ItemDoc { desc: desc, sections: sections, .. doc @@ -56,11 +56,11 @@ fn fold_item(fold: &fold::Fold<()>, +doc: doc::ItemDoc) -> doc::ItemDoc { fn fold_trait(fold: &fold::Fold<()>, +doc: doc::TraitDoc) -> doc::TraitDoc { let doc = fold::default_seq_fold_trait(fold, doc); - { + doc::TraitDoc { methods: do par::map(doc.methods) |method| { let (desc, sections) = sectionalize(method.desc); - { + doc::MethodDoc { desc: desc, sections: sections, .. *method @@ -73,11 +73,11 @@ fn fold_trait(fold: &fold::Fold<()>, +doc: doc::TraitDoc) -> doc::TraitDoc { fn fold_impl(fold: &fold::Fold<()>, +doc: doc::ImplDoc) -> doc::ImplDoc { let doc = fold::default_seq_fold_impl(fold, doc); - { + doc::ImplDoc { methods: do par::map(doc.methods) |method| { let (desc, sections) = sectionalize(method.desc); - { + doc::MethodDoc { desc: desc, sections: sections, .. *method @@ -121,7 +121,7 @@ fn sectionalize(desc: Option<~str>) -> (Option<~str>, ~[doc::Section]) { if current_section.is_some() { sections += ~[current_section.get()]; } - current_section = Some({ + current_section = Some(doc::Section { header: header, body: ~"" }); @@ -129,7 +129,7 @@ fn sectionalize(desc: Option<~str>) -> (Option<~str>, ~[doc::Section]) { None => { match copy current_section { Some(section) => { - current_section = Some({ + current_section = Some(doc::Section { body: section.body + ~"\n" + *line, .. section }); diff --git a/src/librustdoc/sort_pass.rs b/src/librustdoc/sort_pass.rs index b3ecb8173fee7..42759be68ad32 100644 --- a/src/librustdoc/sort_pass.rs +++ b/src/librustdoc/sort_pass.rs @@ -55,7 +55,7 @@ fn fold_mod( +doc: doc::ModDoc ) -> doc::ModDoc { let doc = fold::default_any_fold_mod(fold, doc); - doc::ModDoc_({ + doc::ModDoc_(doc::ModDoc_ { items: sort::merge_sort(doc.items, fold.ctxt.op), .. *doc }) diff --git a/src/librustdoc/text_pass.rs b/src/librustdoc/text_pass.rs index 5627bfead9f45..fb55641b764f4 100644 --- a/src/librustdoc/text_pass.rs +++ b/src/librustdoc/text_pass.rs @@ -62,7 +62,7 @@ fn fold_item( ) -> doc::ItemDoc { let doc = fold::default_seq_fold_item(fold, doc); - { + doc::ItemDoc { brief: maybe_apply_op(fold.ctxt, doc.brief), desc: maybe_apply_op(fold.ctxt, doc.desc), sections: apply_to_sections(fold.ctxt, doc.sections), @@ -74,7 +74,7 @@ fn apply_to_sections( op: NominalOp, sections: ~[doc::Section] ) -> ~[doc::Section] { - par::map(sections, |section, copy op| { + par::map(sections, |section, copy op| doc::Section { header: (op.op)(section.header), body: (op.op)(section.body) }) @@ -86,9 +86,9 @@ fn fold_enum( let doc = fold::default_seq_fold_enum(fold, doc); let fold_copy = copy *fold; - { + doc::EnumDoc { variants: do par::map(doc.variants) |variant, copy fold_copy| { - { + doc::VariantDoc { desc: maybe_apply_op(fold_copy.ctxt, variant.desc), .. *variant } @@ -103,7 +103,7 @@ fn fold_trait( ) -> doc::TraitDoc { let doc = fold::default_seq_fold_trait(fold, doc); - { + doc::TraitDoc { methods: apply_to_methods(fold.ctxt, doc.methods), .. doc } @@ -114,7 +114,7 @@ fn apply_to_methods( docs: ~[doc::MethodDoc] ) -> ~[doc::MethodDoc] { do par::map(docs) |doc, copy op| { - { + doc::MethodDoc { brief: maybe_apply_op(op, doc.brief), desc: maybe_apply_op(op, doc.desc), sections: apply_to_sections(op, doc.sections), @@ -129,7 +129,7 @@ fn fold_impl( ) -> doc::ImplDoc { let doc = fold::default_seq_fold_impl(fold, doc); - { + doc::ImplDoc { methods: apply_to_methods(fold.ctxt, doc.methods), .. doc } diff --git a/src/librustdoc/tystr_pass.rs b/src/librustdoc/tystr_pass.rs index 5d92ed14c18df..3b9991d18274e 100644 --- a/src/librustdoc/tystr_pass.rs +++ b/src/librustdoc/tystr_pass.rs @@ -59,7 +59,7 @@ fn fold_fn( let srv = fold.ctxt; - { + doc::SimpleItemDoc { sig: get_fn_sig(srv, doc.id()), .. doc } @@ -101,7 +101,7 @@ fn fold_const( ) -> doc::ConstDoc { let srv = fold.ctxt; - { + doc::SimpleItemDoc { sig: Some(do astsrv::exec(srv) |ctxt| { match ctxt.ast_map.get(doc.id()) { ast_map::node_item(@ast::item { @@ -129,7 +129,7 @@ fn fold_enum( let doc_id = doc.id(); let srv = fold.ctxt; - { + doc::EnumDoc { variants: do par::map(doc.variants) |variant| { let variant = *variant; let sig = do astsrv::exec(srv) |ctxt| { @@ -148,7 +148,7 @@ fn fold_enum( } }; - { + doc::VariantDoc { sig: Some(sig), .. variant } @@ -167,7 +167,7 @@ fn fold_trait( fold: &fold::Fold, +doc: doc::TraitDoc ) -> doc::TraitDoc { - { + doc::TraitDoc { methods: merge_methods(fold.ctxt, doc.id(), doc.methods), .. doc } @@ -179,7 +179,7 @@ fn merge_methods( docs: ~[doc::MethodDoc] ) -> ~[doc::MethodDoc] { do par::map(docs) |doc| { - { + doc::MethodDoc { sig: get_method_sig(srv, item_id, doc.name), .. *doc } @@ -276,7 +276,7 @@ fn fold_impl( } }; - { + doc::ImplDoc { trait_types: trait_types, self_ty: self_ty, methods: merge_methods(fold.ctxt, doc.id(), doc.methods), @@ -316,7 +316,7 @@ fn fold_type( let srv = fold.ctxt; - { + doc::SimpleItemDoc { sig: do astsrv::exec(srv) |ctxt| { match ctxt.ast_map.get(doc.id()) { ast_map::node_item(@ast::item { @@ -349,7 +349,7 @@ fn fold_struct( ) -> doc::StructDoc { let srv = fold.ctxt; - { + doc::StructDoc { sig: do astsrv::exec(srv) |ctxt| { match ctxt.ast_map.get(doc.id()) { ast_map::node_item(item, _) => { diff --git a/src/libstd/bigint.rs b/src/libstd/bigint.rs index fc7834291267b..4283a7e402bce 100644 --- a/src/libstd/bigint.rs +++ b/src/libstd/bigint.rs @@ -17,7 +17,7 @@ A BigInt is a combination of BigUint and Sign. */ use core::cmp::{Eq, Ord}; -use core::num::{Num, Zero, One}; +use core::num::{IntConvertible, Zero, One}; use core::*; /** @@ -121,7 +121,7 @@ impl BigUint : One { static pub pure fn one() -> BigUint { BigUint::new(~[1]) } } -impl BigUint : Num { +impl BigUint : Add { pure fn add(&self, other: &BigUint) -> BigUint { let new_len = uint::max(self.data.len(), other.data.len()); @@ -138,7 +138,9 @@ impl BigUint : Num { if carry == 0 { return BigUint::new(sum) }; return BigUint::new(sum + [carry]); } +} +impl BigUint : Sub { pure fn sub(&self, other: &BigUint) -> BigUint { let new_len = uint::max(self.data.len(), other.data.len()); @@ -161,7 +163,9 @@ impl BigUint : Num { assert borrow == 0; // <=> assert (self >= other); return BigUint::new(diff); } +} +impl BigUint : Mul { pure fn mul(&self, other: &BigUint) -> BigUint { if self.is_zero() || other.is_zero() { return Zero::zero(); } @@ -224,18 +228,27 @@ impl BigUint : Num { } } } +} +impl BigUint : Div { pure fn div(&self, other: &BigUint) -> BigUint { let (d, _) = self.divmod(other); return d; } +} + +impl BigUint : Modulo { pure fn modulo(&self, other: &BigUint) -> BigUint { let (_, m) = self.divmod(other); return m; } +} +impl BigUint : Neg { pure fn neg(&self) -> BigUint { fail } +} +impl BigUint : IntConvertible { pure fn to_int(&self) -> int { uint::min(self.to_uint(), int::max_value as uint) as int } @@ -625,7 +638,7 @@ impl BigInt : One { } } -impl BigInt : Num { +impl BigInt : Add { pure fn add(&self, other: &BigInt) -> BigInt { match (self.sign, other.sign) { (Zero, _) => copy *other, @@ -637,6 +650,9 @@ impl BigInt : Num { (Minus, Minus) => -((-self) + (-*other)) } } +} + +impl BigInt : Sub { pure fn sub(&self, other: &BigInt) -> BigInt { match (self.sign, other.sign) { (Zero, _) => -other, @@ -654,6 +670,9 @@ impl BigInt : Num { (Minus, Minus) => (-other) - (-*self) } } +} + +impl BigInt : Mul { pure fn mul(&self, other: &BigInt) -> BigInt { match (self.sign, other.sign) { (Zero, _) | (_, Zero) => Zero::zero(), @@ -665,18 +684,29 @@ impl BigInt : Num { } } } +} + +impl BigInt : Div { pure fn div(&self, other: &BigInt) -> BigInt { let (d, _) = self.divmod(other); return d; } +} + +impl BigInt : Modulo { pure fn modulo(&self, other: &BigInt) -> BigInt { let (_, m) = self.divmod(other); return m; } +} + +impl BigInt : Neg { pure fn neg(&self) -> BigInt { BigInt::from_biguint(self.sign.neg(), copy self.data) } +} +impl BigInt : IntConvertible { pure fn to_int(&self) -> int { match self.sign { Plus => uint::min(self.to_uint(), int::max_value as uint) as int, @@ -834,7 +864,7 @@ pub impl BigInt { mod biguint_tests { use core::*; - use core::num::{Num, Zero, One}; + use num::{IntConvertible, Zero, One}; use super::{BigInt, BigUint, BigDigit}; #[test] @@ -974,7 +1004,7 @@ mod biguint_tests { fn test_convert_int() { fn check(v: ~[BigDigit], i: int) { let b = BigUint::new(v); - assert b == Num::from_int(i); + assert b == IntConvertible::from_int(i); assert b.to_int() == i; } @@ -1244,7 +1274,7 @@ mod bigint_tests { use super::{BigInt, BigUint, BigDigit, Sign, Minus, Zero, Plus}; use core::*; - use core::num::{Num, Zero, One}; + use core::num::{IntConvertible, Zero, One}; #[test] fn test_from_biguint() { @@ -1303,7 +1333,7 @@ mod bigint_tests { #[test] fn test_convert_int() { fn check(b: BigInt, i: int) { - assert b == Num::from_int(i); + assert b == IntConvertible::from_int(i); assert b.to_int() == i; } @@ -1563,7 +1593,8 @@ mod bigint_tests { #[test] fn test_to_str_radix() { fn check(n: int, ans: &str) { - assert ans == Num::from_int::(n).to_str_radix(10); + assert ans == IntConvertible::from_int::( + n).to_str_radix(10); } check(10, "10"); check(1, "1"); @@ -1576,7 +1607,7 @@ mod bigint_tests { #[test] fn test_from_str_radix() { fn check(s: &str, ans: Option) { - let ans = ans.map(|&n| Num::from_int(n)); + let ans = ans.map(|&n| IntConvertible::from_int(n)); assert BigInt::from_str_radix(s, 10) == ans; } check("10", Some(10)); diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index b4217dfb39d4a..2abd59523a104 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.rs @@ -249,69 +249,19 @@ mod tests { assert deq.get(3) == d; } + #[deriving_eq] enum Taggy { One(int), Two(int, int), Three(int, int, int), } + #[deriving_eq] enum Taggypar { Onepar(int), Twopar(int, int), Threepar(int, int, int), } + #[deriving_eq] struct RecCy { x: int, y: int, - t: Taggy, - } - - impl Taggy : Eq { - pure fn eq(&self, other: &Taggy) -> bool { - match (*self) { - One(a1) => match (*other) { - One(b1) => return a1 == b1, - _ => return false - }, - Two(a1, a2) => match (*other) { - Two(b1, b2) => return a1 == b1 && a2 == b2, - _ => return false - }, - Three(a1, a2, a3) => match (*other) { - Three(b1, b2, b3) => return a1 == b1 && a2 == b2 && a3 == b3, - _ => return false - } - } - } - pure fn ne(&self, other: &Taggy) -> bool { !(*self).eq(other) } - } - - impl Taggypar : Eq { - //let eq4: EqFn> = |x,y| taggypareq::(x, y); - pure fn eq(&self, other: &Taggypar) -> bool { - match (*self) { - Onepar::(a1) => match (*other) { - Onepar::(b1) => return a1 == b1, - _ => return false - }, - Twopar::(a1, a2) => match (*other) { - Twopar::(b1, b2) => return a1 == b1 && a2 == b2, - _ => return false - }, - Threepar::(a1, a2, a3) => match (*other) { - Threepar::(b1, b2, b3) => { - return a1 == b1 && a2 == b2 && a3 == b3 - } - _ => return false - } - } - } - pure fn ne(&self, other: &Taggypar) -> bool { - !(*self).eq(other) - } - } - - impl RecCy : Eq { - pure fn eq(&self, other: &RecCy) -> bool { - return (*self).x == (*other).x && (*self).y == (*other).y && - (*self).t == (*other).t; - } - pure fn ne(&self, other: &RecCy) -> bool { !(*self).eq(other) } + t: Taggy } #[test] diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs index dc379cec21b59..f93705c0c62b6 100644 --- a/src/libstd/ebml.rs +++ b/src/libstd/ebml.rs @@ -676,6 +676,7 @@ pub mod writer { mod tests { use ebml::reader; use ebml::writer; + use serialize::Encodable; use serialize; use core::io; diff --git a/src/libstd/json.rs b/src/libstd/json.rs index 45d467095fb85..1361d8647b574 100644 --- a/src/libstd/json.rs +++ b/src/libstd/json.rs @@ -15,6 +15,7 @@ //! json serialization +use serialize::Encodable; use serialize; use sort::Sort; diff --git a/src/libstd/map.rs b/src/libstd/map.rs index 3c890ef06541f..f3016e9df21a8 100644 --- a/src/libstd/map.rs +++ b/src/libstd/map.rs @@ -28,7 +28,7 @@ pub type Set = HashMap; pub type HashMap = chained::T; -pub trait Map { +pub trait StdMap { /// Return the number of elements in the map pure fn size() -> uint; @@ -124,7 +124,7 @@ pub mod util { // FIXME (#2344): package this up and export it as a datatype usable for // external code that doesn't want to pay the cost of a box. pub mod chained { - use map::{Map, util}; + use map::{StdMap, util}; use core::io; use core::ops; @@ -239,7 +239,7 @@ pub mod chained { } } - impl T: Map { + impl T: StdMap { pure fn size() -> uint { self.count } pure fn contains_key(k: K) -> bool { diff --git a/src/libstd/smallintmap.rs b/src/libstd/smallintmap.rs index 5f16f7155b61c..f17fce28ea93b 100644 --- a/src/libstd/smallintmap.rs +++ b/src/libstd/smallintmap.rs @@ -15,7 +15,7 @@ #[forbid(deprecated_mode)]; use map; -use map::Map; +use map::StdMap; use core::dvec::DVec; use core::ops; @@ -81,7 +81,7 @@ pub pure fn contains_key(self: SmallIntMap, key: uint) -> bool { } /// Implements the map::map interface for smallintmap -impl SmallIntMap: map::Map { +impl SmallIntMap: map::StdMap { pure fn size() -> uint { let mut sz = 0u; for self.v.each |item| { @@ -165,8 +165,8 @@ impl SmallIntMap: ops::Index { } /// Cast the given smallintmap to a map::map -pub fn as_map(s: SmallIntMap) -> map::Map { - s as map::Map:: +pub fn as_map(s: SmallIntMap) -> map::StdMap { + s as map::StdMap:: } #[cfg(test)] diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index ddd0f846f9d6c..201d53c0c3f36 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -12,7 +12,7 @@ use core::prelude::*; use ast::*; use ast; -use ast_util::{path_to_ident, stmt_id}; +use ast_util::{inlined_item_utils, path_to_ident, stmt_id}; use ast_util; use attr; use codemap; diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 23ea27e7c5cfc..7b134a8db2424 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -376,7 +376,7 @@ pure fn struct_field_visibility(field: ast::struct_field) -> visibility { } } -trait inlined_item_utils { +pub trait inlined_item_utils { fn ident() -> ident; fn id() -> ast::node_id; fn accept(e: E, v: visit::vt); diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 7a7c2312f5640..7e3cbd18f5273 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -33,7 +33,7 @@ use core::uint; use core::vec; use std::serialize::{Encodable, Decodable, Encoder, Decoder}; -trait Pos { +pub trait Pos { static pure fn from_uint(n: uint) -> self; pure fn to_uint(&self) -> uint; } diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 6112313cf4808..4c0cc161fdd03 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -10,7 +10,7 @@ use core::prelude::*; -use codemap::span; +use codemap::{Pos, span}; use codemap; use core::cmp; diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs index 343ce4b039b51..8a5b8a127d035 100644 --- a/src/libsyntax/ext/pipes/ast_builder.rs +++ b/src/libsyntax/ext/pipes/ast_builder.rs @@ -66,7 +66,7 @@ impl @ast::path: append_types { } } -trait ext_ctxt_ast_builder { +pub trait ext_ctxt_ast_builder { fn ty_param(id: ast::ident, +bounds: ~[ast::ty_param_bound]) -> ast::ty_param; fn arg(name: ident, ty: @ast::Ty) -> ast::arg; diff --git a/src/libsyntax/ext/pipes/mod.rs b/src/libsyntax/ext/pipes/mod.rs index 8eef065395e06..f91ec1ea48f85 100644 --- a/src/libsyntax/ext/pipes/mod.rs +++ b/src/libsyntax/ext/pipes/mod.rs @@ -49,6 +49,7 @@ use codemap::span; use ext::base; use ext::base::ext_ctxt; use ext::pipes::parse_proto::proto_parser; +use ext::pipes::pipec::gen_init; use ext::pipes::proto::{visit, protocol}; use parse::lexer::{new_tt_reader, reader}; use parse::parser::Parser; diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index e53057cb312e3..774a559625828 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -13,7 +13,8 @@ use ast::ident; use ast_util::dummy_sp; use ext::base::ext_ctxt; -use ext::pipes::ast_builder::{append_types, path, path_global}; +use ext::pipes::ast_builder::{append_types, ext_ctxt_ast_builder, path}; +use ext::pipes::ast_builder::{path_global}; use ext::pipes::proto::*; use ext::quote::rt::*; use parse::*; @@ -35,7 +36,7 @@ trait to_type_decls { fn to_endpoint_decls(cx: ext_ctxt, dir: direction) -> ~[@ast::item]; } -trait gen_init { +pub trait gen_init { fn gen_init(cx: ext_ctxt) -> @ast::item; fn compile(cx: ext_ctxt) -> @ast::item; fn buffer_ty_path(cx: ext_ctxt) -> @ast::Ty; diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs index 26638cd8cd64f..9d24b3db72437 100644 --- a/src/libsyntax/ext/pipes/proto.rs +++ b/src/libsyntax/ext/pipes/proto.rs @@ -13,7 +13,7 @@ use core::prelude::*; use ast; use codemap::span; use ext::base::ext_ctxt; -use ext::pipes::ast_builder::{path, append_types}; +use ext::pipes::ast_builder::{append_types, ext_ctxt_ast_builder, path}; use core::cmp; use core::dvec::DVec; diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 3354d015476e5..7605e01fbf024 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -10,7 +10,7 @@ use ast; use attr; -use codemap::{span, BytePos}; +use codemap::{BytePos, Pos, span}; use ext::base::ext_ctxt; use ext::base; use ext::build; diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 3ade0bf86b122..4ecbbdc9760ba 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -9,7 +9,7 @@ // except according to those terms. use codemap; -use codemap::{span, Loc, FileMap}; +use codemap::{FileMap, Loc, Pos, span}; use ext::base::*; use ext::base; use ext::build::{mk_base_vec_e, mk_uint, mk_u8, mk_base_str}; diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs index 66c3111b30960..fbe258852e273 100644 --- a/src/libsyntax/parse/comments.rs +++ b/src/libsyntax/parse/comments.rs @@ -11,7 +11,7 @@ use core::prelude::*; use ast; -use codemap::{BytePos, CharPos, CodeMap, FileMap}; +use codemap::{BytePos, CharPos, CodeMap, FileMap, Pos}; use diagnostic; use parse::lexer::{is_whitespace, get_str_from, reader}; use parse::lexer::{string_reader, bump, is_eof, nextch}; diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index 1574a037a4638..5a0f40f3c12f5 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -12,7 +12,7 @@ use core::prelude::*; use ast; use ast_util; -use codemap::{span, CodeMap, CharPos, BytePos}; +use codemap::{BytePos, CharPos, CodeMap, Pos, span}; use codemap; use diagnostic::span_handler; use ext::tt::transcribe::{tt_next_token}; diff --git a/src/test/auxiliary/issue_2242_b.rs b/src/test/auxiliary/issue_2242_b.rs deleted file mode 100644 index 73ec1f47230fe..0000000000000 --- a/src/test/auxiliary/issue_2242_b.rs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[link(name = "b", vers = "0.1")]; -#[crate_type = "lib"]; - -extern mod a; -use a::to_strz; - -impl int: to_strz { - fn to_strz() -> ~str { fmt!("%?", self) } -} diff --git a/src/test/compile-fail/drop-on-non-struct.rs b/src/test/compile-fail/drop-on-non-struct.rs index 95512a2da6068..6988027235074 100644 --- a/src/test/compile-fail/drop-on-non-struct.rs +++ b/src/test/compile-fail/drop-on-non-struct.rs @@ -11,6 +11,7 @@ type Foo = @[u8]; impl Foo : Drop { //~ ERROR the Drop trait may only be implemented +//~^ ERROR cannot provide an extension implementation fn finalize(&self) { io::println("kaboom"); } diff --git a/src/test/compile-fail/map-types.rs b/src/test/compile-fail/map-types.rs index 89377eb3d152a..7161e85444792 100644 --- a/src/test/compile-fail/map-types.rs +++ b/src/test/compile-fail/map-types.rs @@ -11,12 +11,13 @@ extern mod std; use std::map; use std::map::HashMap; -use std::map::Map; +use std::map::StdMap; // Test that trait types printed in error msgs include the type arguments. fn main() { - let x: Map<~str,~str> = map::HashMap::<~str,~str>() as Map::<~str,~str>; - let y: Map = x; - //~^ ERROR mismatched types: expected `@std::map::Map` + let x: StdMap<~str,~str> = map::HashMap::<~str,~str>() as + StdMap::<~str,~str>; + let y: StdMap = x; + //~^ ERROR mismatched types: expected `@std::map::StdMap` } diff --git a/src/test/run-pass/auto-encode.rs b/src/test/run-pass/auto-encode.rs index 6ea08d200e77d..ec73704ca27ba 100644 --- a/src/test/run-pass/auto-encode.rs +++ b/src/test/run-pass/auto-encode.rs @@ -128,19 +128,16 @@ impl CLike : cmp::Eq { #[auto_encode] #[auto_decode] +#[deriving_eq] struct Spanned { lo: uint, hi: uint, node: T, } -impl Spanned : cmp::Eq { - pure fn eq(&self, other: &Spanned) -> bool { - self.lo == other.lo && - self.hi == other.hi && - self.node == other.node - } - pure fn ne(&self, other: &Spanned) -> bool { !self.eq(other) } +enum AnEnum { + AVariant, + AnotherVariant } #[auto_encode] diff --git a/src/test/run-pass/class-impl-very-parameterized-trait.rs b/src/test/run-pass/class-impl-very-parameterized-trait.rs index b802b9708923e..6bc881884522a 100644 --- a/src/test/run-pass/class-impl-very-parameterized-trait.rs +++ b/src/test/run-pass/class-impl-very-parameterized-trait.rs @@ -51,7 +51,7 @@ impl cat { } } -impl cat : Map { +impl cat : StdMap { pure fn size() -> uint { self.meows as uint } fn insert(+k: int, +_v: T) -> bool { self.meows += k; diff --git a/src/test/run-pass/issue-2242-d.rs b/src/test/run-pass/issue-2242-d.rs deleted file mode 100644 index 006a33ebb65ed..0000000000000 --- a/src/test/run-pass/issue-2242-d.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// xfail-fast (aux-build) -// aux-build:issue_2242_a.rs -// aux-build:issue_2242_b.rs -// aux-build:issue_2242_c.rs - -extern mod a; -extern mod b; -extern mod c; - -use a::to_strz; - -fn main() { - io::println((~"foo").to_strz()); - io::println(1.to_strz()); - io::println(true.to_strz()); -} From 2c31c787fcfb7604de6d0c57f34f41a7fd0b785e Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Mon, 28 Jan 2013 10:46:43 -0800 Subject: [PATCH 2/4] librustc: Disallow trait bounds in types, enumerations, and structure definitions --- src/libcore/hashmap.rs | 6 +- src/libcore/io.rs | 2 +- src/libcore/oldcomm.rs | 8 +- src/libcore/pipes.rs | 294 +++++++++++++++++- src/libcore/private.rs | 6 +- src/libcore/private/global.rs | 2 +- src/libcore/reflect.rs | 2 +- src/libcore/task/local_data.rs | 2 +- src/libcore/task/spawn.rs | 2 +- src/librustc/middle/ty.rs | 2 +- src/librustc/middle/typeck/collect.rs | 22 ++ src/librustc/middle/typeck/infer/unify.rs | 2 +- src/libstd/arc.rs | 14 +- src/libstd/comm.rs | 9 +- src/libstd/flatpipes.rs | 33 +- src/libstd/map.rs | 8 +- src/libstd/priority_queue.rs | 2 +- src/libstd/sync.rs | 4 +- src/libstd/treemap.rs | 10 +- src/libstd/workcache.rs | 7 + src/libsyntax/ext/pipes/ast_builder.rs | 7 + src/libsyntax/ext/pipes/pipec.rs | 8 +- src/libsyntax/parse/obsolete.rs | 18 +- src/libsyntax/util/interner.rs | 2 +- src/test/auxiliary/issue-2526.rs | 2 +- src/test/auxiliary/test_comm.rs | 4 +- .../bench/task-perf-word-count-generic.rs | 12 +- src/test/compile-fail/issue-2718-a.rs | 2 +- src/test/run-fail/bug-811.rs | 2 +- src/test/run-fail/issue-2444.rs | 2 +- src/test/run-pass/auto-encode.rs | 5 - src/test/run-pass/box-unbox.rs | 2 +- .../class-impl-very-parameterized-trait.rs | 2 +- src/test/run-pass/generic-exterior-box.rs | 2 +- src/test/run-pass/generic-exterior-unique.rs | 2 +- src/test/run-pass/issue-2288.rs | 2 +- src/test/run-pass/issue-2311-2.rs | 2 +- src/test/run-pass/issue-2445-b.rs | 2 +- src/test/run-pass/issue-2445.rs | 2 +- src/test/run-pass/issue-2718.rs | 6 +- src/test/run-pass/issue-3149.rs | 2 +- src/test/run-pass/reflect-visit-data.rs | 2 +- src/test/run-pass/resource-generic.rs | 2 +- src/test/run-pass/send-type-inference.rs | 2 +- 44 files changed, 424 insertions(+), 107 deletions(-) diff --git a/src/libcore/hashmap.rs b/src/libcore/hashmap.rs index c3af7a99692e5..a22b21a1e2acf 100644 --- a/src/libcore/hashmap.rs +++ b/src/libcore/hashmap.rs @@ -35,13 +35,13 @@ pub mod linear { const INITIAL_CAPACITY: uint = 32u; // 2^5 - struct Bucket { + struct Bucket { hash: uint, key: K, value: V, } - pub struct LinearMap { + pub struct LinearMap { k0: u64, k1: u64, resize_at: uint, @@ -423,7 +423,7 @@ pub mod linear { pure fn ne(&self, other: &LinearMap) -> bool { !self.eq(other) } } - pub struct LinearSet { + pub struct LinearSet { priv map: LinearMap } diff --git a/src/libcore/io.rs b/src/libcore/io.rs index fedcb9511960e..933c38b5499b5 100644 --- a/src/libcore/io.rs +++ b/src/libcore/io.rs @@ -1111,7 +1111,7 @@ pub mod fsync { // Artifacts that need to fsync on destruction - pub struct Res { + pub struct Res { arg: Arg, } diff --git a/src/libcore/oldcomm.rs b/src/libcore/oldcomm.rs index c221df293dcdb..1473aa6da0782 100644 --- a/src/libcore/oldcomm.rs +++ b/src/libcore/oldcomm.rs @@ -68,7 +68,7 @@ use vec; * transmitted. If a port value is copied, both copies refer to the same * port. Ports may be associated with multiple `chan`s. */ -pub enum Port { +pub enum Port { Port_(@PortPtr) } @@ -84,7 +84,7 @@ pub enum Port { * data will be silently dropped. Channels may be duplicated and * themselves transmitted over other channels. */ -pub enum Chan { +pub enum Chan { Chan_(port_id) } @@ -120,7 +120,7 @@ pub fn listen(f: fn(Chan) -> U) -> U { f(po.chan()) } -struct PortPtr { +struct PortPtr { po: *rust_port, drop { unsafe { @@ -238,7 +238,7 @@ fn peek_chan(ch: Chan) -> bool { } /// Receive on a raw port pointer -fn recv_(p: *rust_port) -> T { +fn recv_(p: *rust_port) -> T { unsafe { let yield = 0; let yieldp = ptr::addr_of(&yield); diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index 9142c11360a0d..20a2cadaa2bd5 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -148,7 +148,7 @@ type Buffer = { #[cfg(stage1)] #[cfg(stage2)] #[cfg(stage3)] -pub struct Buffer { +pub struct Buffer { header: BufferHeader, data: T, } @@ -209,10 +209,18 @@ impl PacketHeader { } #[doc(hidden)] +#[cfg(stage0)] pub struct Packet { header: PacketHeader, mut payload: Option, } +#[doc(hidden)] +#[cfg(stage1)] +#[cfg(stage2)] +pub struct Packet { + header: PacketHeader, + mut payload: Option, +} #[doc(hidden)] pub trait HasBuffer { @@ -253,12 +261,11 @@ fn unibuffer() -> ~Buffer> { } move b } - #[doc(hidden)] #[cfg(stage1)] #[cfg(stage2)] #[cfg(stage3)] -fn unibuffer() -> ~Buffer> { +fn unibuffer() -> ~Buffer> { let b = ~Buffer { header: BufferHeader(), data: Packet { @@ -274,6 +281,7 @@ fn unibuffer() -> ~Buffer> { } #[doc(hidden)] +#[cfg(stage0)] pub fn packet() -> *Packet { let b = unibuffer(); let p = ptr::addr_of(&(b.data)); @@ -281,6 +289,16 @@ pub fn packet() -> *Packet { unsafe { forget(move b) } p } +#[doc(hidden)] +#[cfg(stage1)] +#[cfg(stage2)] +pub fn packet() -> *Packet { + let b = unibuffer(); + let p = ptr::addr_of(&(b.data)); + // We'll take over memory management from here. + unsafe { forget(move b) } + p +} #[doc(hidden)] pub fn entangle_buffer( @@ -384,11 +402,19 @@ fn swap_state_rel(dst: &mut State, src: State) -> State { } #[doc(hidden)] +#[cfg(stage0)] pub unsafe fn get_buffer(p: *PacketHeader) -> ~Buffer { transmute((*p).buf_header()) } +#[doc(hidden)] +#[cfg(stage1)] +#[cfg(stage2)] +pub unsafe fn get_buffer(p: *PacketHeader) -> ~Buffer { + transmute((*p).buf_header()) +} // This could probably be done with SharedMutableState to avoid move_it!(). +#[cfg(stage0)] struct BufferResource { buffer: ~Buffer, @@ -410,7 +436,31 @@ struct BufferResource { } } } +#[cfg(stage1)] +#[cfg(stage2)] +struct BufferResource { + buffer: ~Buffer, + drop { + unsafe { + let b = move_it!(self.buffer); + //let p = ptr::addr_of(*b); + //error!("drop %?", p); + let old_count = atomic_sub_rel(&mut b.header.ref_count, 1); + //let old_count = atomic_xchng_rel(b.header.ref_count, 0); + if old_count == 1 { + // The new count is 0. + + // go go gadget drop glue + } + else { + forget(move b) + } + } + } +} + +#[cfg(stage0)] fn BufferResource(b: ~Buffer) -> BufferResource { //let p = ptr::addr_of(*b); //error!("take %?", p); @@ -421,8 +471,21 @@ fn BufferResource(b: ~Buffer) -> BufferResource { buffer: move b } } +#[cfg(stage1)] +#[cfg(stage2)] +fn BufferResource(b: ~Buffer) -> BufferResource { + //let p = ptr::addr_of(*b); + //error!("take %?", p); + atomic_add_acq(&mut b.header.ref_count, 1); + + BufferResource { + // tjc: ???? + buffer: move b + } +} #[doc(hidden)] +#[cfg(stage0)] pub fn send(p: SendPacketBuffered, payload: T) -> bool { let header = p.header(); @@ -464,6 +527,49 @@ pub fn send(p: SendPacketBuffered, } } } +#[doc(hidden)] +#[cfg(stage1)] +#[cfg(stage2)] +pub fn send(p: SendPacketBuffered, payload: T) -> bool { + let header = p.header(); + let p_ = p.unwrap(); + let p = unsafe { &*p_ }; + assert ptr::addr_of(&(p.header)) == header; + assert p.payload.is_none(); + p.payload = move Some(move payload); + let old_state = swap_state_rel(&mut p.header.state, Full); + match old_state { + Empty => { + // Yay, fastpath. + + // The receiver will eventually clean this up. + //unsafe { forget(p); } + return true; + } + Full => fail ~"duplicate send", + Blocked => { + debug!("waking up task for %?", p_); + let old_task = swap_task(&mut p.header.blocked_task, ptr::null()); + if !old_task.is_null() { + unsafe { + rustrt::task_signal_event( + old_task, + ptr::addr_of(&(p.header)) as *libc::c_void); + rustrt::rust_task_deref(old_task); + } + } + + // The receiver will eventually clean this up. + //unsafe { forget(p); } + return true; + } + Terminated => { + // The receiver will never receive this. Rely on drop_glue + // to clean everything up. + return false; + } + } +} /** Receives a message from a pipe. @@ -809,13 +915,24 @@ pub fn select(endpoints: ~[RecvPacketBuffered]) message. */ +#[cfg(stage0)] pub type SendPacket = SendPacketBuffered>; +#[cfg(stage1)] +#[cfg(stage2)] +pub type SendPacket = SendPacketBuffered>; #[doc(hidden)] +#[cfg(stage0)] pub fn SendPacket(p: *Packet) -> SendPacket { SendPacketBuffered(p) } +#[cfg(stage1)] +#[cfg(stage2)] +pub fn SendPacket(p: *Packet) -> SendPacket { + SendPacketBuffered(p) +} +#[cfg(stage0)] pub struct SendPacketBuffered { mut p: Option<*Packet>, mut buffer: Option>, @@ -834,7 +951,31 @@ pub struct SendPacketBuffered { // } else { "some" }); } } } +#[cfg(stage1)] +#[cfg(stage2)] +pub struct SendPacketBuffered { + mut p: Option<*Packet>, + mut buffer: Option>, +} +impl SendPacketBuffered : ::ops::Drop { + fn finalize(&self) { + //if self.p != none { + // debug!("drop send %?", option::get(self.p)); + //} + if self.p != None { + let mut p = None; + p <-> self.p; + sender_terminate(option::unwrap(move p)) + } + //unsafe { error!("send_drop: %?", + // if self.buffer == none { + // "none" + // } else { "some" }); } + } +} + +#[cfg(stage0)] pub fn SendPacketBuffered(p: *Packet) -> SendPacketBuffered { //debug!("take send %?", p); @@ -846,8 +987,50 @@ pub fn SendPacketBuffered(p: *Packet) } } } +#[cfg(stage1)] +#[cfg(stage2)] +pub fn SendPacketBuffered(p: *Packet) + -> SendPacketBuffered { + //debug!("take send %?", p); + SendPacketBuffered { + p: Some(p), + buffer: unsafe { + Some(BufferResource( + get_buffer(ptr::addr_of(&((*p).header))))) + } + } +} + +#[cfg(stage0)] +impl SendPacketBuffered { + fn unwrap() -> *Packet { + let mut p = None; + p <-> self.p; + option::unwrap(move p) + } + + pure fn header() -> *PacketHeader { + match self.p { + Some(packet) => unsafe { + let packet = &*packet; + let header = ptr::addr_of(&(packet.header)); + //forget(packet); + header + }, + None => fail ~"packet already consumed" + } + } -impl SendPacketBuffered { + fn reuse_buffer() -> BufferResource { + //error!("send reuse_buffer"); + let mut tmp = None; + tmp <-> self.buffer; + option::unwrap(move tmp) + } +} +#[cfg(stage1)] +#[cfg(stage2)] +impl SendPacketBuffered { fn unwrap() -> *Packet { let mut p = None; p <-> self.p; @@ -876,13 +1059,25 @@ impl SendPacketBuffered { /// Represents the receive end of a pipe. It can receive exactly one /// message. +#[cfg(stage0)] pub type RecvPacket = RecvPacketBuffered>; +#[cfg(stage1)] +#[cfg(stage2)] +pub type RecvPacket = RecvPacketBuffered>; #[doc(hidden)] +#[cfg(stage0)] pub fn RecvPacket(p: *Packet) -> RecvPacket { RecvPacketBuffered(p) } +#[doc(hidden)] +#[cfg(stage1)] +#[cfg(stage2)] +pub fn RecvPacket(p: *Packet) -> RecvPacket { + RecvPacketBuffered(p) +} +#[cfg(stage0)] pub struct RecvPacketBuffered { mut p: Option<*Packet>, mut buffer: Option>, @@ -901,6 +1096,29 @@ pub struct RecvPacketBuffered { // } else { "some" }); } } } +#[cfg(stage1)] +#[cfg(stage2)] +pub struct RecvPacketBuffered { + mut p: Option<*Packet>, + mut buffer: Option>, +} + +impl RecvPacketBuffered : ::ops::Drop { + fn finalize(&self) { + //if self.p != none { + // debug!("drop recv %?", option::get(self.p)); + //} + if self.p != None { + let mut p = None; + p <-> self.p; + receiver_terminate(option::unwrap(move p)) + } + //unsafe { error!("recv_drop: %?", + // if self.buffer == none { + // "none" + // } else { "some" }); } + } +} impl RecvPacketBuffered { fn unwrap() -> *Packet { @@ -931,6 +1149,7 @@ impl RecvPacketBuffered : Selectable { } } +#[cfg(stage0)] pub fn RecvPacketBuffered(p: *Packet) -> RecvPacketBuffered { //debug!("take recv %?", p); @@ -942,12 +1161,33 @@ pub fn RecvPacketBuffered(p: *Packet) } } } +#[cfg(stage1)] +#[cfg(stage2)] +pub fn RecvPacketBuffered(p: *Packet) + -> RecvPacketBuffered { + //debug!("take recv %?", p); + RecvPacketBuffered { + p: Some(p), + buffer: unsafe { + Some(BufferResource( + get_buffer(ptr::addr_of(&((*p).header))))) + } + } +} #[doc(hidden)] +#[cfg(stage0)] pub fn entangle() -> (SendPacket, RecvPacket) { let p = packet(); (SendPacket(p), RecvPacket(p)) } +#[doc(hidden)] +#[cfg(stage1)] +#[cfg(stage2)] +pub fn entangle() -> (SendPacket, RecvPacket) { + let p = packet(); + (SendPacket(p), RecvPacket(p)) +} /** Spawn a task to provide a service. @@ -1039,24 +1279,50 @@ pub trait Peekable { } #[doc(hidden)] +#[cfg(stage0)] struct Chan_ { - mut endp: Option>, + mut endp: Option> +} +#[doc(hidden)] +#[cfg(stage1)] +#[cfg(stage2)] +struct Chan_ { + mut endp: Option> } /// An endpoint that can send many messages. +#[cfg(stage0)] pub enum Chan { Chan_(Chan_) } +#[cfg(stage1)] +#[cfg(stage2)] +pub enum Chan { + Chan_(Chan_) +} #[doc(hidden)] +#[cfg(stage0)] struct Port_ { mut endp: Option>, } +#[doc(hidden)] +#[cfg(stage1)] +#[cfg(stage2)] +struct Port_ { + mut endp: Option>, +} /// An endpoint that can receive many messages. +#[cfg(stage0)] pub enum Port { Port_(Port_) } +#[cfg(stage1)] +#[cfg(stage2)] +pub enum Port { + Port_(Port_) +} /** Creates a `(chan, port)` pair. @@ -1142,9 +1408,15 @@ impl Port: Selectable { } /// Treat many ports as one. +#[cfg(stage0)] pub struct PortSet { mut ports: ~[pipes::Port], } +#[cfg(stage1)] +#[cfg(stage2)] +pub struct PortSet { + mut ports: ~[pipes::Port], +} pub fn PortSet() -> PortSet{ PortSet { @@ -1207,7 +1479,11 @@ impl PortSet : Peekable { } /// A channel that can be shared between many senders. +#[cfg(stage0)] pub type SharedChan = private::Exclusive>; +#[cfg(stage1)] +#[cfg(stage2)] +pub type SharedChan = private::Exclusive>; impl SharedChan: GenericChan { fn send(x: T) { @@ -1275,9 +1551,17 @@ proto! oneshot ( ) /// The send end of a oneshot pipe. +#[cfg(stage0)] pub type ChanOne = oneshot::client::Oneshot; +#[cfg(stage1)] +#[cfg(stage2)] +pub type ChanOne = oneshot::client::Oneshot; /// The receive end of a oneshot pipe. +#[cfg(stage0)] pub type PortOne = oneshot::server::Oneshot; +#[cfg(stage1)] +#[cfg(stage2)] +pub type PortOne = oneshot::server::Oneshot; /// Initialiase a (send-endpoint, recv-endpoint) oneshot pipe pair. pub fn oneshot() -> (PortOne, ChanOne) { diff --git a/src/libcore/private.rs b/src/libcore/private.rs index 332c763f151e8..b6ac711d7649c 100644 --- a/src/libcore/private.rs +++ b/src/libcore/private.rs @@ -238,7 +238,7 @@ pub unsafe fn unwrap_shared_mutable_state(rc: SharedMutableState) * Data races between tasks can result in crashes and, with sufficient * cleverness, arbitrary type coercion. */ -pub type SharedMutableState = ArcDestruct; +pub type SharedMutableState = ArcDestruct; pub unsafe fn shared_mutable_state(data: T) -> SharedMutableState { @@ -341,11 +341,11 @@ impl LittleLock { } } -struct ExData { lock: LittleLock, mut failed: bool, mut data: T, } +struct ExData { lock: LittleLock, mut failed: bool, mut data: T, } /** * An arc over mutable data that is protected by a lock. For library use only. */ -pub struct Exclusive { x: SharedMutableState> } +pub struct Exclusive { x: SharedMutableState> } pub fn exclusive(user_data: T) -> Exclusive { let data = ExData { diff --git a/src/libcore/private/global.rs b/src/libcore/private/global.rs index 69319abc00930..ee20fb665bea6 100644 --- a/src/libcore/private/global.rs +++ b/src/libcore/private/global.rs @@ -41,7 +41,7 @@ use sys::Closure; use task::spawn; use uint; -pub type GlobalDataKey = &fn(v: T); +pub type GlobalDataKey = &fn(v: T); pub unsafe fn global_data_clone_create( key: GlobalDataKey, create: &fn() -> ~T) -> T { diff --git a/src/libcore/reflect.rs b/src/libcore/reflect.rs index 55eb53bc0266a..81a36e1ae13ee 100644 --- a/src/libcore/reflect.rs +++ b/src/libcore/reflect.rs @@ -41,7 +41,7 @@ pub fn align(size: uint, align: uint) -> uint { } /// Adaptor to wrap around visitors implementing MovePtr. -pub struct MovePtrAdaptor { +pub struct MovePtrAdaptor { inner: V } pub fn MovePtrAdaptor(v: V) -> MovePtrAdaptor { diff --git a/src/libcore/task/local_data.rs b/src/libcore/task/local_data.rs index 05a4e35b249e4..42765ef139ff5 100644 --- a/src/libcore/task/local_data.rs +++ b/src/libcore/task/local_data.rs @@ -45,7 +45,7 @@ use task; * * These two cases aside, the interface is safe. */ -pub type LocalDataKey = &fn(v: @T); +pub type LocalDataKey = &fn(v: @T); /** * Remove a task-local data value from the table, returning the diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs index 0a2f6634214e6..3db6fa00f16dd 100644 --- a/src/libcore/task/spawn.rs +++ b/src/libcore/task/spawn.rs @@ -77,7 +77,7 @@ use cast; use container::Map; use oldcomm; use option; -use pipes::{Chan, GenericChan, GenericPort, Port}; +use pipes::{Chan, GenericChan, GenericPort, Port, stream}; use pipes; use prelude::*; use private; diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 8f1873f628f05..1bdaa984914db 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -568,7 +568,7 @@ struct FnSig { * by the meta information because, in some cases, the * meta information is inferred. */ #[deriving_eq] -struct FnTyBase { +struct FnTyBase { meta: M, // Either FnMeta or FnVid sig: FnSig // Types of arguments/return type } diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index ce0c7a94c7cc0..8374a65f63c30 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -598,6 +598,20 @@ fn convert_methods(ccx: @crate_ctxt, } } +fn ensure_no_ty_param_bounds(ccx: @crate_ctxt, + span: span, + ty_params: &[ast::ty_param], + thing: &static/str) { + for ty_params.each |ty_param| { + if ty_param.bounds.len() > 0 { + ccx.tcx.sess.span_err( + span, + fmt!("trait bounds are not allowed in %s definitions", + thing)); + } + } +} + fn convert(ccx: @crate_ctxt, it: @ast::item) { let tcx = ccx.tcx; let rp = tcx.region_paramd_items.find(it.id); @@ -607,6 +621,7 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) { // These don't define types. ast::item_foreign_mod(_) | ast::item_mod(_) => {} ast::item_enum(ref enum_definition, ref ty_params) => { + ensure_no_ty_param_bounds(ccx, it.span, *ty_params, "enumeration"); let tpt = ty_of_item(ccx, it); write_ty_to_tcx(tcx, it.id, tpt.ty); get_enum_variant_types(ccx, @@ -644,6 +659,8 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) { let _ = convert_methods(ccx, provided_methods, rp, bounds); } ast::item_struct(struct_def, tps) => { + ensure_no_ty_param_bounds(ccx, it.span, tps, "structure"); + // Write the class type let tpt = ty_of_item(ccx, it); write_ty_to_tcx(tcx, it.id, tpt.ty); @@ -651,6 +668,11 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) { convert_struct(ccx, rp, struct_def, tps, tpt, it.id); } + ast::item_ty(_, ref ty_params) => { + ensure_no_ty_param_bounds(ccx, it.span, *ty_params, "type"); + let tpt = ty_of_item(ccx, it); + write_ty_to_tcx(tcx, it.id, tpt.ty); + } _ => { // This call populates the type cache with the converted type // of the item in passing. All we have to do here is to write diff --git a/src/librustc/middle/typeck/infer/unify.rs b/src/librustc/middle/typeck/infer/unify.rs index 6c831427b031e..b2b1188388f45 100644 --- a/src/librustc/middle/typeck/infer/unify.rs +++ b/src/librustc/middle/typeck/infer/unify.rs @@ -31,7 +31,7 @@ struct ValsAndBindings { mut bindings: ~[(V, VarValue)], } -struct Node { +struct Node { root: V, possible_types: T, rank: uint, diff --git a/src/libstd/arc.rs b/src/libstd/arc.rs index 0c40fe283af0b..edffa32e501ee 100644 --- a/src/libstd/arc.rs +++ b/src/libstd/arc.rs @@ -79,7 +79,7 @@ impl &Condvar { ****************************************************************************/ /// An atomically reference counted wrapper for shared immutable state. -struct ARC { x: SharedMutableState } +struct ARC { x: SharedMutableState } /// Create an atomically reference counted wrapper. pub fn ARC(data: T) -> ARC { @@ -130,9 +130,9 @@ impl ARC: Clone { ****************************************************************************/ #[doc(hidden)] -struct MutexARCInner { lock: Mutex, failed: bool, data: T } +struct MutexARCInner { lock: Mutex, failed: bool, data: T } /// An ARC with mutable data protected by a blocking mutex. -struct MutexARC { x: SharedMutableState> } +struct MutexARC { x: SharedMutableState> } /// Create a mutex-protected ARC with the supplied data. pub fn MutexARC(user_data: T) -> MutexARC { @@ -267,14 +267,14 @@ fn PoisonOnFail(failed: &r/mut bool) -> PoisonOnFail { ****************************************************************************/ #[doc(hidden)] -struct RWARCInner { lock: RWlock, failed: bool, data: T } +struct RWARCInner { lock: RWlock, failed: bool, data: T } /** * A dual-mode ARC protected by a reader-writer lock. The data can be accessed * mutably or immutably, and immutably-accessing tasks may run concurrently. * * Unlike mutex_arcs, rw_arcs are safe, because they cannot be nested. */ -struct RWARC { +struct RWARC { x: SharedMutableState>, mut cant_nest: () } @@ -426,10 +426,10 @@ fn borrow_rwlock(state: &r/mut RWARCInner) -> &r/RWlock { // FIXME (#3154) ice with struct/& prevents these from being structs. /// The "write permission" token used for RWARC.write_downgrade(). -pub enum RWWriteMode = +pub enum RWWriteMode = (&mut T, sync::RWlockWriteMode, PoisonOnFail); /// The "read permission" token used for RWARC.write_downgrade(). -pub enum RWReadMode = (&T, sync::RWlockReadMode); +pub enum RWReadMode = (&T, sync::RWlockReadMode); impl &RWWriteMode { /// Access the pre-downgrade RWARC in write mode. diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs index 3118a0c1ba545..16e8b63da8174 100644 --- a/src/libstd/comm.rs +++ b/src/libstd/comm.rs @@ -23,7 +23,14 @@ use core::pipes; use core::prelude::*; /// An extension of `pipes::stream` that allows both sending and receiving. -pub struct DuplexStream { +#[cfg(stage0)] +pub struct DuplexStream { + priv chan: Chan, + priv port: Port, +} +#[cfg(stage1)] +#[cfg(stage2)] +pub struct DuplexStream { priv chan: Chan, priv port: Port, } diff --git a/src/libstd/flatpipes.rs b/src/libstd/flatpipes.rs index afc3e72e636cb..bd684baf6b300 100644 --- a/src/libstd/flatpipes.rs +++ b/src/libstd/flatpipes.rs @@ -63,7 +63,7 @@ and an `Unflattener` that converts the bytes to a value. Create using the constructors in the `serial` and `pod` modules. */ -pub struct FlatPort, P: BytePort> { +pub struct FlatPort { unflattener: U, byte_port: P } @@ -74,7 +74,7 @@ byte vectors, and a `ByteChan` that transmits the bytes. Create using the constructors in the `serial` and `pod` modules. */ -pub struct FlatChan, C: ByteChan> { +pub struct FlatChan { flattener: F, byte_chan: C } @@ -181,14 +181,12 @@ pub mod pod { use core::pipes; use core::prelude::*; - pub type ReaderPort = + pub type ReaderPort = FlatPort, ReaderBytePort>; - pub type WriterChan = + pub type WriterChan = FlatChan, WriterByteChan>; - pub type PipePort = - FlatPort, PipeBytePort>; - pub type PipeChan = - FlatChan, PipeByteChan>; + pub type PipePort = FlatPort, PipeBytePort>; + pub type PipeChan = FlatChan, PipeByteChan>; /// Create a `FlatPort` from a `Reader` pub fn reader_port( @@ -352,11 +350,11 @@ pub mod flatteners { // FIXME #4074: Copy + Owned != POD - pub struct PodUnflattener { + pub struct PodUnflattener { bogus: () } - pub struct PodFlattener { + pub struct PodFlattener { bogus: () } @@ -398,14 +396,13 @@ pub mod flatteners { pub type DeserializeBuffer = ~fn(buf: &[u8]) -> T; - pub struct DeserializingUnflattener> { + pub struct DeserializingUnflattener { deserialize_buffer: DeserializeBuffer } pub type SerializeValue = ~fn(val: &T) -> ~[u8]; - pub struct SerializingFlattener> { + pub struct SerializingFlattener { serialize_value: SerializeValue } @@ -518,11 +515,11 @@ pub mod bytepipes { use core::pipes; use core::prelude::*; - pub struct ReaderBytePort { + pub struct ReaderBytePort { reader: R } - pub struct WriterByteChan { + pub struct WriterByteChan { writer: W } @@ -767,9 +764,9 @@ mod test { test_some_tcp_stream(reader_port, writer_chan, 9667); } - type ReaderPortFactory> = + type ReaderPortFactory = ~fn(TcpSocketBuf) -> FlatPort>; - type WriterChanFactory> = + type WriterChanFactory = ~fn(TcpSocketBuf) -> FlatChan>; fn test_some_tcp_stream, F: Flattener>( @@ -893,7 +890,7 @@ mod test { use core::sys; use core::task; - type PortLoader = + type PortLoader

= ~fn(~[u8]) -> FlatPort, P>; fn reader_port_loader(bytes: ~[u8] diff --git a/src/libstd/map.rs b/src/libstd/map.rs index f3016e9df21a8..2fa2825eb4cd7 100644 --- a/src/libstd/map.rs +++ b/src/libstd/map.rs @@ -24,9 +24,9 @@ use core::uint; use core::vec; /// A convenience type to treat a hashmap as a set -pub type Set = HashMap; +pub type Set = HashMap; -pub type HashMap = chained::T; +pub type HashMap = chained::T; pub trait StdMap { /// Return the number of elements in the map @@ -142,12 +142,12 @@ pub mod chained { mut next: Option<@Entry> } - struct HashMap_ { + struct HashMap_ { mut count: uint, mut chains: ~[mut Option<@Entry>] } - pub type T = @HashMap_; + pub type T = @HashMap_; enum SearchResult { NotFound, diff --git a/src/libstd/priority_queue.rs b/src/libstd/priority_queue.rs index 01b62797a8d76..59ba9ad61540d 100644 --- a/src/libstd/priority_queue.rs +++ b/src/libstd/priority_queue.rs @@ -22,7 +22,7 @@ extern "C" mod rusti { fn init() -> T; } -pub struct PriorityQueue { +pub struct PriorityQueue { priv data: ~[T], } diff --git a/src/libstd/sync.rs b/src/libstd/sync.rs index 03ef98d09c5c0..6ded82d5ae4c4 100644 --- a/src/libstd/sync.rs +++ b/src/libstd/sync.rs @@ -83,7 +83,7 @@ struct SemInner { blocked: Q } #[doc(hidden)] -enum Sem = Exclusive>; +enum Sem = Exclusive>; #[doc(hidden)] fn new_sem(count: int, q: Q) -> Sem { @@ -167,7 +167,7 @@ impl &Sem<~[mut Waitqueue]> { #[doc(hidden)] type SemRelease = SemReleaseGeneric<()>; type SemAndSignalRelease = SemReleaseGeneric<~[mut Waitqueue]>; -struct SemReleaseGeneric { sem: &Sem } +struct SemReleaseGeneric { sem: &Sem } impl SemReleaseGeneric : Drop { fn finalize(&self) { diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index 36d919494f13d..5d0c83859f0a5 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -39,7 +39,7 @@ use core::prelude::*; // * symmetric difference: ^ // These would be convenient since the methods work like `each` -pub struct TreeMap { +pub struct TreeMap { priv root: Option<~TreeNode>, priv length: uint } @@ -167,7 +167,7 @@ impl TreeMap { } /// Lazy forward iterator over a map -pub struct TreeMapIterator { +pub struct TreeMapIterator { priv stack: ~[&~TreeNode], priv node: &Option<~TreeNode>, priv current: Option<&~TreeNode> @@ -205,7 +205,7 @@ impl TreeMapIterator { } } -pub struct TreeSet { +pub struct TreeSet { priv map: TreeMap } @@ -472,7 +472,7 @@ impl TreeSet { } /// Lazy forward iterator over a set -pub struct TreeSetIterator { +pub struct TreeSetIterator { priv iter: TreeMapIterator } @@ -494,7 +494,7 @@ impl TreeSetIterator { // Nodes keep track of their level in the tree, starting at 1 in the // leaves and with a red child sharing the level of the parent. -struct TreeNode { +struct TreeNode { key: K, value: V, left: Option<~TreeNode>, diff --git a/src/libstd/workcache.rs b/src/libstd/workcache.rs index fbd695aee762c..79a22f34d31f9 100644 --- a/src/libstd/workcache.rs +++ b/src/libstd/workcache.rs @@ -223,10 +223,17 @@ struct Exec { discovered_outputs: WorkMap } +#[cfg(stage0)] struct Work { prep: @Mut, res: Option>> } +#[cfg(stage1)] +#[cfg(stage2)] +struct Work { + prep: @Mut, + res: Option>> +} fn json_encode>(t: &T) -> ~str { do io::with_str_writer |wr| { diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs index 8a5b8a127d035..0433aab51fc3e 100644 --- a/src/libsyntax/ext/pipes/ast_builder.rs +++ b/src/libsyntax/ext/pipes/ast_builder.rs @@ -110,6 +110,7 @@ pub trait ext_ctxt_ast_builder { fn ty_option(ty: @ast::Ty) -> @ast::Ty; fn ty_infer() -> @ast::Ty; fn ty_nil_ast_builder() -> @ast::Ty; + fn strip_bounds(bounds: &[ast::ty_param]) -> ~[ast::ty_param]; } impl ext_ctxt: ext_ctxt_ast_builder { @@ -370,6 +371,12 @@ impl ext_ctxt: ext_ctxt_ast_builder { } } + fn strip_bounds(bounds: &[ast::ty_param]) -> ~[ast::ty_param] { + do bounds.map |ty_param| { + ast::ty_param { bounds: @~[], ..copy *ty_param } + } + } + fn item_ty_poly(name: ident, span: span, ty: @ast::Ty, diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index 774a559625828..e7a8cbb9891f8 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -248,7 +248,7 @@ impl state: to_type_decls { ast::enum_def(enum_def_ { variants: items_msg, common: None }), - self.ty_params + cx.strip_bounds(self.ty_params) ) ] } @@ -281,7 +281,7 @@ impl state: to_type_decls { self.data_name()], dummy_sp()) .add_tys(cx.ty_vars_global(self.ty_params))))), - self.ty_params)); + cx.strip_bounds(self.ty_params))); } else { items.push( @@ -299,7 +299,7 @@ impl state: to_type_decls { dummy_sp()) .add_tys(cx.ty_vars_global(self.ty_params))), self.proto.buffer_ty_path(cx)])), - self.ty_params)); + cx.strip_bounds(self.ty_params))); }; items } @@ -417,7 +417,7 @@ impl protocol: gen_init { cx.ident_of(~"__Buffer"), dummy_sp(), cx.ty_rec(fields), - params) + cx.strip_bounds(params)) } fn compile(cx: ext_ctxt) -> @ast::item { diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 67f6c4bed3f95..86dea693f8af6 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -33,6 +33,7 @@ use core::str; use core::to_bytes; /// The specific types of unsupported syntax +#[deriving_eq] pub enum ObsoleteSyntax { ObsoleteLowerCaseKindBounds, ObsoleteLet, @@ -45,16 +46,8 @@ pub enum ObsoleteSyntax { ObsoleteModeInFnType, ObsoleteMoveInit, ObsoleteBinaryMove, - ObsoleteUnsafeBlock -} - -impl ObsoleteSyntax : cmp::Eq { - pure fn eq(&self, other: &ObsoleteSyntax) -> bool { - (*self) as uint == (*other) as uint - } - pure fn ne(&self, other: &ObsoleteSyntax) -> bool { - !(*self).eq(other) - } + ObsoleteUnsafeBlock, + ObsoleteUnenforcedBound } impl ObsoleteSyntax: to_bytes::IterBytes { @@ -123,6 +116,11 @@ impl Parser { ObsoleteUnsafeBlock => ( "non-standalone unsafe block", "use an inner `unsafe { ... }` block instead" + ), + ObsoleteUnenforcedBound => ( + "unenforced type parameter bound", + "use trait bounds on the functions that take the type as \ + arguments, not on the types themselves" ) }; diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index e4a09c3c349b8..9de875485db53 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -18,7 +18,7 @@ use core::dvec::DVec; use std::map::HashMap; use std::map; -type hash_interner = +type hash_interner = {map: HashMap, vect: DVec}; diff --git a/src/test/auxiliary/issue-2526.rs b/src/test/auxiliary/issue-2526.rs index a14cc3758b19b..fc5cf1275183b 100644 --- a/src/test/auxiliary/issue-2526.rs +++ b/src/test/auxiliary/issue-2526.rs @@ -17,7 +17,7 @@ extern mod std; export context; -struct arc_destruct { +struct arc_destruct { _data: int, } diff --git a/src/test/auxiliary/test_comm.rs b/src/test/auxiliary/test_comm.rs index af321b9959f2b..6fd39368baecd 100644 --- a/src/test/auxiliary/test_comm.rs +++ b/src/test/auxiliary/test_comm.rs @@ -24,7 +24,7 @@ use core::libc::size_t; * transmitted. If a port value is copied, both copies refer to the same * port. Ports may be associated with multiple `chan`s. */ -pub enum port { +pub enum port { port_t(@port_ptr) } @@ -35,7 +35,7 @@ pub fn port() -> port { } } -struct port_ptr { +struct port_ptr { po: *rust_port, } diff --git a/src/test/bench/task-perf-word-count-generic.rs b/src/test/bench/task-perf-word-count-generic.rs index a817414314600..b617f6acec6e5 100644 --- a/src/test/bench/task-perf-word-count-generic.rs +++ b/src/test/bench/task-perf-word-count-generic.rs @@ -120,15 +120,15 @@ mod map_reduce { use std::map::HashMap; use std::map; - pub type putter = fn(&K, V); + pub type putter = fn(&K, V); - pub type mapper = fn~(K1, putter); + pub type mapper = fn~(K1, putter); - pub type getter = fn() -> Option; + pub type getter = fn() -> Option; - pub type reducer = fn~(&K, getter); + pub type reducer = fn~(&K, getter); - enum ctrl_proto { + enum ctrl_proto { find_reducer(K, Chan>>), mapper_done } @@ -146,7 +146,7 @@ mod map_reduce { } ) - pub enum reduce_proto { + pub enum reduce_proto { emit_val(V), done, addref, diff --git a/src/test/compile-fail/issue-2718-a.rs b/src/test/compile-fail/issue-2718-a.rs index 2332d54037fbd..925350d9b8804 100644 --- a/src/test/compile-fail/issue-2718-a.rs +++ b/src/test/compile-fail/issue-2718-a.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub struct send_packet { +pub struct send_packet { p: T } diff --git a/src/test/run-fail/bug-811.rs b/src/test/run-fail/bug-811.rs index 739bf097d4fda..31158df4185f7 100644 --- a/src/test/run-fail/bug-811.rs +++ b/src/test/run-fail/bug-811.rs @@ -14,7 +14,7 @@ fn test00_start(ch: chan_t, message: int) { send(ch, message); } type task_id = int; type port_id = int; -enum chan_t = {task: task_id, port: port_id}; +enum chan_t = {task: task_id, port: port_id}; fn send(ch: chan_t, data: T) { fail; } diff --git a/src/test/run-fail/issue-2444.rs b/src/test/run-fail/issue-2444.rs index b1d8c99faa519..9172364a2f916 100644 --- a/src/test/run-fail/issue-2444.rs +++ b/src/test/run-fail/issue-2444.rs @@ -13,7 +13,7 @@ extern mod std; use std::arc; -enum e { e(arc::ARC) } +enum e { e(arc::ARC) } fn foo() -> e {fail;} diff --git a/src/test/run-pass/auto-encode.rs b/src/test/run-pass/auto-encode.rs index ec73704ca27ba..ee8cf89d528a5 100644 --- a/src/test/run-pass/auto-encode.rs +++ b/src/test/run-pass/auto-encode.rs @@ -135,11 +135,6 @@ struct Spanned { node: T, } -enum AnEnum { - AVariant, - AnotherVariant -} - #[auto_encode] #[auto_decode] struct SomeStruct { v: ~[uint] } diff --git a/src/test/run-pass/box-unbox.rs b/src/test/run-pass/box-unbox.rs index 3558501471318..ad32ffc75c9c1 100644 --- a/src/test/run-pass/box-unbox.rs +++ b/src/test/run-pass/box-unbox.rs @@ -10,7 +10,7 @@ -struct Box {c: @T} +struct Box {c: @T} fn unbox(b: Box) -> T { return *b.c; } diff --git a/src/test/run-pass/class-impl-very-parameterized-trait.rs b/src/test/run-pass/class-impl-very-parameterized-trait.rs index 6bc881884522a..bccb42c493892 100644 --- a/src/test/run-pass/class-impl-very-parameterized-trait.rs +++ b/src/test/run-pass/class-impl-very-parameterized-trait.rs @@ -27,7 +27,7 @@ impl cat_type : cmp::Eq { // for any int value that's less than the meows field // ok: T should be in scope when resolving the trait ref for map -struct cat { +struct cat { // Yes, you can have negative meows priv mut meows : int, diff --git a/src/test/run-pass/generic-exterior-box.rs b/src/test/run-pass/generic-exterior-box.rs index 738bb73b0be4f..c2abcc7528300 100644 --- a/src/test/run-pass/generic-exterior-box.rs +++ b/src/test/run-pass/generic-exterior-box.rs @@ -10,7 +10,7 @@ -struct Recbox {x: @T} +struct Recbox {x: @T} fn reclift(t: T) -> Recbox { return Recbox {x: @t}; } diff --git a/src/test/run-pass/generic-exterior-unique.rs b/src/test/run-pass/generic-exterior-unique.rs index 2095578aefad8..a4a576abc758c 100644 --- a/src/test/run-pass/generic-exterior-unique.rs +++ b/src/test/run-pass/generic-exterior-unique.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct Recbox {x: ~T} +struct Recbox {x: ~T} fn reclift(t: T) -> Recbox { return Recbox {x: ~t}; } diff --git a/src/test/run-pass/issue-2288.rs b/src/test/run-pass/issue-2288.rs index 52b3baba58e36..0fa06e2f2129b 100644 --- a/src/test/run-pass/issue-2288.rs +++ b/src/test/run-pass/issue-2288.rs @@ -11,7 +11,7 @@ trait clam { fn chowder(y: A); } -struct foo { +struct foo { x: A, } diff --git a/src/test/run-pass/issue-2311-2.rs b/src/test/run-pass/issue-2311-2.rs index 10befa7422836..21201d0a95705 100644 --- a/src/test/run-pass/issue-2311-2.rs +++ b/src/test/run-pass/issue-2311-2.rs @@ -9,7 +9,7 @@ // except according to those terms. trait clam { } -struct foo { +struct foo { x: A, } diff --git a/src/test/run-pass/issue-2445-b.rs b/src/test/run-pass/issue-2445-b.rs index 35d3d0897098b..f1b7d45e440ec 100644 --- a/src/test/run-pass/issue-2445-b.rs +++ b/src/test/run-pass/issue-2445-b.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct c1 { +struct c1 { x: T, } diff --git a/src/test/run-pass/issue-2445.rs b/src/test/run-pass/issue-2445.rs index 7cf681c9f94ef..fada6a7b02e11 100644 --- a/src/test/run-pass/issue-2445.rs +++ b/src/test/run-pass/issue-2445.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct c1 { +struct c1 { x: T, } diff --git a/src/test/run-pass/issue-2718.rs b/src/test/run-pass/issue-2718.rs index f8f2fc461c3ff..68a318eab4e3e 100644 --- a/src/test/run-pass/issue-2718.rs +++ b/src/test/run-pass/issue-2718.rs @@ -34,7 +34,7 @@ pub mod pipes { pure fn ne(&self, other: &state) -> bool { !(*self).eq(other) } } - pub type packet = { + pub type packet = { mut state: state, mut blocked_task: Option, mut payload: Option @@ -157,7 +157,7 @@ pub mod pipes { } } - pub struct send_packet { + pub struct send_packet { mut p: Option<*packet>, } @@ -185,7 +185,7 @@ pub mod pipes { } } - pub struct recv_packet { + pub struct recv_packet { mut p: Option<*packet>, } diff --git a/src/test/run-pass/issue-3149.rs b/src/test/run-pass/issue-3149.rs index 533106ff93621..c578f1144a785 100644 --- a/src/test/run-pass/issue-3149.rs +++ b/src/test/run-pass/issue-3149.rs @@ -22,7 +22,7 @@ pure fn Matrix4(m11: T, m12: T, m13: T, m14: T, } } -struct Matrix4 { +struct Matrix4 { m11: T, m12: T, m13: T, m14: T, m21: T, m22: T, m23: T, m24: T, m31: T, m32: T, m33: T, m34: T, diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs index d072df4d8e880..cf0a0a07397c0 100644 --- a/src/test/run-pass/reflect-visit-data.rs +++ b/src/test/run-pass/reflect-visit-data.rs @@ -29,7 +29,7 @@ fn align(size: uint, align: uint) -> uint { ((size + align) - 1u) & !(align - 1u) } -enum ptr_visit_adaptor = Inner; +enum ptr_visit_adaptor = Inner; impl ptr_visit_adaptor { diff --git a/src/test/run-pass/resource-generic.rs b/src/test/run-pass/resource-generic.rs index e528cd32974ba..7165d6089e85f 100644 --- a/src/test/run-pass/resource-generic.rs +++ b/src/test/run-pass/resource-generic.rs @@ -13,7 +13,7 @@ struct Arg {val: T, fin: extern fn(T)} -struct finish { +struct finish { arg: Arg } diff --git a/src/test/run-pass/send-type-inference.rs b/src/test/run-pass/send-type-inference.rs index 8476e256cd24c..8cb597a0d792c 100644 --- a/src/test/run-pass/send-type-inference.rs +++ b/src/test/run-pass/send-type-inference.rs @@ -9,7 +9,7 @@ // except according to those terms. // tests that ctrl's type gets inferred properly -type command = {key: K, val: V}; +type command = {key: K, val: V}; fn cache_server(c: oldcomm::Chan>>) { let ctrl = oldcomm::Port(); From c8e9d0694d5d9bdabfb52fd1836a8107abbfb82b Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Mon, 28 Jan 2013 18:10:34 -0800 Subject: [PATCH 3/4] librustc: De-implicit-self the visitor --- src/libcargo/cargo.rc | 1 + src/libcore/core.rc | 1 + src/libcore/reflect.rs | 440 +++++++++++++++++- src/libcore/repr.rs | 305 ++++++++++++ src/librustc/front/intrinsic.rs | 132 +++--- src/librustc/middle/lint.rs | 21 +- src/librustc/middle/trans/reflect.rs | 3 +- src/librustc/rustc.rc | 1 + src/librustdoc/rustdoc.rc | 1 + src/libstd/std.rc | 1 + src/libsyntax/syntax.rc | 1 + src/test/compile-fail/lint-default-methods.rs | 2 +- src/test/run-pass/reflect-visit-data.rs | 246 +++++----- 13 files changed, 956 insertions(+), 199 deletions(-) diff --git a/src/libcargo/cargo.rc b/src/libcargo/cargo.rc index efbb9a929d2df..c11e1ec010f3f 100644 --- a/src/libcargo/cargo.rc +++ b/src/libcargo/cargo.rc @@ -35,6 +35,7 @@ #[allow(non_camel_case_types)]; #[allow(deprecated_mode)]; #[allow(deprecated_pattern)]; +#[allow(deprecated_self)]; extern mod core(vers = "0.6"); extern mod std(vers = "0.6"); diff --git a/src/libcore/core.rc b/src/libcore/core.rc index f7a65ed1fe442..1ac0bf4c0c5c0 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -52,6 +52,7 @@ Implicitly, all crates behave as if they included the following prologue: #[warn(deprecated_pattern)]; #[warn(vecs_implicitly_copyable)]; #[deny(non_camel_case_types)]; +#[allow(deprecated_self)]; /* The Prelude. */ diff --git a/src/libcore/reflect.rs b/src/libcore/reflect.rs index 81a36e1ae13ee..94fc9e37a7519 100644 --- a/src/libcore/reflect.rs +++ b/src/libcore/reflect.rs @@ -75,6 +75,7 @@ impl MovePtrAdaptor { } /// Abstract type-directed pointer-movement using the MovePtr trait +#[cfg(stage0)] impl MovePtrAdaptor: TyVisitor { fn visit_bot() -> bool { self.align_to::<()>(); @@ -325,7 +326,8 @@ impl MovePtrAdaptor: TyVisitor { true } - fn visit_enter_class(n_fields: uint, sz: uint, align: uint) -> bool { + fn visit_enter_class(n_fields: uint, sz: uint, align: uint) + -> bool { self.align(align); if ! self.inner.visit_enter_class(n_fields, sz, align) { return false; @@ -343,7 +345,8 @@ impl MovePtrAdaptor: TyVisitor { true } - fn visit_leave_class(n_fields: uint, sz: uint, align: uint) -> bool { + fn visit_leave_class(n_fields: uint, sz: uint, align: uint) + -> bool { if ! self.inner.visit_leave_class(n_fields, sz, align) { return false; } @@ -394,7 +397,8 @@ impl MovePtrAdaptor: TyVisitor { true } - fn visit_enter_enum(n_variants: uint, sz: uint, align: uint) -> bool { + fn visit_enter_enum(n_variants: uint, sz: uint, align: uint) + -> bool { self.align(align); if ! self.inner.visit_enter_enum(n_variants, sz, align) { return false; @@ -433,7 +437,8 @@ impl MovePtrAdaptor: TyVisitor { true } - fn visit_leave_enum(n_variants: uint, sz: uint, align: uint) -> bool { + fn visit_leave_enum(n_variants: uint, sz: uint, align: uint) + -> bool { if ! self.inner.visit_leave_enum(n_variants, sz, align) { return false; } @@ -494,3 +499,430 @@ impl MovePtrAdaptor: TyVisitor { true } } + +/// Abstract type-directed pointer-movement using the MovePtr trait +#[cfg(stage1)] +#[cfg(stage2)] +impl MovePtrAdaptor: TyVisitor { + fn visit_bot(&self) -> bool { + self.align_to::<()>(); + if ! self.inner.visit_bot() { return false; } + self.bump_past::<()>(); + true + } + + fn visit_nil(&self) -> bool { + self.align_to::<()>(); + if ! self.inner.visit_nil() { return false; } + self.bump_past::<()>(); + true + } + + fn visit_bool(&self) -> bool { + self.align_to::(); + if ! self.inner.visit_bool() { return false; } + self.bump_past::(); + true + } + + fn visit_int(&self) -> bool { + self.align_to::(); + if ! self.inner.visit_int() { return false; } + self.bump_past::(); + true + } + + fn visit_i8(&self) -> bool { + self.align_to::(); + if ! self.inner.visit_i8() { return false; } + self.bump_past::(); + true + } + + fn visit_i16(&self) -> bool { + self.align_to::(); + if ! self.inner.visit_i16() { return false; } + self.bump_past::(); + true + } + + fn visit_i32(&self) -> bool { + self.align_to::(); + if ! self.inner.visit_i32() { return false; } + self.bump_past::(); + true + } + + fn visit_i64(&self) -> bool { + self.align_to::(); + if ! self.inner.visit_i64() { return false; } + self.bump_past::(); + true + } + + fn visit_uint(&self) -> bool { + self.align_to::(); + if ! self.inner.visit_uint() { return false; } + self.bump_past::(); + true + } + + fn visit_u8(&self) -> bool { + self.align_to::(); + if ! self.inner.visit_u8() { return false; } + self.bump_past::(); + true + } + + fn visit_u16(&self) -> bool { + self.align_to::(); + if ! self.inner.visit_u16() { return false; } + self.bump_past::(); + true + } + + fn visit_u32(&self) -> bool { + self.align_to::(); + if ! self.inner.visit_u32() { return false; } + self.bump_past::(); + true + } + + fn visit_u64(&self) -> bool { + self.align_to::(); + if ! self.inner.visit_u64() { return false; } + self.bump_past::(); + true + } + + fn visit_float(&self) -> bool { + self.align_to::(); + if ! self.inner.visit_float() { return false; } + self.bump_past::(); + true + } + + fn visit_f32(&self) -> bool { + self.align_to::(); + if ! self.inner.visit_f32() { return false; } + self.bump_past::(); + true + } + + fn visit_f64(&self) -> bool { + self.align_to::(); + if ! self.inner.visit_f64() { return false; } + self.bump_past::(); + true + } + + fn visit_char(&self) -> bool { + self.align_to::(); + if ! self.inner.visit_char() { return false; } + self.bump_past::(); + true + } + + fn visit_str(&self) -> bool { + self.align_to::<~str>(); + if ! self.inner.visit_str() { return false; } + self.bump_past::<~str>(); + true + } + + fn visit_estr_box(&self) -> bool { + self.align_to::<@str>(); + if ! self.inner.visit_estr_box() { return false; } + self.bump_past::<@str>(); + true + } + + fn visit_estr_uniq(&self) -> bool { + self.align_to::<~str>(); + if ! self.inner.visit_estr_uniq() { return false; } + self.bump_past::<~str>(); + true + } + + fn visit_estr_slice(&self) -> bool { + self.align_to::<&static/str>(); + if ! self.inner.visit_estr_slice() { return false; } + self.bump_past::<&static/str>(); + true + } + + fn visit_estr_fixed(&self, n: uint, + sz: uint, + align: uint) -> bool { + self.align(align); + if ! self.inner.visit_estr_fixed(n, sz, align) { return false; } + self.bump(sz); + true + } + + fn visit_box(&self, mtbl: uint, inner: *TyDesc) -> bool { + self.align_to::<@u8>(); + if ! self.inner.visit_box(mtbl, inner) { return false; } + self.bump_past::<@u8>(); + true + } + + fn visit_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool { + self.align_to::<~u8>(); + if ! self.inner.visit_uniq(mtbl, inner) { return false; } + self.bump_past::<~u8>(); + true + } + + fn visit_ptr(&self, mtbl: uint, inner: *TyDesc) -> bool { + self.align_to::<*u8>(); + if ! self.inner.visit_ptr(mtbl, inner) { return false; } + self.bump_past::<*u8>(); + true + } + + fn visit_rptr(&self, mtbl: uint, inner: *TyDesc) -> bool { + self.align_to::<&static/u8>(); + if ! self.inner.visit_rptr(mtbl, inner) { return false; } + self.bump_past::<&static/u8>(); + true + } + + fn visit_unboxed_vec(&self, mtbl: uint, inner: *TyDesc) -> bool { + self.align_to::(); + if ! self.inner.visit_vec(mtbl, inner) { return false; } + true + } + + fn visit_vec(&self, mtbl: uint, inner: *TyDesc) -> bool { + self.align_to::<~[u8]>(); + if ! self.inner.visit_vec(mtbl, inner) { return false; } + self.bump_past::<~[u8]>(); + true + } + + fn visit_evec_box(&self, mtbl: uint, inner: *TyDesc) -> bool { + self.align_to::<@[u8]>(); + if ! self.inner.visit_evec_box(mtbl, inner) { return false; } + self.bump_past::<@[u8]>(); + true + } + + fn visit_evec_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool { + self.align_to::<~[u8]>(); + if ! self.inner.visit_evec_uniq(mtbl, inner) { return false; } + self.bump_past::<~[u8]>(); + true + } + + fn visit_evec_slice(&self, mtbl: uint, inner: *TyDesc) -> bool { + self.align_to::<&static/[u8]>(); + if ! self.inner.visit_evec_slice(mtbl, inner) { return false; } + self.bump_past::<&static/[u8]>(); + true + } + + fn visit_evec_fixed(&self, n: uint, sz: uint, align: uint, + mtbl: uint, inner: *TyDesc) -> bool { + self.align(align); + if ! self.inner.visit_evec_fixed(n, sz, align, mtbl, inner) { + return false; + } + self.bump(sz); + true + } + + fn visit_enter_rec(&self, n_fields: uint, sz: uint, align: uint) -> bool { + self.align(align); + if ! self.inner.visit_enter_rec(n_fields, sz, align) { return false; } + true + } + + fn visit_rec_field(&self, i: uint, name: &str, + mtbl: uint, inner: *TyDesc) -> bool { + unsafe { self.align((*inner).align); } + if ! self.inner.visit_rec_field(i, name, mtbl, inner) { + return false; + } + unsafe { self.bump((*inner).size); } + true + } + + fn visit_leave_rec(&self, n_fields: uint, sz: uint, align: uint) -> bool { + if ! self.inner.visit_leave_rec(n_fields, sz, align) { return false; } + true + } + + fn visit_enter_class(&self, n_fields: uint, sz: uint, align: uint) + -> bool { + self.align(align); + if ! self.inner.visit_enter_class(n_fields, sz, align) { + return false; + } + true + } + + fn visit_class_field(&self, i: uint, name: &str, + mtbl: uint, inner: *TyDesc) -> bool { + unsafe { self.align((*inner).align); } + if ! self.inner.visit_class_field(i, name, mtbl, inner) { + return false; + } + unsafe { self.bump((*inner).size); } + true + } + + fn visit_leave_class(&self, n_fields: uint, sz: uint, align: uint) + -> bool { + if ! self.inner.visit_leave_class(n_fields, sz, align) { + return false; + } + true + } + + fn visit_enter_tup(&self, n_fields: uint, sz: uint, align: uint) -> bool { + self.align(align); + if ! self.inner.visit_enter_tup(n_fields, sz, align) { return false; } + true + } + + fn visit_tup_field(&self, i: uint, inner: *TyDesc) -> bool { + unsafe { self.align((*inner).align); } + if ! self.inner.visit_tup_field(i, inner) { return false; } + unsafe { self.bump((*inner).size); } + true + } + + fn visit_leave_tup(&self, n_fields: uint, sz: uint, align: uint) -> bool { + if ! self.inner.visit_leave_tup(n_fields, sz, align) { return false; } + true + } + + fn visit_enter_fn(&self, purity: uint, proto: uint, + n_inputs: uint, retstyle: uint) -> bool { + if ! self.inner.visit_enter_fn(purity, proto, n_inputs, retstyle) { + return false + } + true + } + + fn visit_fn_input(&self, i: uint, mode: uint, inner: *TyDesc) -> bool { + if ! self.inner.visit_fn_input(i, mode, inner) { return false; } + true + } + + fn visit_fn_output(&self, retstyle: uint, inner: *TyDesc) -> bool { + if ! self.inner.visit_fn_output(retstyle, inner) { return false; } + true + } + + fn visit_leave_fn(&self, purity: uint, proto: uint, + n_inputs: uint, retstyle: uint) -> bool { + if ! self.inner.visit_leave_fn(purity, proto, n_inputs, retstyle) { + return false; + } + true + } + + fn visit_enter_enum(&self, n_variants: uint, sz: uint, align: uint) + -> bool { + self.align(align); + if ! self.inner.visit_enter_enum(n_variants, sz, align) { + return false; + } + true + } + + fn visit_enter_enum_variant(&self, variant: uint, + disr_val: int, + n_fields: uint, + name: &str) -> bool { + self.inner.push_ptr(); + if ! self.inner.visit_enter_enum_variant(variant, disr_val, + n_fields, name) { + return false; + } + true + } + + fn visit_enum_variant_field(&self, i: uint, inner: *TyDesc) -> bool { + unsafe { self.align((*inner).align); } + if ! self.inner.visit_enum_variant_field(i, inner) { return false; } + unsafe { self.bump((*inner).size); } + true + } + + fn visit_leave_enum_variant(&self, variant: uint, + disr_val: int, + n_fields: uint, + name: &str) -> bool { + if ! self.inner.visit_leave_enum_variant(variant, disr_val, + n_fields, name) { + return false; + } + self.inner.pop_ptr(); + true + } + + fn visit_leave_enum(&self, n_variants: uint, sz: uint, align: uint) + -> bool { + if ! self.inner.visit_leave_enum(n_variants, sz, align) { + return false; + } + self.bump(sz); + true + } + + fn visit_trait(&self) -> bool { + self.align_to::(); + if ! self.inner.visit_trait() { return false; } + self.bump_past::(); + true + } + + fn visit_var(&self) -> bool { + if ! self.inner.visit_var() { return false; } + true + } + + fn visit_var_integral(&self) -> bool { + if ! self.inner.visit_var_integral() { return false; } + true + } + + fn visit_param(&self, i: uint) -> bool { + if ! self.inner.visit_param(i) { return false; } + true + } + + fn visit_self(&self) -> bool { + self.align_to::<&static/u8>(); + if ! self.inner.visit_self() { return false; } + self.align_to::<&static/u8>(); + true + } + + fn visit_type(&self) -> bool { + if ! self.inner.visit_type() { return false; } + true + } + + fn visit_opaque_box(&self) -> bool { + self.align_to::<@u8>(); + if ! self.inner.visit_opaque_box() { return false; } + self.bump_past::<@u8>(); + true + } + + fn visit_constr(&self, inner: *TyDesc) -> bool { + if ! self.inner.visit_constr(inner) { return false; } + true + } + + fn visit_closure_ptr(&self, ck: uint) -> bool { + self.align_to::(); + if ! self.inner.visit_closure_ptr(ck) { return false; } + self.bump_past::(); + true + } +} diff --git a/src/libcore/repr.rs b/src/libcore/repr.rs index 4d4970eada805..75a572fa46444 100644 --- a/src/libcore/repr.rs +++ b/src/libcore/repr.rs @@ -265,6 +265,7 @@ impl ReprVisitor { } +#[cfg(stage0)] impl ReprVisitor : TyVisitor { fn visit_bot() -> bool { self.writer.write_str("!"); @@ -559,6 +560,310 @@ impl ReprVisitor : TyVisitor { fn visit_closure_ptr(_ck: uint) -> bool { true } } +#[cfg(stage1)] +#[cfg(stage2)] +impl ReprVisitor : TyVisitor { + fn visit_bot(&self) -> bool { + self.writer.write_str("!"); + true + } + fn visit_nil(&self) -> bool { self.write::<()>() } + fn visit_bool(&self) -> bool { self.write::() } + fn visit_int(&self) -> bool { self.write::() } + fn visit_i8(&self) -> bool { self.write::() } + fn visit_i16(&self) -> bool { self.write::() } + fn visit_i32(&self) -> bool { self.write::() } + fn visit_i64(&self) -> bool { self.write::() } + + fn visit_uint(&self) -> bool { self.write::() } + fn visit_u8(&self) -> bool { self.write::() } + fn visit_u16(&self) -> bool { self.write::() } + fn visit_u32(&self) -> bool { self.write::() } + fn visit_u64(&self) -> bool { self.write::() } + + fn visit_float(&self) -> bool { self.write::() } + fn visit_f32(&self) -> bool { self.write::() } + fn visit_f64(&self) -> bool { self.write::() } + + fn visit_char(&self) -> bool { + do self.get:: |&ch| { + self.writer.write_char('\''); + self.writer.write_escaped_char(ch); + self.writer.write_char('\''); + } + } + + // Type no longer exists, vestigial function. + fn visit_str(&self) -> bool { fail; } + + fn visit_estr_box(&self) -> bool { + do self.get::<@str> |s| { + self.writer.write_char('@'); + self.write_escaped_slice(*s); + } + } + fn visit_estr_uniq(&self) -> bool { + do self.get::<~str> |s| { + self.writer.write_char('~'); + self.write_escaped_slice(*s); + } + } + fn visit_estr_slice(&self) -> bool { + do self.get::<&str> |s| { + self.write_escaped_slice(*s); + } + } + + // Type no longer exists, vestigial function. + fn visit_estr_fixed(&self, _n: uint, _sz: uint, + _align: uint) -> bool { fail; } + + fn visit_box(&self, mtbl: uint, inner: *TyDesc) -> bool { + self.writer.write_char('@'); + self.write_mut_qualifier(mtbl); + do self.get::<&managed::raw::BoxRepr> |b| { + let p = ptr::to_unsafe_ptr(&b.data) as *c_void; + self.visit_ptr_inner(p, inner); + } + } + + fn visit_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool { + self.writer.write_char('~'); + self.write_mut_qualifier(mtbl); + do self.get::<&managed::raw::BoxRepr> |b| { + let p = ptr::to_unsafe_ptr(&b.data) as *c_void; + self.visit_ptr_inner(p, inner); + } + } + + fn visit_ptr(&self, _mtbl: uint, _inner: *TyDesc) -> bool { + do self.get::<*c_void> |p| { + self.writer.write_str(fmt!("(0x%x as *())", + *p as uint)); + } + } + + fn visit_rptr(&self, mtbl: uint, inner: *TyDesc) -> bool { + self.writer.write_char('&'); + self.write_mut_qualifier(mtbl); + do self.get::<*c_void> |p| { + self.visit_ptr_inner(*p, inner); + } + } + + // Type no longer exists, vestigial function. + fn visit_vec(&self, _mtbl: uint, _inner: *TyDesc) -> bool { fail; } + + + fn visit_unboxed_vec(&self, mtbl: uint, inner: *TyDesc) -> bool { + do self.get:: |b| { + self.write_unboxed_vec_repr(mtbl, b, inner); + } + } + + fn visit_evec_box(&self, mtbl: uint, inner: *TyDesc) -> bool { + do self.get::<&VecRepr> |b| { + self.writer.write_char('@'); + self.write_unboxed_vec_repr(mtbl, &b.unboxed, inner); + } + } + + fn visit_evec_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool { + do self.get::<&VecRepr> |b| { + self.writer.write_char('~'); + self.write_unboxed_vec_repr(mtbl, &b.unboxed, inner); + } + } + + fn visit_evec_slice(&self, mtbl: uint, inner: *TyDesc) -> bool { + do self.get:: |s| { + self.writer.write_char('&'); + self.write_vec_range(mtbl, s.data, s.len, inner); + } + } + + fn visit_evec_fixed(&self, _n: uint, sz: uint, _align: uint, + mtbl: uint, inner: *TyDesc) -> bool { + do self.get:: |b| { + self.write_vec_range(mtbl, ptr::to_unsafe_ptr(b), sz, inner); + } + } + + fn visit_enter_rec(&self, _n_fields: uint, + _sz: uint, _align: uint) -> bool { + self.writer.write_char('{'); + true + } + + fn visit_rec_field(&self, i: uint, name: &str, + mtbl: uint, inner: *TyDesc) -> bool { + if i != 0 { + self.writer.write_str(", "); + } + self.write_mut_qualifier(mtbl); + self.writer.write_str(name); + self.writer.write_str(": "); + self.visit_inner(inner); + true + } + + fn visit_leave_rec(&self, _n_fields: uint, + _sz: uint, _align: uint) -> bool { + self.writer.write_char('}'); + true + } + + fn visit_enter_class(&self, _n_fields: uint, + _sz: uint, _align: uint) -> bool { + self.writer.write_char('{'); + true + } + fn visit_class_field(&self, i: uint, name: &str, + mtbl: uint, inner: *TyDesc) -> bool { + if i != 0 { + self.writer.write_str(", "); + } + self.write_mut_qualifier(mtbl); + self.writer.write_str(name); + self.writer.write_str(": "); + self.visit_inner(inner); + true + } + fn visit_leave_class(&self, _n_fields: uint, + _sz: uint, _align: uint) -> bool { + self.writer.write_char('}'); + true + } + + fn visit_enter_tup(&self, _n_fields: uint, + _sz: uint, _align: uint) -> bool { + self.writer.write_char('('); + true + } + fn visit_tup_field(&self, i: uint, inner: *TyDesc) -> bool { + if i != 0 { + self.writer.write_str(", "); + } + self.visit_inner(inner); + true + } + fn visit_leave_tup(&self, _n_fields: uint, + _sz: uint, _align: uint) -> bool { + self.writer.write_char(')'); + true + } + + fn visit_enter_enum(&self, n_variants: uint, + _sz: uint, _align: uint) -> bool { + if n_variants == 1 { + self.var_stk.push(Degenerate) + } else { + self.var_stk.push(TagMatch) + } + true + } + + fn visit_enter_enum_variant(&self, _variant: uint, + disr_val: int, + n_fields: uint, + name: &str) -> bool { + let mut write = false; + match self.var_stk.pop() { + Degenerate => { + write = true; + self.var_stk.push(Degenerate); + } + TagMatch | TagMismatch => { + do self.get::() |t| { + if disr_val == *t { + write = true; + self.var_stk.push(TagMatch); + } else { + self.var_stk.push(TagMismatch); + } + }; + self.bump_past::(); + } + } + + if write { + self.writer.write_str(name); + if n_fields > 0 { + self.writer.write_char('('); + } + } + true + } + + fn visit_enum_variant_field(&self, i: uint, inner: *TyDesc) -> bool { + match self.var_stk.last() { + Degenerate | TagMatch => { + if i != 0 { + self.writer.write_str(", "); + } + if ! self.visit_inner(inner) { + return false; + } + } + TagMismatch => () + } + true + } + + fn visit_leave_enum_variant(&self, _variant: uint, + _disr_val: int, + n_fields: uint, + _name: &str) -> bool { + match self.var_stk.last() { + Degenerate | TagMatch => { + if n_fields > 0 { + self.writer.write_char(')'); + } + } + TagMismatch => () + } + true + } + + fn visit_leave_enum(&self, _n_variants: uint, + _sz: uint, _align: uint) -> bool { + self.var_stk.pop(); + true + } + + fn visit_enter_fn(&self, _purity: uint, _proto: uint, + _n_inputs: uint, _retstyle: uint) -> bool { true } + fn visit_fn_input(&self, _i: uint, _mode: uint, _inner: *TyDesc) -> bool { + true + } + fn visit_fn_output(&self, _retstyle: uint, _inner: *TyDesc) -> bool { + true + } + fn visit_leave_fn(&self, _purity: uint, _proto: uint, + _n_inputs: uint, _retstyle: uint) -> bool { true } + + + fn visit_trait(&self) -> bool { true } + fn visit_var(&self) -> bool { true } + fn visit_var_integral(&self) -> bool { true } + fn visit_param(&self, _i: uint) -> bool { true } + fn visit_self(&self) -> bool { true } + fn visit_type(&self) -> bool { true } + + fn visit_opaque_box(&self) -> bool { + self.writer.write_char('@'); + do self.get::<&managed::raw::BoxRepr> |b| { + let p = ptr::to_unsafe_ptr(&b.data) as *c_void; + self.visit_ptr_inner(p, b.header.type_desc); + } + } + + // Type no longer exists, vestigial function. + fn visit_constr(&self, _inner: *TyDesc) -> bool { fail; } + + fn visit_closure_ptr(&self, _ck: uint) -> bool { true } +} + pub fn write_repr(writer: @Writer, object: &T) { unsafe { let ptr = ptr::to_unsafe_ptr(object) as *c_void; diff --git a/src/librustc/front/intrinsic.rs b/src/librustc/front/intrinsic.rs index 6657e6fcf0fee..5ccac6f091acc 100644 --- a/src/librustc/front/intrinsic.rs +++ b/src/librustc/front/intrinsic.rs @@ -31,97 +31,97 @@ mod intrinsic { }; trait TyVisitor { - fn visit_bot() -> bool; - fn visit_nil() -> bool; - fn visit_bool() -> bool; - - fn visit_int() -> bool; - fn visit_i8() -> bool; - fn visit_i16() -> bool; - fn visit_i32() -> bool; - fn visit_i64() -> bool; - - fn visit_uint() -> bool; - fn visit_u8() -> bool; - fn visit_u16() -> bool; - fn visit_u32() -> bool; - fn visit_u64() -> bool; - - fn visit_float() -> bool; - fn visit_f32() -> bool; - fn visit_f64() -> bool; - - fn visit_char() -> bool; - fn visit_str() -> bool; - - fn visit_estr_box() -> bool; - fn visit_estr_uniq() -> bool; - fn visit_estr_slice() -> bool; - fn visit_estr_fixed(n: uint, sz: uint, align: uint) -> bool; - - fn visit_box(mtbl: uint, inner: *TyDesc) -> bool; - fn visit_uniq(mtbl: uint, inner: *TyDesc) -> bool; - fn visit_ptr(mtbl: uint, inner: *TyDesc) -> bool; - fn visit_rptr(mtbl: uint, inner: *TyDesc) -> bool; - - fn visit_vec(mtbl: uint, inner: *TyDesc) -> bool; - fn visit_unboxed_vec(mtbl: uint, inner: *TyDesc) -> bool; - fn visit_evec_box(mtbl: uint, inner: *TyDesc) -> bool; - fn visit_evec_uniq(mtbl: uint, inner: *TyDesc) -> bool; - fn visit_evec_slice(mtbl: uint, inner: *TyDesc) -> bool; - fn visit_evec_fixed(n: uint, sz: uint, align: uint, + fn visit_bot(&self) -> bool; + fn visit_nil(&self) -> bool; + fn visit_bool(&self) -> bool; + + fn visit_int(&self) -> bool; + fn visit_i8(&self) -> bool; + fn visit_i16(&self) -> bool; + fn visit_i32(&self) -> bool; + fn visit_i64(&self) -> bool; + + fn visit_uint(&self) -> bool; + fn visit_u8(&self) -> bool; + fn visit_u16(&self) -> bool; + fn visit_u32(&self) -> bool; + fn visit_u64(&self) -> bool; + + fn visit_float(&self) -> bool; + fn visit_f32(&self) -> bool; + fn visit_f64(&self) -> bool; + + fn visit_char(&self) -> bool; + fn visit_str(&self) -> bool; + + fn visit_estr_box(&self) -> bool; + fn visit_estr_uniq(&self) -> bool; + fn visit_estr_slice(&self) -> bool; + fn visit_estr_fixed(&self, n: uint, sz: uint, align: uint) -> bool; + + fn visit_box(&self, mtbl: uint, inner: *TyDesc) -> bool; + fn visit_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool; + fn visit_ptr(&self, mtbl: uint, inner: *TyDesc) -> bool; + fn visit_rptr(&self, mtbl: uint, inner: *TyDesc) -> bool; + + fn visit_vec(&self, mtbl: uint, inner: *TyDesc) -> bool; + fn visit_unboxed_vec(&self, mtbl: uint, inner: *TyDesc) -> bool; + fn visit_evec_box(&self, mtbl: uint, inner: *TyDesc) -> bool; + fn visit_evec_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool; + fn visit_evec_slice(&self, mtbl: uint, inner: *TyDesc) -> bool; + fn visit_evec_fixed(&self, n: uint, sz: uint, align: uint, mtbl: uint, inner: *TyDesc) -> bool; - fn visit_enter_rec(n_fields: uint, + fn visit_enter_rec(&self, n_fields: uint, sz: uint, align: uint) -> bool; - fn visit_rec_field(i: uint, name: &str, + fn visit_rec_field(&self, i: uint, name: &str, mtbl: uint, inner: *TyDesc) -> bool; - fn visit_leave_rec(n_fields: uint, + fn visit_leave_rec(&self, n_fields: uint, sz: uint, align: uint) -> bool; - fn visit_enter_class(n_fields: uint, + fn visit_enter_class(&self, n_fields: uint, sz: uint, align: uint) -> bool; - fn visit_class_field(i: uint, name: &str, + fn visit_class_field(&self, i: uint, name: &str, mtbl: uint, inner: *TyDesc) -> bool; - fn visit_leave_class(n_fields: uint, + fn visit_leave_class(&self, n_fields: uint, sz: uint, align: uint) -> bool; - fn visit_enter_tup(n_fields: uint, + fn visit_enter_tup(&self, n_fields: uint, sz: uint, align: uint) -> bool; - fn visit_tup_field(i: uint, inner: *TyDesc) -> bool; - fn visit_leave_tup(n_fields: uint, + fn visit_tup_field(&self, i: uint, inner: *TyDesc) -> bool; + fn visit_leave_tup(&self, n_fields: uint, sz: uint, align: uint) -> bool; - fn visit_enter_enum(n_variants: uint, + fn visit_enter_enum(&self, n_variants: uint, sz: uint, align: uint) -> bool; - fn visit_enter_enum_variant(variant: uint, + fn visit_enter_enum_variant(&self, variant: uint, disr_val: int, n_fields: uint, name: &str) -> bool; - fn visit_enum_variant_field(i: uint, inner: *TyDesc) -> bool; - fn visit_leave_enum_variant(variant: uint, + fn visit_enum_variant_field(&self, i: uint, inner: *TyDesc) -> bool; + fn visit_leave_enum_variant(&self, variant: uint, disr_val: int, n_fields: uint, name: &str) -> bool; - fn visit_leave_enum(n_variants: uint, + fn visit_leave_enum(&self, n_variants: uint, sz: uint, align: uint) -> bool; - fn visit_enter_fn(purity: uint, proto: uint, + fn visit_enter_fn(&self, purity: uint, proto: uint, n_inputs: uint, retstyle: uint) -> bool; - fn visit_fn_input(i: uint, mode: uint, inner: *TyDesc) -> bool; - fn visit_fn_output(retstyle: uint, inner: *TyDesc) -> bool; - fn visit_leave_fn(purity: uint, proto: uint, + fn visit_fn_input(&self, i: uint, mode: uint, inner: *TyDesc) -> bool; + fn visit_fn_output(&self, retstyle: uint, inner: *TyDesc) -> bool; + fn visit_leave_fn(&self, purity: uint, proto: uint, n_inputs: uint, retstyle: uint) -> bool; - fn visit_trait() -> bool; - fn visit_var() -> bool; - fn visit_var_integral() -> bool; - fn visit_param(i: uint) -> bool; - fn visit_self() -> bool; - fn visit_type() -> bool; - fn visit_opaque_box() -> bool; - fn visit_constr(inner: *TyDesc) -> bool; - fn visit_closure_ptr(ck: uint) -> bool; + fn visit_trait(&self) -> bool; + fn visit_var(&self) -> bool; + fn visit_var_integral(&self) -> bool; + fn visit_param(&self, i: uint) -> bool; + fn visit_self(&self) -> bool; + fn visit_type(&self) -> bool; + fn visit_opaque_box(&self) -> bool; + fn visit_constr(&self, inner: *TyDesc) -> bool; + fn visit_closure_ptr(&self, ck: uint) -> bool; } #[abi = "rust-intrinsic"] diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 515666445e3aa..9b4911d9fbea7 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -233,7 +233,7 @@ fn get_lint_dict() -> lint_dict { (~"deprecated_self", @{lint: deprecated_self, desc: "warn about deprecated uses of `self`", - default: allow}), + default: warn}), /* FIXME(#3266)--make liveness warnings lintable (~"unused_variable", @@ -631,13 +631,18 @@ fn check_item_deprecated_self(cx: ty::ctxt, item: @ast::item) { fn maybe_warn(cx: ty::ctxt, item: @ast::item, self_ty: ast::self_ty) { - cx.sess.span_lint( - deprecated_self, - item.id, - item.id, - self_ty.span, - ~"this method form is deprecated; use an explicit `self` \ - parameter or mark the method as static"); + match self_ty.node { + ast::sty_by_ref => { + cx.sess.span_lint( + deprecated_self, + item.id, + item.id, + self_ty.span, + ~"this method form is deprecated; use an explicit `self` \ + parameter or mark the method as static"); + } + _ => {} + } } match /*bad*/copy item.node { diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index 39ab5735dee3f..ba9ff3a4f98bb 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -105,7 +105,8 @@ impl reflector { mth_idx, v, ty::vstore_box, - ast::sty_by_ref), + ast::sty_region( + ast::m_imm)), ArgVals(args), SaveIn(scratch.val), DontAutorefArg); let result = scratch.to_value_llval(bcx); let next_bcx = sub_block(bcx, ~"next"); diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc index 818c6eb04ea88..4ebd0b33f038a 100644 --- a/src/librustc/rustc.rc +++ b/src/librustc/rustc.rc @@ -25,6 +25,7 @@ #[allow(non_camel_case_types)]; #[allow(deprecated_mode)]; #[warn(deprecated_pattern)]; +#[allow(deprecated_self)]; #[no_core]; diff --git a/src/librustdoc/rustdoc.rc b/src/librustdoc/rustdoc.rc index 77ed564aab471..c756bbe82492e 100644 --- a/src/librustdoc/rustdoc.rc +++ b/src/librustdoc/rustdoc.rc @@ -26,6 +26,7 @@ #[allow(non_implicitly_copyable_typarams)]; #[allow(deprecated_mode)]; #[allow(deprecated_pattern)]; +#[allow(deprecated_self)]; extern mod core(vers = "0.6"); extern mod std(vers = "0.6"); diff --git a/src/libstd/std.rc b/src/libstd/std.rc index eea9bd0a40f7a..f75715cfd6d90 100644 --- a/src/libstd/std.rc +++ b/src/libstd/std.rc @@ -32,6 +32,7 @@ not required in or otherwise suitable for the core library. // that can't be silenced otherwise. Most every module is set to forbid #[allow(deprecated_mode)]; #[forbid(deprecated_pattern)]; +#[allow(deprecated_self)]; #[no_core]; diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rc index 0777269f8f7fc..bccff550a435f 100644 --- a/src/libsyntax/syntax.rc +++ b/src/libsyntax/syntax.rc @@ -23,6 +23,7 @@ #[allow(non_camel_case_types)]; #[allow(deprecated_mode)]; #[warn(deprecated_pattern)]; +#[allow(deprecated_self)]; #[no_core]; diff --git a/src/test/compile-fail/lint-default-methods.rs b/src/test/compile-fail/lint-default-methods.rs index 6b71f9e972fb2..1350c3e3ad1cd 100644 --- a/src/test/compile-fail/lint-default-methods.rs +++ b/src/test/compile-fail/lint-default-methods.rs @@ -1,7 +1,7 @@ #[forbid(default_methods)]; trait Foo { //~ ERROR default methods are experimental - fn bar() { io::println("hi"); } + fn bar(&self) { io::println("hi"); } } fn main() {} diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs index cf0a0a07397c0..c7c1a6bb33195 100644 --- a/src/test/run-pass/reflect-visit-data.rs +++ b/src/test/run-pass/reflect-visit-data.rs @@ -61,154 +61,154 @@ impl ptr_visit_adaptor { impl ptr_visit_adaptor: TyVisitor { - fn visit_bot() -> bool { + fn visit_bot(&self) -> bool { self.align_to::<()>(); if ! self.inner.visit_bot() { return false; } self.bump_past::<()>(); true } - fn visit_nil() -> bool { + fn visit_nil(&self) -> bool { self.align_to::<()>(); if ! self.inner.visit_nil() { return false; } self.bump_past::<()>(); true } - fn visit_bool() -> bool { + fn visit_bool(&self) -> bool { self.align_to::(); if ! self.inner.visit_bool() { return false; } self.bump_past::(); true } - fn visit_int() -> bool { + fn visit_int(&self) -> bool { self.align_to::(); if ! self.inner.visit_int() { return false; } self.bump_past::(); true } - fn visit_i8() -> bool { + fn visit_i8(&self) -> bool { self.align_to::(); if ! self.inner.visit_i8() { return false; } self.bump_past::(); true } - fn visit_i16() -> bool { + fn visit_i16(&self) -> bool { self.align_to::(); if ! self.inner.visit_i16() { return false; } self.bump_past::(); true } - fn visit_i32() -> bool { + fn visit_i32(&self) -> bool { self.align_to::(); if ! self.inner.visit_i32() { return false; } self.bump_past::(); true } - fn visit_i64() -> bool { + fn visit_i64(&self) -> bool { self.align_to::(); if ! self.inner.visit_i64() { return false; } self.bump_past::(); true } - fn visit_uint() -> bool { + fn visit_uint(&self) -> bool { self.align_to::(); if ! self.inner.visit_uint() { return false; } self.bump_past::(); true } - fn visit_u8() -> bool { + fn visit_u8(&self) -> bool { self.align_to::(); if ! self.inner.visit_u8() { return false; } self.bump_past::(); true } - fn visit_u16() -> bool { + fn visit_u16(&self) -> bool { self.align_to::(); if ! self.inner.visit_u16() { return false; } self.bump_past::(); true } - fn visit_u32() -> bool { + fn visit_u32(&self) -> bool { self.align_to::(); if ! self.inner.visit_u32() { return false; } self.bump_past::(); true } - fn visit_u64() -> bool { + fn visit_u64(&self) -> bool { self.align_to::(); if ! self.inner.visit_u64() { return false; } self.bump_past::(); true } - fn visit_float() -> bool { + fn visit_float(&self) -> bool { self.align_to::(); if ! self.inner.visit_float() { return false; } self.bump_past::(); true } - fn visit_f32() -> bool { + fn visit_f32(&self) -> bool { self.align_to::(); if ! self.inner.visit_f32() { return false; } self.bump_past::(); true } - fn visit_f64() -> bool { + fn visit_f64(&self) -> bool { self.align_to::(); if ! self.inner.visit_f64() { return false; } self.bump_past::(); true } - fn visit_char() -> bool { + fn visit_char(&self) -> bool { self.align_to::(); if ! self.inner.visit_char() { return false; } self.bump_past::(); true } - fn visit_str() -> bool { + fn visit_str(&self) -> bool { self.align_to::<~str>(); if ! self.inner.visit_str() { return false; } self.bump_past::<~str>(); true } - fn visit_estr_box() -> bool { + fn visit_estr_box(&self) -> bool { self.align_to::<@str>(); if ! self.inner.visit_estr_box() { return false; } self.bump_past::<@str>(); true } - fn visit_estr_uniq() -> bool { + fn visit_estr_uniq(&self) -> bool { self.align_to::<~str>(); if ! self.inner.visit_estr_uniq() { return false; } self.bump_past::<~str>(); true } - fn visit_estr_slice() -> bool { + fn visit_estr_slice(&self) -> bool { self.align_to::<&static/str>(); if ! self.inner.visit_estr_slice() { return false; } self.bump_past::<&static/str>(); true } - fn visit_estr_fixed(n: uint, + fn visit_estr_fixed(&self, n: uint, sz: uint, align: uint) -> bool { self.align(align); @@ -217,35 +217,35 @@ impl ptr_visit_adaptor: TyVisitor { true } - fn visit_box(mtbl: uint, inner: *TyDesc) -> bool { + fn visit_box(&self, mtbl: uint, inner: *TyDesc) -> bool { self.align_to::<@u8>(); if ! self.inner.visit_box(mtbl, inner) { return false; } self.bump_past::<@u8>(); true } - fn visit_uniq(mtbl: uint, inner: *TyDesc) -> bool { + fn visit_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool { self.align_to::<~u8>(); if ! self.inner.visit_uniq(mtbl, inner) { return false; } self.bump_past::<~u8>(); true } - fn visit_ptr(mtbl: uint, inner: *TyDesc) -> bool { + fn visit_ptr(&self, mtbl: uint, inner: *TyDesc) -> bool { self.align_to::<*u8>(); if ! self.inner.visit_ptr(mtbl, inner) { return false; } self.bump_past::<*u8>(); true } - fn visit_rptr(mtbl: uint, inner: *TyDesc) -> bool { + fn visit_rptr(&self, mtbl: uint, inner: *TyDesc) -> bool { self.align_to::<&static/u8>(); if ! self.inner.visit_rptr(mtbl, inner) { return false; } self.bump_past::<&static/u8>(); true } - fn visit_unboxed_vec(mtbl: uint, inner: *TyDesc) -> bool { + fn visit_unboxed_vec(&self, mtbl: uint, inner: *TyDesc) -> bool { self.align_to::(); // FIXME (#3732): Inner really has to move its own pointers on this one. // or else possibly we could have some weird interface wherein we @@ -255,35 +255,35 @@ impl ptr_visit_adaptor: TyVisitor { true } - fn visit_vec(mtbl: uint, inner: *TyDesc) -> bool { + fn visit_vec(&self, mtbl: uint, inner: *TyDesc) -> bool { self.align_to::<~[u8]>(); if ! self.inner.visit_vec(mtbl, inner) { return false; } self.bump_past::<~[u8]>(); true } - fn visit_evec_box(mtbl: uint, inner: *TyDesc) -> bool { + fn visit_evec_box(&self, mtbl: uint, inner: *TyDesc) -> bool { self.align_to::<@[u8]>(); if ! self.inner.visit_evec_box(mtbl, inner) { return false; } self.bump_past::<@[u8]>(); true } - fn visit_evec_uniq(mtbl: uint, inner: *TyDesc) -> bool { + fn visit_evec_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool { self.align_to::<~[u8]>(); if ! self.inner.visit_evec_uniq(mtbl, inner) { return false; } self.bump_past::<~[u8]>(); true } - fn visit_evec_slice(mtbl: uint, inner: *TyDesc) -> bool { + fn visit_evec_slice(&self, mtbl: uint, inner: *TyDesc) -> bool { self.align_to::<&static/[u8]>(); if ! self.inner.visit_evec_slice(mtbl, inner) { return false; } self.bump_past::<&static/[u8]>(); true } - fn visit_evec_fixed(n: uint, sz: uint, align: uint, + fn visit_evec_fixed(&self, n: uint, sz: uint, align: uint, mtbl: uint, inner: *TyDesc) -> bool { self.align(align); if ! self.inner.visit_evec_fixed(n, sz, align, mtbl, inner) { @@ -293,24 +293,25 @@ impl ptr_visit_adaptor: TyVisitor { true } - fn visit_enter_rec(n_fields: uint, sz: uint, align: uint) -> bool { + fn visit_enter_rec(&self, n_fields: uint, sz: uint, align: uint) -> bool { self.align(align); if ! self.inner.visit_enter_rec(n_fields, sz, align) { return false; } true } - fn visit_rec_field(i: uint, name: &str, + fn visit_rec_field(&self, i: uint, name: &str, mtbl: uint, inner: *TyDesc) -> bool { if ! self.inner.visit_rec_field(i, name, mtbl, inner) { return false; } true } - fn visit_leave_rec(n_fields: uint, sz: uint, align: uint) -> bool { + fn visit_leave_rec(&self, n_fields: uint, sz: uint, align: uint) -> bool { if ! self.inner.visit_leave_rec(n_fields, sz, align) { return false; } true } - fn visit_enter_class(n_fields: uint, sz: uint, align: uint) -> bool { + fn visit_enter_class(&self, n_fields: uint, sz: uint, align: uint) + -> bool { self.align(align); if ! self.inner.visit_enter_class(n_fields, sz, align) { return false; @@ -318,7 +319,7 @@ impl ptr_visit_adaptor: TyVisitor { true } - fn visit_class_field(i: uint, name: &str, + fn visit_class_field(&self, i: uint, name: &str, mtbl: uint, inner: *TyDesc) -> bool { if ! self.inner.visit_class_field(i, name, mtbl, inner) { return false; @@ -326,30 +327,31 @@ impl ptr_visit_adaptor: TyVisitor { true } - fn visit_leave_class(n_fields: uint, sz: uint, align: uint) -> bool { + fn visit_leave_class(&self, n_fields: uint, sz: uint, align: uint) + -> bool { if ! self.inner.visit_leave_class(n_fields, sz, align) { return false; } true } - fn visit_enter_tup(n_fields: uint, sz: uint, align: uint) -> bool { + fn visit_enter_tup(&self, n_fields: uint, sz: uint, align: uint) -> bool { self.align(align); if ! self.inner.visit_enter_tup(n_fields, sz, align) { return false; } true } - fn visit_tup_field(i: uint, inner: *TyDesc) -> bool { + fn visit_tup_field(&self, i: uint, inner: *TyDesc) -> bool { if ! self.inner.visit_tup_field(i, inner) { return false; } true } - fn visit_leave_tup(n_fields: uint, sz: uint, align: uint) -> bool { + fn visit_leave_tup(&self, n_fields: uint, sz: uint, align: uint) -> bool { if ! self.inner.visit_leave_tup(n_fields, sz, align) { return false; } true } - fn visit_enter_fn(purity: uint, proto: uint, + fn visit_enter_fn(&self, purity: uint, proto: uint, n_inputs: uint, retstyle: uint) -> bool { if ! self.inner.visit_enter_fn(purity, proto, n_inputs, retstyle) { return false @@ -357,17 +359,17 @@ impl ptr_visit_adaptor: TyVisitor { true } - fn visit_fn_input(i: uint, mode: uint, inner: *TyDesc) -> bool { + fn visit_fn_input(&self, i: uint, mode: uint, inner: *TyDesc) -> bool { if ! self.inner.visit_fn_input(i, mode, inner) { return false; } true } - fn visit_fn_output(retstyle: uint, inner: *TyDesc) -> bool { + fn visit_fn_output(&self, retstyle: uint, inner: *TyDesc) -> bool { if ! self.inner.visit_fn_output(retstyle, inner) { return false; } true } - fn visit_leave_fn(purity: uint, proto: uint, + fn visit_leave_fn(&self, purity: uint, proto: uint, n_inputs: uint, retstyle: uint) -> bool { if ! self.inner.visit_leave_fn(purity, proto, n_inputs, retstyle) { return false; @@ -375,13 +377,14 @@ impl ptr_visit_adaptor: TyVisitor { true } - fn visit_enter_enum(n_variants: uint, sz: uint, align: uint) -> bool { + fn visit_enter_enum(&self, n_variants: uint, sz: uint, align: uint) + -> bool { self.align(align); if ! self.inner.visit_enter_enum(n_variants, sz, align) { return false; } true } - fn visit_enter_enum_variant(variant: uint, + fn visit_enter_enum_variant(&self, variant: uint, disr_val: int, n_fields: uint, name: &str) -> bool { @@ -392,12 +395,12 @@ impl ptr_visit_adaptor: TyVisitor { true } - fn visit_enum_variant_field(i: uint, inner: *TyDesc) -> bool { + fn visit_enum_variant_field(&self, i: uint, inner: *TyDesc) -> bool { if ! self.inner.visit_enum_variant_field(i, inner) { return false; } true } - fn visit_leave_enum_variant(variant: uint, + fn visit_leave_enum_variant(&self, variant: uint, disr_val: int, n_fields: uint, name: &str) -> bool { @@ -408,58 +411,59 @@ impl ptr_visit_adaptor: TyVisitor { true } - fn visit_leave_enum(n_variants: uint, sz: uint, align: uint) -> bool { + fn visit_leave_enum(&self, n_variants: uint, sz: uint, align: uint) + -> bool { if ! self.inner.visit_leave_enum(n_variants, sz, align) { return false; } true } - fn visit_trait() -> bool { + fn visit_trait(&self) -> bool { self.align_to::(); if ! self.inner.visit_trait() { return false; } self.bump_past::(); true } - fn visit_var() -> bool { + fn visit_var(&self) -> bool { if ! self.inner.visit_var() { return false; } true } - fn visit_var_integral() -> bool { + fn visit_var_integral(&self) -> bool { if ! self.inner.visit_var_integral() { return false; } true } - fn visit_param(i: uint) -> bool { + fn visit_param(&self, i: uint) -> bool { if ! self.inner.visit_param(i) { return false; } true } - fn visit_self() -> bool { + fn visit_self(&self) -> bool { self.align_to::<&static/u8>(); if ! self.inner.visit_self() { return false; } self.align_to::<&static/u8>(); true } - fn visit_type() -> bool { + fn visit_type(&self) -> bool { if ! self.inner.visit_type() { return false; } true } - fn visit_opaque_box() -> bool { + fn visit_opaque_box(&self) -> bool { self.align_to::<@u8>(); if ! self.inner.visit_opaque_box() { return false; } self.bump_past::<@u8>(); true } - fn visit_constr(inner: *TyDesc) -> bool { + fn visit_constr(&self, inner: *TyDesc) -> bool { if ! self.inner.visit_constr(inner) { return false; } true } - fn visit_closure_ptr(ck: uint) -> bool { + fn visit_closure_ptr(&self, ck: uint) -> bool { self.align_to::(); if ! self.inner.visit_closure_ptr(ck) { return false; } self.bump_past::(); @@ -503,121 +507,125 @@ impl my_visitor: movable_ptr { impl my_visitor: TyVisitor { - fn visit_bot() -> bool { true } - fn visit_nil() -> bool { true } - fn visit_bool() -> bool { + fn visit_bot(&self) -> bool { true } + fn visit_nil(&self) -> bool { true } + fn visit_bool(&self) -> bool { do self.get::() |b| { self.vals += ~[bool::to_str(b)]; }; true } - fn visit_int() -> bool { + fn visit_int(&self) -> bool { do self.get::() |i| { self.vals += ~[int::to_str(i, 10u)]; }; true } - fn visit_i8() -> bool { true } - fn visit_i16() -> bool { true } - fn visit_i32() -> bool { true } - fn visit_i64() -> bool { true } + fn visit_i8(&self) -> bool { true } + fn visit_i16(&self) -> bool { true } + fn visit_i32(&self) -> bool { true } + fn visit_i64(&self) -> bool { true } - fn visit_uint() -> bool { true } - fn visit_u8() -> bool { true } - fn visit_u16() -> bool { true } - fn visit_u32() -> bool { true } - fn visit_u64() -> bool { true } + fn visit_uint(&self) -> bool { true } + fn visit_u8(&self) -> bool { true } + fn visit_u16(&self) -> bool { true } + fn visit_u32(&self) -> bool { true } + fn visit_u64(&self) -> bool { true } - fn visit_float() -> bool { true } - fn visit_f32() -> bool { true } - fn visit_f64() -> bool { true } + fn visit_float(&self) -> bool { true } + fn visit_f32(&self) -> bool { true } + fn visit_f64(&self) -> bool { true } - fn visit_char() -> bool { true } - fn visit_str() -> bool { true } + fn visit_char(&self) -> bool { true } + fn visit_str(&self) -> bool { true } - fn visit_estr_box() -> bool { true } - fn visit_estr_uniq() -> bool { true } - fn visit_estr_slice() -> bool { true } - fn visit_estr_fixed(_n: uint, _sz: uint, + fn visit_estr_box(&self) -> bool { true } + fn visit_estr_uniq(&self) -> bool { true } + fn visit_estr_slice(&self) -> bool { true } + fn visit_estr_fixed(&self, _n: uint, _sz: uint, _align: uint) -> bool { true } - fn visit_box(_mtbl: uint, _inner: *TyDesc) -> bool { true } - fn visit_uniq(_mtbl: uint, _inner: *TyDesc) -> bool { true } - fn visit_ptr(_mtbl: uint, _inner: *TyDesc) -> bool { true } - fn visit_rptr(_mtbl: uint, _inner: *TyDesc) -> bool { true } - - fn visit_vec(_mtbl: uint, _inner: *TyDesc) -> bool { true } - fn visit_unboxed_vec(_mtbl: uint, _inner: *TyDesc) -> bool { true } - fn visit_evec_box(_mtbl: uint, _inner: *TyDesc) -> bool { true } - fn visit_evec_uniq(_mtbl: uint, _inner: *TyDesc) -> bool { true } - fn visit_evec_slice(_mtbl: uint, _inner: *TyDesc) -> bool { true } - fn visit_evec_fixed(_n: uint, _sz: uint, _align: uint, + fn visit_box(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_uniq(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_ptr(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_rptr(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + + fn visit_vec(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_unboxed_vec(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_evec_box(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_evec_uniq(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_evec_slice(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_evec_fixed(&self, _n: uint, _sz: uint, _align: uint, _mtbl: uint, _inner: *TyDesc) -> bool { true } - fn visit_enter_rec(_n_fields: uint, + fn visit_enter_rec(&self, _n_fields: uint, _sz: uint, _align: uint) -> bool { true } - fn visit_rec_field(_i: uint, _name: &str, + fn visit_rec_field(&self, _i: uint, _name: &str, _mtbl: uint, inner: *TyDesc) -> bool { error!("rec field!"); self.visit_inner(inner) } - fn visit_leave_rec(_n_fields: uint, + fn visit_leave_rec(&self, _n_fields: uint, _sz: uint, _align: uint) -> bool { true } - fn visit_enter_class(_n_fields: uint, + fn visit_enter_class(&self, _n_fields: uint, _sz: uint, _align: uint) -> bool { true } - fn visit_class_field(_i: uint, _name: &str, + fn visit_class_field(&self, _i: uint, _name: &str, _mtbl: uint, inner: *TyDesc) -> bool { self.visit_inner(inner) } - fn visit_leave_class(_n_fields: uint, + fn visit_leave_class(&self, _n_fields: uint, _sz: uint, _align: uint) -> bool { true } - fn visit_enter_tup(_n_fields: uint, + fn visit_enter_tup(&self, _n_fields: uint, _sz: uint, _align: uint) -> bool { true } - fn visit_tup_field(_i: uint, inner: *TyDesc) -> bool { + fn visit_tup_field(&self, _i: uint, inner: *TyDesc) -> bool { error!("tup field!"); self.visit_inner(inner) } - fn visit_leave_tup(_n_fields: uint, + fn visit_leave_tup(&self, _n_fields: uint, _sz: uint, _align: uint) -> bool { true } - fn visit_enter_enum(_n_variants: uint, + fn visit_enter_enum(&self, _n_variants: uint, _sz: uint, _align: uint) -> bool { // FIXME (#3732): this needs to rewind between enum variants, or something. true } - fn visit_enter_enum_variant(_variant: uint, + fn visit_enter_enum_variant(&self, _variant: uint, _disr_val: int, _n_fields: uint, _name: &str) -> bool { true } - fn visit_enum_variant_field(_i: uint, inner: *TyDesc) -> bool { + fn visit_enum_variant_field(&self, _i: uint, inner: *TyDesc) -> bool { self.visit_inner(inner) } - fn visit_leave_enum_variant(_variant: uint, + fn visit_leave_enum_variant(&self, _variant: uint, _disr_val: int, _n_fields: uint, _name: &str) -> bool { true } - fn visit_leave_enum(_n_variants: uint, + fn visit_leave_enum(&self, _n_variants: uint, _sz: uint, _align: uint) -> bool { true } - fn visit_enter_fn(_purity: uint, _proto: uint, + fn visit_enter_fn(&self, _purity: uint, _proto: uint, _n_inputs: uint, _retstyle: uint) -> bool { true } - fn visit_fn_input(_i: uint, _mode: uint, _inner: *TyDesc) -> bool { true } - fn visit_fn_output(_retstyle: uint, _inner: *TyDesc) -> bool { true } - fn visit_leave_fn(_purity: uint, _proto: uint, + fn visit_fn_input(&self, _i: uint, _mode: uint, _inner: *TyDesc) -> bool { + true + } + fn visit_fn_output(&self, _retstyle: uint, _inner: *TyDesc) -> bool { + true + } + fn visit_leave_fn(&self, _purity: uint, _proto: uint, _n_inputs: uint, _retstyle: uint) -> bool { true } - fn visit_trait() -> bool { true } - fn visit_var() -> bool { true } - fn visit_var_integral() -> bool { true } - fn visit_param(_i: uint) -> bool { true } - fn visit_self() -> bool { true } - fn visit_type() -> bool { true } - fn visit_opaque_box() -> bool { true } - fn visit_constr(_inner: *TyDesc) -> bool { true } - fn visit_closure_ptr(_ck: uint) -> bool { true } + fn visit_trait(&self) -> bool { true } + fn visit_var(&self) -> bool { true } + fn visit_var_integral(&self) -> bool { true } + fn visit_param(&self, _i: uint) -> bool { true } + fn visit_self(&self) -> bool { true } + fn visit_type(&self) -> bool { true } + fn visit_opaque_box(&self) -> bool { true } + fn visit_constr(&self, _inner: *TyDesc) -> bool { true } + fn visit_closure_ptr(&self, _ck: uint) -> bool { true } } fn get_tydesc_for(&&_t: T) -> *TyDesc { From 2195f75fc2daf37fc554cf4c02c083409bc07022 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Mon, 28 Jan 2013 22:44:59 -0800 Subject: [PATCH 4/4] librustc: Speed up byte copy operations --- src/libcore/libc.rs | 13 +++++++++++++ src/libcore/ptr.rs | 26 ++++++++++++++++++++++++- src/libcore/vec.rs | 7 +++++++ src/librustc/middle/trans/base.rs | 10 +++++++++- src/librustc/middle/trans/foreign.rs | 18 +++++++++++++++++ src/librustc/middle/trans/type_use.rs | 2 ++ src/librustc/middle/typeck/check/mod.rs | 22 +++++++++++++++++++++ 7 files changed, 96 insertions(+), 2 deletions(-) diff --git a/src/libcore/libc.rs b/src/libcore/libc.rs index ecd48fe16bc35..a1107d49c0ec1 100644 --- a/src/libcore/libc.rs +++ b/src/libcore/libc.rs @@ -1123,10 +1123,23 @@ pub mod funcs { unsafe fn strerror(n: c_int) -> *c_char; unsafe fn strtok(s: *c_char, t: *c_char) -> *c_char; unsafe fn strxfrm(s: *c_char, ct: *c_char, n: size_t) -> size_t; + + // These are fine to execute on the Rust stack. They must be, in + // fact, because LLVM generates calls to them! + #[rust_stack] + #[inline(always)] unsafe fn memcpy(s: *c_void, ct: *c_void, n: size_t) -> *c_void; + #[rust_stack] + #[inline(always)] unsafe fn memmove(s: *c_void, ct: *c_void, n: size_t) -> *c_void; + #[rust_stack] + #[inline(always)] unsafe fn memcmp(cx: *c_void, ct: *c_void, n: size_t) -> c_int; + #[rust_stack] + #[inline(always)] unsafe fn memchr(cx: *c_void, c: c_int, n: size_t) -> *c_void; + #[rust_stack] + #[inline(always)] unsafe fn memset(s: *c_void, c: c_int, n: size_t) -> *c_void; } } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index f059c119f4989..dd5c4143b6d7a 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -116,9 +116,16 @@ pub pure fn is_not_null(ptr: *const T) -> bool { !is_null(ptr) } * and destination may overlap. */ #[inline(always)] +#[cfg(target_word_size = "32")] pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { let n = count * sys::size_of::(); - libc_::memmove(dst as *mut c_void, src as *c_void, n as size_t); + memmove32(dst as *mut u8, src as *u8, n as u32); +} +#[inline(always)] +#[cfg(target_word_size = "64")] +pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { + let n = count * sys::size_of::(); + memmove64(dst as *mut u8, src as *u8, n as u64); } #[inline(always)] @@ -183,6 +190,23 @@ pub trait Ptr { pure fn offset(count: uint) -> self; } +#[cfg(stage0)] +unsafe fn memmove32(dst: *mut u8, src: *const u8, count: u32) { + libc::memmove(dst as *c_void, src as *c_void, count as size_t); +} +#[cfg(stage0)] +unsafe fn memmove64(dst: *mut u8, src: *const u8, count: u64) { + libc::memmove(dst as *c_void, src as *c_void, count as size_t); +} + +#[abi="rust-intrinsic"] +#[cfg(stage1)] +#[cfg(stage2)] +pub extern { + fn memmove32(dst: *mut u8, src: *u8, size: u32); + fn memmove64(dst: *mut u8, src: *u8, size: u64); +} + /// Extension methods for immutable pointers impl *T: Ptr { /// Returns true if the pointer is equal to the null pointer. diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index e9d60d0f26923..9707ed8459a40 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -266,6 +266,7 @@ pub pure fn slice(v: &[const T], start: uint, end: uint) -> ~[T] { } /// Return a slice that points into another slice. +#[inline(always)] pub pure fn view(v: &r/[T], start: uint, end: uint) -> &r/[T] { assert (start <= end); assert (end <= len(v)); @@ -279,6 +280,7 @@ pub pure fn view(v: &r/[T], start: uint, end: uint) -> &r/[T] { } /// Return a slice that points into another slice. +#[inline(always)] pub pure fn mut_view(v: &r/[mut T], start: uint, end: uint) -> &r/[mut T] { assert (start <= end); assert (end <= len(v)); @@ -292,6 +294,7 @@ pub pure fn mut_view(v: &r/[mut T], start: uint, end: uint) -> &r/[mut T] { } /// Return a slice that points into another slice. +#[inline(always)] pub pure fn const_view(v: &r/[const T], start: uint, end: uint) -> &r/[const T] { assert (start <= end); @@ -305,6 +308,8 @@ pub pure fn const_view(v: &r/[const T], start: uint, } } +/// Copies + /// Split the vector `v` by applying each element against the predicate `f`. pub fn split(v: &[T], f: fn(t: &T) -> bool) -> ~[~[T]] { let ln = len(v); @@ -2127,6 +2132,7 @@ pub mod raw { * Copies `count` bytes from `src` to `dst`. The source and destination * may overlap. */ + #[inline(always)] pub unsafe fn copy_memory(dst: &[mut T], src: &[const T], count: uint) { assert dst.len() >= count; @@ -2193,6 +2199,7 @@ pub mod bytes { * Copies `count` bytes from `src` to `dst`. The source and destination * may overlap. */ + #[inline(always)] pub fn copy_memory(dst: &[mut u8], src: &[const u8], count: uint) { // Bound checks are done at vec::raw::copy_memory. unsafe { vec::raw::copy_memory(dst, src, count) } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index f4814b4657b97..e9f83e25f5590 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2593,9 +2593,15 @@ fn declare_intrinsics(llmod: ModuleRef) -> HashMap<~str, ValueRef> { T_void())); let memcpy32 = decl_cdecl_fn(llmod, ~"llvm.memcpy.p0i8.p0i8.i32", - T_fn(T_memcpy32_args, T_void())); + T_fn(copy T_memcpy32_args, T_void())); let memcpy64 = decl_cdecl_fn(llmod, ~"llvm.memcpy.p0i8.p0i8.i64", + T_fn(copy T_memcpy64_args, T_void())); + let memmove32 = + decl_cdecl_fn(llmod, ~"llvm.memmove.p0i8.p0i8.i32", + T_fn(T_memcpy32_args, T_void())); + let memmove64 = + decl_cdecl_fn(llmod, ~"llvm.memmove.p0i8.p0i8.i64", T_fn(T_memcpy64_args, T_void())); let memset32 = decl_cdecl_fn(llmod, ~"llvm.memset.p0i8.i32", @@ -2704,6 +2710,8 @@ fn declare_intrinsics(llmod: ModuleRef) -> HashMap<~str, ValueRef> { intrinsics.insert(~"llvm.gcread", gcread); intrinsics.insert(~"llvm.memcpy.p0i8.p0i8.i32", memcpy32); intrinsics.insert(~"llvm.memcpy.p0i8.p0i8.i64", memcpy64); + intrinsics.insert(~"llvm.memmove.p0i8.p0i8.i32", memmove32); + intrinsics.insert(~"llvm.memmove.p0i8.p0i8.i64", memmove64); intrinsics.insert(~"llvm.memset.p0i8.i32", memset32); intrinsics.insert(~"llvm.memset.p0i8.i64", memset64); intrinsics.insert(~"llvm.trap", trap); diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 317a64ea52875..46ab560e1b67a 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -568,6 +568,24 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item, T_ptr(T_nil())); Store(bcx, morestack_addr, fcx.llretptr); } + ~"memmove32" => { + let dst_ptr = get_param(decl, first_real_arg); + let src_ptr = get_param(decl, first_real_arg + 1); + let size = get_param(decl, first_real_arg + 2); + let align = C_i32(1); + let volatile = C_bool(false); + let llfn = bcx.ccx().intrinsics.get(~"llvm.memmove.p0i8.p0i8.i32"); + Call(bcx, llfn, ~[dst_ptr, src_ptr, size, align, volatile]); + } + ~"memmove64" => { + let dst_ptr = get_param(decl, first_real_arg); + let src_ptr = get_param(decl, first_real_arg + 1); + let size = get_param(decl, first_real_arg + 2); + let align = C_i32(1); + let volatile = C_bool(false); + let llfn = bcx.ccx().intrinsics.get(~"llvm.memmove.p0i8.p0i8.i64"); + Call(bcx, llfn, ~[dst_ptr, src_ptr, size, align, volatile]); + } ~"sqrtf32" => { let x = get_param(decl, first_real_arg); let sqrtf = ccx.intrinsics.get(~"llvm.sqrt.f32"); diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index ba1901f215c57..1ef5abe8ee683 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -129,6 +129,8 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint) ~"visit_tydesc" | ~"forget" | ~"addr_of" | ~"frame_address" | ~"morestack_addr" => 0, + ~"memmove32" | ~"memmove64" => 0, + ~"sqrtf32" | ~"sqrtf64" | ~"powif32" | ~"powif64" | ~"sinf32" | ~"sinf64" | ~"cosf32" | ~"cosf64" | ~"powf32" | ~"powf64" | ~"expf32" | ~"expf64" | diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 3d5f6e9d303d9..c4440b8941131 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -3152,6 +3152,28 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) { ~"morestack_addr" => { (0u, ~[], ty::mk_nil_ptr(tcx)) } + ~"memmove32" => { + (0, ~[arg(ast::by_copy, + ty::mk_ptr(tcx, + ty::mt { ty: ty::mk_u8(tcx), mutbl: ast::m_mutbl })), + arg(ast::by_copy, + ty::mk_ptr(tcx, + ty::mt { ty: ty::mk_u8(tcx), mutbl: ast::m_imm })), + arg(ast::by_copy, + ty::mk_u32(tcx))], + ty::mk_nil(tcx)) + } + ~"memmove64" => { + (0, ~[arg(ast::by_copy, + ty::mk_ptr(tcx, + ty::mt { ty: ty::mk_u8(tcx), mutbl: ast::m_mutbl })), + arg(ast::by_copy, + ty::mk_ptr(tcx, + ty::mt { ty: ty::mk_u8(tcx), mutbl: ast::m_imm })), + arg(ast::by_copy, + ty::mk_u64(tcx))], + ty::mk_nil(tcx)) + } ~"sqrtf32" => { (0u, ~[arg(ast::by_copy, ty::mk_f32(tcx))], ty::mk_f32(tcx))