diff --git a/src/libextra/flate.rs b/src/libextra/flate.rs index 530885001292c51d77d5b0df33ba1cb21c42d452..65d4f79c640249e01008fd71e39b37f75cbf9998 100644 --- a/src/libextra/flate.rs +++ b/src/libextra/flate.rs @@ -25,13 +25,13 @@ pub mod rustrt { #[link_name = "rustrt"] extern { - pub fn tdefl_compress_mem_to_heap(psrc_buf: *const c_void, + pub fn tdefl_compress_mem_to_heap(psrc_buf: *c_void, src_buf_len: size_t, pout_len: *mut size_t, flags: c_int) -> *c_void; - pub fn tinfl_decompress_mem_to_heap(psrc_buf: *const c_void, + pub fn tinfl_decompress_mem_to_heap(psrc_buf: *c_void, src_buf_len: size_t, pout_len: *mut size_t, flags: c_int) diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 3fdd1587c0d7adbde4d8add3b46b947c843bb90f..0536a5e0227318071dd38fbc2fb059ffa9b140ce 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -804,12 +804,9 @@ pub fn get_enum_variants(intr: @ident_interner, cdata: cmd, id: ast::NodeId, fn get_explicit_self(item: ebml::Doc) -> ast::explicit_self_ { fn get_mutability(ch: u8) -> ast::mutability { match ch as char { - 'i' => { ast::m_imm } - 'm' => { ast::m_mutbl } - 'c' => { ast::m_const } - _ => { - fail!("unknown mutability character: `%c`", ch as char) - } + 'i' => ast::m_imm, + 'm' => ast::m_mutbl, + _ => fail!("unknown mutability character: `%c`", ch as char), } } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 21eee26620c0d74d25f2c63022184a306c81bc98..6a2d1901aef3f36cda8006a93a7009c18e537548 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -635,15 +635,8 @@ fn encode_explicit_self(ebml_w: &mut writer::Encoder, explicit_self: ast::explic fn encode_mutability(ebml_w: &writer::Encoder, m: ast::mutability) { match m { - m_imm => { - ebml_w.writer.write(&[ 'i' as u8 ]); - } - m_mutbl => { - ebml_w.writer.write(&[ 'm' as u8 ]); - } - m_const => { - ebml_w.writer.write(&[ 'c' as u8 ]); - } + m_imm => ebml_w.writer.write(&[ 'i' as u8 ]), + m_mutbl => ebml_w.writer.write(&[ 'm' as u8 ]), } } } diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 89b30e46ac06d1a5f00c5ad70ea507db90ccd216..a03266649ab0a3ee0da8405ec389d5f9d6cb0219 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -417,7 +417,6 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t { fn parse_mutability(st: &mut PState) -> ast::mutability { match peek(st) { 'm' => { next(st); ast::m_mutbl } - '?' => { next(st); ast::m_const } _ => { ast::m_imm } } } diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 5611808cc6d982225d6a7357f667633ea266b104..d00928dd3db74232da80f73a8df73150f12d41ab 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -99,7 +99,6 @@ fn enc_mutability(w: @io::Writer, mt: ast::mutability) { match mt { m_imm => (), m_mutbl => w.write_char('m'), - m_const => w.write_char('?') } } diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index 4991f75dc3e371ccb71e95f4c1cc8991d2c67cb4..ba5b9d9dca142c40321d81eaac4200e7c3cccf50 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -23,7 +23,7 @@ use middle::borrowck::*; use middle::moves; use middle::ty; -use syntax::ast::{m_mutbl, m_imm, m_const}; +use syntax::ast::m_mutbl; use syntax::ast; use syntax::ast_util; use syntax::codemap::span; @@ -220,9 +220,9 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self, // Restrictions that would cause the new loan to be illegal: let illegal_if = match loan2.mutbl { - m_mutbl => RESTR_ALIAS | RESTR_FREEZE | RESTR_CLAIM, - m_imm => RESTR_ALIAS | RESTR_FREEZE, - m_const => RESTR_ALIAS, + MutableMutability => RESTR_ALIAS | RESTR_FREEZE | RESTR_CLAIM, + ImmutableMutability => RESTR_ALIAS | RESTR_FREEZE, + ConstMutability => RESTR_ALIAS, }; debug!("illegal_if=%?", illegal_if); @@ -231,7 +231,7 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self, if restr.loan_path != loan2.loan_path { loop; } match (new_loan.mutbl, old_loan.mutbl) { - (m_mutbl, m_mutbl) => { + (MutableMutability, MutableMutability) => { self.bccx.span_err( new_loan.span, fmt!("cannot borrow `%s` as mutable \ @@ -582,7 +582,6 @@ fn check_for_assignment_to_restricted_or_frozen_location( // Otherwise stop iterating LpExtend(_, mc::McDeclared, _) | LpExtend(_, mc::McImmutable, _) | - LpExtend(_, mc::McReadOnly, _) | LpVar(_) => { return true; } @@ -590,8 +589,11 @@ fn check_for_assignment_to_restricted_or_frozen_location( // Check for a non-const loan of `loan_path` let cont = do this.each_in_scope_loan(expr.id) |loan| { - if loan.loan_path == loan_path && loan.mutbl != m_const { - this.report_illegal_mutation(expr, full_loan_path, loan); + if loan.loan_path == loan_path && + loan.mutbl != ConstMutability { + this.report_illegal_mutation(expr, + full_loan_path, + loan); false } else { true diff --git a/src/librustc/middle/borrowck/gather_loans/lifetime.rs b/src/librustc/middle/borrowck/gather_loans/lifetime.rs index 1dcfc515139bb7169c21f84fd0f0ce38f20946cb..e76d11c269b2b21461c489aae232ca14135a8b77 100644 --- a/src/librustc/middle/borrowck/gather_loans/lifetime.rs +++ b/src/librustc/middle/borrowck/gather_loans/lifetime.rs @@ -15,7 +15,7 @@ use middle::borrowck::*; use mc = middle::mem_categorization; use middle::ty; -use syntax::ast::{m_const, m_imm, m_mutbl}; +use syntax::ast::{m_imm, m_mutbl}; use syntax::ast; use syntax::codemap::span; use util::ppaux::{note_and_explain_region}; @@ -26,7 +26,7 @@ pub fn guarantee_lifetime(bccx: @BorrowckCtxt, span: span, cmt: mc::cmt, loan_region: ty::Region, - loan_mutbl: ast::mutability) { + loan_mutbl: LoanMutability) { debug!("guarantee_lifetime(cmt=%s, loan_region=%s)", cmt.repr(bccx.tcx), loan_region.repr(bccx.tcx)); let ctxt = GuaranteeLifetimeContext {bccx: bccx, @@ -54,7 +54,7 @@ struct GuaranteeLifetimeContext { span: span, loan_region: ty::Region, - loan_mutbl: ast::mutability, + loan_mutbl: LoanMutability, cmt_original: mc::cmt } @@ -235,11 +235,11 @@ fn check_root(&self, // we need to dynamically mark it to prevent incompatible // borrows from happening later. let opt_dyna = match ptr_mutbl { - m_imm | m_const => None, + m_imm => None, m_mutbl => { match self.loan_mutbl { - m_mutbl => Some(DynaMut), - m_imm | m_const => Some(DynaImm) + MutableMutability => Some(DynaMut), + ImmutableMutability | ConstMutability => Some(DynaImm) } } }; diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs index 6d2a4fcc9f31a8498afdc4ca9dd59ad1cdf11b87..8c5da2f3d0f84fac59dd103c7498500be4cc0ec8 100644 --- a/src/librustc/middle/borrowck/gather_loans/mod.rs +++ b/src/librustc/middle/borrowck/gather_loans/mod.rs @@ -26,7 +26,6 @@ use util::common::indenter; use util::ppaux::{Repr}; -use syntax::ast::{m_const, m_imm, m_mutbl}; use syntax::ast; use syntax::ast_util::id_range; use syntax::codemap::span; @@ -237,7 +236,11 @@ fn gather_loans_in_expr(v: &mut GatherLoanVisitor, // make sure that the thing we are pointing out stays valid // for the lifetime `scope_r` of the resulting ptr: let scope_r = ty_region(tcx, ex.span, ty::expr_ty(tcx, ex)); - this.guarantee_valid(ex.id, ex.span, base_cmt, mutbl, scope_r); + this.guarantee_valid(ex.id, + ex.span, + base_cmt, + LoanMutability::from_ast_mutability(mutbl), + scope_r); visit::walk_expr(v, ex, this); } @@ -278,7 +281,11 @@ fn gather_loans_in_expr(v: &mut GatherLoanVisitor, // adjustments). let scope_r = ty::re_scope(ex.id); let arg_cmt = this.bccx.cat_expr(arg); - this.guarantee_valid(arg.id, arg.span, arg_cmt, m_imm, scope_r); + this.guarantee_valid(arg.id, + arg.span, + arg_cmt, + ImmutableMutability, + scope_r); visit::walk_expr(v, ex, this); } @@ -357,18 +364,22 @@ pub fn guarantee_adjustments(&mut self, match *autoref { ty::AutoPtr(r, m) => { + let loan_mutability = + LoanMutability::from_ast_mutability(m); self.guarantee_valid(expr.id, expr.span, cmt, - m, + loan_mutability, r) } ty::AutoBorrowVec(r, m) | ty::AutoBorrowVecRef(r, m) => { let cmt_index = mcx.cat_index(expr, cmt, autoderefs+1); + let loan_mutability = + LoanMutability::from_ast_mutability(m); self.guarantee_valid(expr.id, expr.span, cmt_index, - m, + loan_mutability, r) } ty::AutoBorrowFn(r) => { @@ -376,7 +387,7 @@ pub fn guarantee_adjustments(&mut self, self.guarantee_valid(expr.id, expr.span, cmt_deref, - m_imm, + ImmutableMutability, r) } ty::AutoBorrowObj(r, m) => { @@ -402,7 +413,7 @@ pub fn guarantee_valid(&mut self, borrow_id: ast::NodeId, borrow_span: span, cmt: mc::cmt, - req_mutbl: ast::mutability, + req_mutbl: LoanMutability, loan_region: ty::Region) { debug!("guarantee_valid(borrow_id=%?, cmt=%s, \ req_mutbl=%?, loan_region=%?)", @@ -473,7 +484,7 @@ pub fn guarantee_valid(&mut self, let kill_scope = self.compute_kill_scope(loan_scope, loan_path); debug!("kill_scope = %?", kill_scope); - if req_mutbl == m_mutbl { + if req_mutbl == MutableMutability { self.mark_loan_path_as_mutated(loan_path); } @@ -516,7 +527,7 @@ pub fn guarantee_valid(&mut self, // index: all_loans.len(), // loan_path: loan_path, // cmt: cmt, - // mutbl: m_const, + // mutbl: ConstMutability, // gen_scope: borrow_id, // kill_scope: kill_scope, // span: borrow_span, @@ -527,29 +538,20 @@ pub fn guarantee_valid(&mut self, fn check_mutability(bccx: @BorrowckCtxt, borrow_span: span, cmt: mc::cmt, - req_mutbl: ast::mutability) { + req_mutbl: LoanMutability) { //! Implements the M-* rules in doc.rs. match req_mutbl { - m_const => { + ConstMutability => { // Data of any mutability can be lent as const. } - m_imm => { - match cmt.mutbl { - mc::McImmutable | mc::McDeclared | mc::McInherited => { - // both imm and mut data can be lent as imm; - // for mutable data, this is a freeze - } - mc::McReadOnly => { - bccx.report(BckError {span: borrow_span, - cmt: cmt, - code: err_mutbl(req_mutbl)}); - } - } + ImmutableMutability => { + // both imm and mut data can be lent as imm; + // for mutable data, this is a freeze } - m_mutbl => { + MutableMutability => { // Only mutable data can be lent as mutable. if !cmt.mutbl.is_mutable() { bccx.report(BckError {span: borrow_span, @@ -561,12 +563,14 @@ fn check_mutability(bccx: @BorrowckCtxt, } } - pub fn restriction_set(&self, req_mutbl: ast::mutability) + pub fn restriction_set(&self, req_mutbl: LoanMutability) -> RestrictionSet { match req_mutbl { - m_const => RESTR_EMPTY, - m_imm => RESTR_EMPTY | RESTR_MUTATE | RESTR_CLAIM, - m_mutbl => RESTR_EMPTY | RESTR_MUTATE | RESTR_CLAIM | RESTR_FREEZE + ConstMutability => RESTR_EMPTY, + ImmutableMutability => RESTR_EMPTY | RESTR_MUTATE | RESTR_CLAIM, + MutableMutability => { + RESTR_EMPTY | RESTR_MUTATE | RESTR_CLAIM | RESTR_FREEZE + } } } @@ -582,8 +586,8 @@ pub fn mark_loan_path_as_mutated(&self, loan_path: @LoanPath) { self.mark_loan_path_as_mutated(base); } LpExtend(_, mc::McDeclared, _) | - LpExtend(_, mc::McImmutable, _) | - LpExtend(_, mc::McReadOnly, _) => { + LpExtend(_, mc::McImmutable, _) => { + // Nothing to do. } } } @@ -701,8 +705,13 @@ fn gather_pat(&mut self, } } }; - self.guarantee_valid(pat.id, pat.span, - cmt_discr, mutbl, scope_r); + let loan_mutability = + LoanMutability::from_ast_mutability(mutbl); + self.guarantee_valid(pat.id, + pat.span, + cmt_discr, + loan_mutability, + scope_r); } ast::bind_infer => { // No borrows here, but there may be moves @@ -725,6 +734,8 @@ fn gather_pat(&mut self, self.vec_slice_info(slice_pat, slice_ty); let mcx = self.bccx.mc_ctxt(); let cmt_index = mcx.cat_index(slice_pat, cmt, 0); + let slice_loan_mutability = + LoanMutability::from_ast_mutability(slice_mutbl); // Note: We declare here that the borrow occurs upon // entering the `[...]` pattern. This implies that @@ -743,8 +754,11 @@ fn gather_pat(&mut self, // trans do the right thing, and it would only work // for `~` vectors. It seems simpler to just require // that people call `vec.pop()` or `vec.unshift()`. - self.guarantee_valid(pat.id, pat.span, - cmt_index, slice_mutbl, slice_r); + self.guarantee_valid(pat.id, + pat.span, + cmt_index, + slice_loan_mutability, + slice_r); } _ => {} diff --git a/src/librustc/middle/borrowck/gather_loans/restrictions.rs b/src/librustc/middle/borrowck/gather_loans/restrictions.rs index ccfef63d9bcba378224d8cdcb8cb407cd5edcd31..26c2cff189c46b00923a7ff94d666170926768eb 100644 --- a/src/librustc/middle/borrowck/gather_loans/restrictions.rs +++ b/src/librustc/middle/borrowck/gather_loans/restrictions.rs @@ -15,7 +15,7 @@ use middle::borrowck::*; use mc = middle::mem_categorization; use middle::ty; -use syntax::ast::{m_const, m_imm, m_mutbl}; +use syntax::ast::{m_imm, m_mutbl}; use syntax::codemap::span; pub enum RestrictionResult { @@ -121,13 +121,6 @@ fn restrict(&self, Safe } - mc::cat_deref(_, _, mc::region_ptr(m_const, _)) | - mc::cat_deref(_, _, mc::gc_ptr(m_const)) => { - // R-Deref-Freeze-Borrowed - self.check_no_mutability_control(cmt, restrictions); - Safe - } - mc::cat_deref(cmt_base, _, pk @ mc::gc_ptr(m_mutbl)) => { // R-Deref-Managed-Borrowed // diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index 4490fe65d91817e5fde4c4b3f53d6cd1b20ffef8..7113af3fbc2464a8f55c7f6526aea344fbfa3000 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -241,12 +241,39 @@ pub enum PartialTotal { /////////////////////////////////////////////////////////////////////////// // Loans and loan paths +#[deriving(Clone, Eq)] +pub enum LoanMutability { + ImmutableMutability, + ConstMutability, + MutableMutability, +} + +impl LoanMutability { + pub fn from_ast_mutability(ast_mutability: ast::mutability) + -> LoanMutability { + match ast_mutability { + ast::m_imm => ImmutableMutability, + ast::m_mutbl => MutableMutability, + } + } +} + +impl ToStr for LoanMutability { + fn to_str(&self) -> ~str { + match *self { + ImmutableMutability => ~"immutable", + ConstMutability => ~"read-only", + MutableMutability => ~"mutable", + } + } +} + /// Record of a loan that was issued. pub struct Loan { index: uint, loan_path: @LoanPath, cmt: mc::cmt, - mutbl: ast::mutability, + mutbl: LoanMutability, restrictions: ~[Restriction], gen_scope: ast::NodeId, kill_scope: ast::NodeId, @@ -417,7 +444,7 @@ fn to_str(&self) -> ~str { // Errors that can occur #[deriving(Eq)] pub enum bckerr_code { - err_mutbl(ast::mutability), + err_mutbl(LoanMutability), err_out_of_root_scope(ty::Region, ty::Region), // superscope, subscope err_out_of_scope(ty::Region, ty::Region), // superscope, subscope err_freeze_aliasable_const @@ -794,17 +821,14 @@ pub fn cmt_to_str(&self, cmt: mc::cmt) -> ~str { mc.cmt_to_str(cmt) } - pub fn mut_to_str(&self, mutbl: ast::mutability) -> ~str { - let mc = &mc::mem_categorization_ctxt {tcx: self.tcx, - method_map: self.method_map}; - mc.mut_to_str(mutbl) + pub fn mut_to_str(&self, mutbl: LoanMutability) -> ~str { + mutbl.to_str() } pub fn mut_to_keyword(&self, mutbl: ast::mutability) -> &'static str { match mutbl { ast::m_imm => "", - ast::m_const => "const", - ast::m_mutbl => "mut" + ast::m_mutbl => "mut", } } } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 8be9a5db8bbbb7df69777fad3cabc6045c4313c6..3f1e409e170cde03b53c3f31a1cae27bccb341d3 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -52,7 +52,7 @@ use util::ppaux::{ty_to_str, region_ptr_to_str, Repr}; use util::common::indenter; -use syntax::ast::{m_imm, m_const, m_mutbl}; +use syntax::ast::{m_imm, m_mutbl}; use syntax::ast; use syntax::codemap::span; use syntax::print::pprust; @@ -113,7 +113,6 @@ pub enum ElementKind { #[deriving(Eq, IterBytes)] pub enum MutabilityCategory { McImmutable, // Immutable. - McReadOnly, // Read-only (`const`) McDeclared, // Directly declared as mutable. McInherited // Inherited from the fact that owner is mutable. } @@ -297,7 +296,6 @@ impl MutabilityCategory { pub fn from_mutbl(m: ast::mutability) -> MutabilityCategory { match m { m_imm => McImmutable, - m_const => McReadOnly, m_mutbl => McDeclared } } @@ -305,7 +303,6 @@ pub fn from_mutbl(m: ast::mutability) -> MutabilityCategory { pub fn inherit(&self) -> MutabilityCategory { match *self { McImmutable => McImmutable, - McReadOnly => McReadOnly, McDeclared => McInherited, McInherited => McInherited } @@ -313,7 +310,7 @@ pub fn inherit(&self) -> MutabilityCategory { pub fn is_mutable(&self) -> bool { match *self { - McImmutable | McReadOnly => false, + McImmutable => false, McDeclared | McInherited => true } } @@ -321,7 +318,7 @@ pub fn is_mutable(&self) -> bool { pub fn is_immutable(&self) -> bool { match *self { McImmutable => true, - McReadOnly | McDeclared | McInherited => false + McDeclared | McInherited => false } } @@ -329,7 +326,6 @@ pub fn to_user_str(&self) -> &'static str { match *self { McDeclared | McInherited => "mutable", McImmutable => "immutable", - McReadOnly => "const" } } } @@ -610,7 +606,6 @@ pub fn inherited_mutability(&self, -> MutabilityCategory { match interior_m { m_imm => base_m.inherit(), - m_const => McReadOnly, m_mutbl => McDeclared } } @@ -999,7 +994,6 @@ pub fn cat_pattern(&self, pub fn mut_to_str(&self, mutbl: ast::mutability) -> ~str { match mutbl { m_mutbl => ~"mutable", - m_const => ~"const", m_imm => ~"immutable" } } @@ -1164,7 +1158,6 @@ pub fn freely_aliasable(&self) -> Option { Some(AliasableManaged(m)) } - cat_deref(_, _, region_ptr(m @ m_const, _)) | cat_deref(_, _, region_ptr(m @ m_imm, _)) => { Some(AliasableBorrowed(m)) } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index db76d75a5a58303d61e96744f360256929f55834..8c96df9b8f0e9c1a30fbaf8d4be96615f800318c 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -272,8 +272,7 @@ fn mk_pointer( match a_seq_ty.ty.node { ast::ty_vec(ref mt) => { let mut mt = ast_mt_to_mt(this, rscope, mt); - if a_seq_ty.mutbl == ast::m_mutbl || - a_seq_ty.mutbl == ast::m_const { + if a_seq_ty.mutbl == ast::m_mutbl { mt = ty::mt { ty: mt.ty, mutbl: a_seq_ty.mutbl }; } return ty::mk_evec(tcx, mt, vst); diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index c15f6a254457e66d8dcc91e8efece7af90514bf9..1f7cccbdc938b3a112288cdc6f7f255e29441ee1 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -102,7 +102,7 @@ trait `ToStr` imported, and I call `to_str()` on a value of type `T`, use extra::list::Nil; use syntax::ast::{def_id, sty_value, sty_region, sty_box}; use syntax::ast::{sty_uniq, sty_static, NodeId}; -use syntax::ast::{m_const, m_mutbl, m_imm}; +use syntax::ast::{m_mutbl, m_imm}; use syntax::ast; use syntax::ast_map; @@ -700,7 +700,7 @@ fn search_for_autosliced_method(&self, ty_evec(mt, vstore_fixed(_)) => { // First try to borrow to a slice let entry = self.search_for_some_kind_of_autorefd_method( - AutoBorrowVec, autoderefs, [m_const, m_imm, m_mutbl], + AutoBorrowVec, autoderefs, [m_imm, m_mutbl], |m,r| ty::mk_evec(tcx, ty::mt {ty:mt.ty, mutbl:m}, vstore_slice(r))); @@ -709,7 +709,7 @@ fn search_for_autosliced_method(&self, // Then try to borrow to a slice *and* borrow a pointer. self.search_for_some_kind_of_autorefd_method( - AutoBorrowVecRef, autoderefs, [m_const, m_imm, m_mutbl], + AutoBorrowVecRef, autoderefs, [m_imm, m_mutbl], |m,r| { let slice_ty = ty::mk_evec(tcx, ty::mt {ty:mt.ty, mutbl:m}, @@ -744,7 +744,7 @@ fn search_for_autosliced_method(&self, // Coerce ~/@/&Trait instances to &Trait. self.search_for_some_kind_of_autorefd_method( - AutoBorrowObj, autoderefs, [m_const, m_imm, m_mutbl], + AutoBorrowObj, autoderefs, [m_imm, m_mutbl], |trt_mut, reg| { ty::mk_trait(tcx, trt_did, trt_substs.clone(), RegionTraitStore(reg), trt_mut, b) @@ -779,7 +779,7 @@ fn search_for_autoptrd_method(&self, self_ty: ty::t, autoderefs: uint) ty_float(*) | ty_enum(*) | ty_ptr(*) | ty_struct(*) | ty_tup(*) | ty_estr(*) | ty_evec(*) | ty_trait(*) | ty_closure(*) => { self.search_for_some_kind_of_autorefd_method( - AutoPtr, autoderefs, [m_const, m_imm, m_mutbl], + AutoPtr, autoderefs, [m_imm, m_mutbl], |m,r| ty::mk_rptr(tcx, r, ty::mt {ty:self_ty, mutbl:m})) } @@ -1270,18 +1270,10 @@ fn rcvr_matches_ty(fcx: @mut FnCtxt, } fn mutability_matches(self_mutbl: ast::mutability, - candidate_mutbl: ast::mutability) -> bool { + candidate_mutbl: ast::mutability) + -> bool { //! True if `self_mutbl <: candidate_mutbl` - - match (self_mutbl, candidate_mutbl) { - (_, m_const) => true, - (m_mutbl, m_mutbl) => true, - (m_imm, m_imm) => true, - (m_mutbl, m_imm) => false, - (m_imm, m_mutbl) => false, - (m_const, m_imm) => false, - (m_const, m_mutbl) => false, - } + self_mutbl == candidate_mutbl } } diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs index 2e337f5f57b74b465d49c8ac5699b1963955a551..86c0736090c937e1a36a88b5cf00fd2517c276c8 100644 --- a/src/librustc/middle/typeck/infer/glb.rs +++ b/src/librustc/middle/typeck/infer/glb.rs @@ -21,7 +21,7 @@ use middle::typeck::infer::{TypeTrace, Subtype}; use middle::typeck::infer::fold_regions_in_sig; use middle::typeck::isr_alist; -use syntax::ast::{Many, Once, extern_fn, impure_fn, m_const, m_imm, m_mutbl}; +use syntax::ast::{Many, Once, extern_fn, impure_fn, m_imm, m_mutbl}; use syntax::ast::{unsafe_fn}; use syntax::ast::{Onceness, purity}; use util::common::{indenter}; @@ -52,16 +52,6 @@ fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres { match (a.mutbl, b.mutbl) { // If one side or both is mut, then the GLB must use // the precise type from the mut side. - (m_mutbl, m_const) => { - Sub(**self).tys(a.ty, b.ty).chain(|_t| { - Ok(ty::mt {ty: a.ty, mutbl: m_mutbl}) - }) - } - (m_const, m_mutbl) => { - Sub(**self).tys(b.ty, a.ty).chain(|_t| { - Ok(ty::mt {ty: b.ty, mutbl: m_mutbl}) - }) - } (m_mutbl, m_mutbl) => { eq_tys(self, a.ty, b.ty).then(|| { Ok(ty::mt {ty: a.ty, mutbl: m_mutbl}) @@ -70,22 +60,12 @@ fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres { // If one side or both is immutable, we can use the GLB of // both sides but mutbl must be `m_imm`. - (m_imm, m_const) | - (m_const, m_imm) | (m_imm, m_imm) => { self.tys(a.ty, b.ty).chain(|t| { Ok(ty::mt {ty: t, mutbl: m_imm}) }) } - // If both sides are const, then we can use GLB of both - // sides and mutbl of only `m_const`. - (m_const, m_const) => { - self.tys(a.ty, b.ty).chain(|t| { - Ok(ty::mt {ty: t, mutbl: m_const}) - }) - } - // There is no mutual subtype of these combinations. (m_mutbl, m_imm) | (m_imm, m_mutbl) => { diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs index 4f38e2aaac6b6f524e78a5bec325647a4e58b59b..50bddaacc3fc98a95b47c83e15baeb0d42e777bb 100644 --- a/src/librustc/middle/typeck/infer/lub.rs +++ b/src/librustc/middle/typeck/infer/lub.rs @@ -24,7 +24,7 @@ use util::ppaux::mt_to_str; use extra::list; -use syntax::ast::{Many, Once, extern_fn, m_const, impure_fn}; +use syntax::ast::{Many, Once, extern_fn, impure_fn}; use syntax::ast::{unsafe_fn}; use syntax::ast::{Onceness, purity}; @@ -55,14 +55,13 @@ fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres { mt_to_str(tcx, a), mt_to_str(tcx, b)); - let m = if a.mutbl == b.mutbl { - a.mutbl - } else { - m_const - }; + if a.mutbl != b.mutbl { + return Err(ty::terr_mutability) + } + let m = a.mutbl; match m { - m_imm | m_const => { + m_imm => { self.tys(a.ty, b.ty).chain(|t| Ok(ty::mt {ty: t, mutbl: m}) ) } @@ -71,11 +70,7 @@ fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres { eq_tys(self, a.ty, b.ty).then(|| { Ok(ty::mt {ty: a.ty, mutbl: m}) }) - }).chain_err(|_e| { - self.tys(a.ty, b.ty).chain(|t| { - Ok(ty::mt {ty: t, mutbl: m_const}) - }) - }) + }).chain_err(|e| Err(e)) } } } diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs index 5a4ea1c9f1f58e3f56c3b228d1fb121a268769ce..a00f018ceab0fdf650e5c93c3525b29060cad261 100644 --- a/src/librustc/middle/typeck/infer/sub.rs +++ b/src/librustc/middle/typeck/infer/sub.rs @@ -26,7 +26,7 @@ use extra::list::Nil; use extra::list; -use syntax::ast::{Onceness, m_const, purity}; +use syntax::ast::{Onceness, purity}; pub struct Sub(CombineFields); // "subtype", "subregion" etc @@ -67,7 +67,7 @@ fn regions(&self, a: ty::Region, b: ty::Region) -> cres { fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres { debug!("mts(%s <: %s)", a.inf_str(self.infcx), b.inf_str(self.infcx)); - if a.mutbl != b.mutbl && b.mutbl != m_const { + if a.mutbl != b.mutbl { return Err(ty::terr_mutability); } @@ -77,7 +77,7 @@ fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres { // (i.e., invariant if mut): eq_tys(self, a.ty, b.ty).then(|| Ok(*a)) } - m_imm | m_const => { + m_imm => { // Otherwise we can be covariant: self.tys(a.ty, b.ty).chain(|_t| Ok(*a) ) } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 0fdcac26ac878fd57af887706f1d85febcdfdf6d..3549323cf085f91d3840633333ab7be3f33c3786 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -239,7 +239,6 @@ fn mutability_to_str(m: ast::mutability) -> ~str { match m { ast::m_mutbl => ~"mut ", ast::m_imm => ~"", - ast::m_const => ~"const " } } diff --git a/src/libstd/cast.rs b/src/libstd/cast.rs index 825d0147c80e2f669a27ebcbab0ead46769f3a11..a4e18d98f47ea6c90209ef76183942a09f700bca 100644 --- a/src/libstd/cast.rs +++ b/src/libstd/cast.rs @@ -10,6 +10,7 @@ //! Unsafe casting functions +use ptr::RawPtr; use sys; use unstable::intrinsics; @@ -94,13 +95,13 @@ pub unsafe fn transmute_region<'a,'b,T>(ptr: &'a T) -> &'b T { /// Coerce an immutable reference to be mutable. #[inline] -pub unsafe fn transmute_mut_unsafe(ptr: *const T) -> *mut T { +pub unsafe fn transmute_mut_unsafe>(ptr: P) -> *mut T { transmute(ptr) } /// Coerce an immutable reference to be mutable. #[inline] -pub unsafe fn transmute_immut_unsafe(ptr: *const T) -> *T { +pub unsafe fn transmute_immut_unsafe>(ptr: P) -> *T { transmute(ptr) } diff --git a/src/libstd/cleanup.rs b/src/libstd/cleanup.rs index 6a6ba12bae301bf9825f4b3afc75bdf9aefd7c17..6b982ec75da126255f7bc8545bfad0920f969b8c 100644 --- a/src/libstd/cleanup.rs +++ b/src/libstd/cleanup.rs @@ -11,7 +11,7 @@ #[doc(hidden)]; use libc::c_void; -use ptr::{mut_null}; +use ptr::null; use unstable::intrinsics::TyDesc; use unstable::raw; @@ -37,7 +37,7 @@ unsafe fn each_live_alloc(read_next_before: bool, use rt::local_heap; let mut box = local_heap::live_allocs(); - while box != mut_null() { + while box != null() { let next_before = (*box).next; let uniq = (*box).ref_count == managed::RC_MANAGED_UNIQUE; diff --git a/src/libstd/os.rs b/src/libstd/os.rs index e7caf3f23abae8697754909d85ea9a49cb5f23cf..7aae9425302255fdfaadac1a28a1612cdaf88096 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -1521,7 +1521,7 @@ pub fn new(min_len: uint, options: ~[MapOption]) -> Result<~MemoryMap, MapError> let r = unsafe { libc::mmap(addr, len, prot, flags, fd, offset) }; - if r == libc::MAP_FAILED { + if r.equiv(&libc::MAP_FAILED) { Err(match errno() as c_int { libc::EACCES => ErrFdNotAvail, libc::EBADF => ErrInvalidFd, diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs index 12af303f33ffe7fb5a3b1f8f34ae031631b8a9c4..860b1f4b7683b704151fc8bb95578ee13c70d374 100644 --- a/src/libstd/ptr.rs +++ b/src/libstd/ptr.rs @@ -12,8 +12,11 @@ use cast; use clone::Clone; +use cmp::Equiv; use iterator::{range, Iterator}; use option::{Option, Some, None}; +#[cfg(stage0)] +use sys; use unstable::intrinsics; use util::swap; @@ -24,18 +27,28 @@ /// Calculate the offset from a pointer #[inline] +#[cfg(stage0)] pub fn offset(ptr: *T, count: int) -> *T { - unsafe { intrinsics::offset(ptr, count) } + (ptr as uint + (count as uint) * sys::size_of::()) as *T } -/// Calculate the offset from a const pointer +/// Calculate the offset from a mut pointer #[inline] -pub fn const_offset(ptr: *const T, count: int) -> *const T { - unsafe { intrinsics::offset(ptr as *T, count) } +#[cfg(stage0)] +pub fn mut_offset(ptr: *mut T, count: int) -> *mut T { + (ptr as uint + (count as uint) * sys::size_of::()) as *mut T +} + +/// Calculate the offset from a pointer +#[inline] +#[cfg(not(stage0))] +pub fn offset(ptr: *T, count: int) -> *T { + unsafe { intrinsics::offset(ptr, count) } } /// Calculate the offset from a mut pointer #[inline] +#[cfg(not(stage0))] pub fn mut_offset(ptr: *mut T, count: int) -> *mut T { unsafe { intrinsics::offset(ptr as *T, count) as *mut T } } @@ -73,11 +86,11 @@ pub fn mut_null() -> *mut T { 0 as *mut T } /// Returns true if the pointer is equal to the null pointer. #[inline] -pub fn is_null(ptr: *const T) -> bool { ptr == null() } +pub fn is_null>(ptr: P) -> bool { ptr.is_null() } /// Returns true if the pointer is not equal to the null pointer. #[inline] -pub fn is_not_null(ptr: *const T) -> bool { !is_null(ptr) } +pub fn is_not_null>(ptr: P) -> bool { ptr.is_not_null() } /** * Copies data from one location to another. @@ -87,8 +100,10 @@ pub fn is_not_null(ptr: *const T) -> bool { !is_null(ptr) } */ #[inline] #[cfg(target_word_size = "32")] -pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { - intrinsics::memmove32(dst, src as *T, count as u32); +pub unsafe fn copy_memory>(dst: *mut T, src: P, count: uint) { + intrinsics::memmove32(dst, + cast::transmute_immut_unsafe(src), + count as u32); } /** @@ -99,8 +114,10 @@ pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { */ #[inline] #[cfg(target_word_size = "64")] -pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { - intrinsics::memmove64(dst, src as *T, count as u64); +pub unsafe fn copy_memory>(dst: *mut T, src: P, count: uint) { + intrinsics::memmove64(dst, + cast::transmute_immut_unsafe(src), + count as u64); } /** @@ -111,8 +128,12 @@ pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { */ #[inline] #[cfg(target_word_size = "32")] -pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: uint) { - intrinsics::memcpy32(dst, src as *T, count as u32); +pub unsafe fn copy_nonoverlapping_memory>(dst: *mut T, + src: P, + count: uint) { + intrinsics::memcpy32(dst, + cast::transmute_immut_unsafe(src), + count as u32); } /** @@ -123,8 +144,12 @@ pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: u */ #[inline] #[cfg(target_word_size = "64")] -pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: uint) { - intrinsics::memcpy64(dst, src as *T, count as u64); +pub unsafe fn copy_nonoverlapping_memory>(dst: *mut T, + src: P, + count: uint) { + intrinsics::memcpy64(dst, + cast::transmute_immut_unsafe(src), + count as u64); } /** @@ -216,12 +241,6 @@ pub fn to_unsafe_ptr(thing: &T) -> *T { thing as *T } -/// Transform a const region pointer - &const T - to a const unsafe pointer - *const T. -#[inline] -pub fn to_const_unsafe_ptr(thing: &const T) -> *const T { - thing as *const T -} - /// Transform a mutable region pointer - &mut T - to a mutable unsafe pointer - *mut T. #[inline] pub fn to_mut_unsafe_ptr(thing: &mut T) -> *mut T { @@ -269,8 +288,10 @@ pub unsafe fn array_each(arr: **T, cb: &fn(*T)) { #[allow(missing_doc)] pub trait RawPtr { + fn null() -> Self; fn is_null(&self) -> bool; fn is_not_null(&self) -> bool; + fn to_uint(&self) -> uint; unsafe fn to_option(&self) -> Option<&T>; fn offset(&self, count: int) -> Self; unsafe fn offset_inbounds(self, count: int) -> Self; @@ -278,13 +299,21 @@ pub trait RawPtr { /// Extension methods for immutable pointers impl RawPtr for *T { + /// Returns the null pointer. + #[inline] + fn null() -> *T { null() } + /// Returns true if the pointer is equal to the null pointer. #[inline] - fn is_null(&self) -> bool { is_null(*self) } + fn is_null(&self) -> bool { *self == RawPtr::null() } /// Returns true if the pointer is not equal to the null pointer. #[inline] - fn is_not_null(&self) -> bool { is_not_null(*self) } + fn is_not_null(&self) -> bool { *self != RawPtr::null() } + + /// Returns the address of this pointer. + #[inline] + fn to_uint(&self) -> uint { *self as uint } /// /// Returns `None` if the pointer is null, or else returns the value wrapped @@ -317,13 +346,21 @@ unsafe fn offset_inbounds(self, count: int) -> *T { /// Extension methods for mutable pointers impl RawPtr for *mut T { + /// Returns the null pointer. + #[inline] + fn null() -> *mut T { mut_null() } + /// Returns true if the pointer is equal to the null pointer. #[inline] - fn is_null(&self) -> bool { is_null(*self) } + fn is_null(&self) -> bool { *self == RawPtr::null() } /// Returns true if the pointer is not equal to the null pointer. #[inline] - fn is_not_null(&self) -> bool { is_not_null(*self) } + fn is_not_null(&self) -> bool { *self != RawPtr::null() } + + /// Returns the address of this pointer. + #[inline] + fn to_uint(&self) -> uint { *self as uint } /// /// Returns `None` if the pointer is null, or else returns the value wrapped @@ -360,13 +397,38 @@ unsafe fn offset_inbounds(self, count: int) -> *mut T { // Equality for pointers #[cfg(not(test))] -impl Eq for *const T { +impl Eq for *T { + #[inline] + fn eq(&self, other: &*T) -> bool { + (*self as uint) == (*other as uint) + } + #[inline] + fn ne(&self, other: &*T) -> bool { !self.eq(other) } +} + +#[cfg(not(test))] +impl Eq for *mut T { #[inline] - fn eq(&self, other: &*const T) -> bool { + fn eq(&self, other: &*mut T) -> bool { (*self as uint) == (*other as uint) } #[inline] - fn ne(&self, other: &*const T) -> bool { !self.eq(other) } + fn ne(&self, other: &*mut T) -> bool { !self.eq(other) } +} + +// Equivalence for pointers +#[cfg(not(test))] +impl Equiv<*mut T> for *T { + fn equiv(&self, other: &*mut T) -> bool { + self.to_uint() == other.to_uint() + } +} + +#[cfg(not(test))] +impl Equiv<*T> for *mut T { + fn equiv(&self, other: &*T) -> bool { + self.to_uint() == other.to_uint() + } } // Equality for extern "C" fn pointers @@ -412,21 +474,41 @@ fn ne(&self, other: &extern "C" fn($($p),*) -> _R) -> bool { // Comparison for pointers #[cfg(not(test))] -impl Ord for *const T { +impl Ord for *T { + #[inline] + fn lt(&self, other: &*T) -> bool { + (*self as uint) < (*other as uint) + } + #[inline] + fn le(&self, other: &*T) -> bool { + (*self as uint) <= (*other as uint) + } + #[inline] + fn ge(&self, other: &*T) -> bool { + (*self as uint) >= (*other as uint) + } + #[inline] + fn gt(&self, other: &*T) -> bool { + (*self as uint) > (*other as uint) + } +} + +#[cfg(not(test))] +impl Ord for *mut T { #[inline] - fn lt(&self, other: &*const T) -> bool { + fn lt(&self, other: &*mut T) -> bool { (*self as uint) < (*other as uint) } #[inline] - fn le(&self, other: &*const T) -> bool { + fn le(&self, other: &*mut T) -> bool { (*self as uint) <= (*other as uint) } #[inline] - fn ge(&self, other: &*const T) -> bool { + fn ge(&self, other: &*mut T) -> bool { (*self as uint) >= (*other as uint) } #[inline] - fn gt(&self, other: &*const T) -> bool { + fn gt(&self, other: &*mut T) -> bool { (*self as uint) > (*other as uint) } } diff --git a/src/libstd/rt/borrowck.rs b/src/libstd/rt/borrowck.rs index cbac43f27c73b865aa0b1802a09e61eef0c63264..01269d0d386d9acad78487dbc39e58409fab4532 100644 --- a/src/libstd/rt/borrowck.rs +++ b/src/libstd/rt/borrowck.rs @@ -11,17 +11,18 @@ use cell::Cell; use c_str::ToCStr; use cast::transmute; -use libc::{c_char, size_t, STDERR_FILENO}; -use io; use io::{Writer, WriterUtil}; +use io; +use libc::{c_char, c_void, size_t, STDERR_FILENO}; use option::{Option, None, Some}; -use uint; +use ptr::RawPtr; use rt::env; use rt::local::Local; use rt::task::Task; -use str; use str::{OwnedStr, StrSlice}; +use str; use sys; +use uint; use unstable::raw; use vec::ImmutableVector; @@ -93,12 +94,12 @@ unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) { static ENABLE_DEBUG: bool = false; #[inline] -unsafe fn debug_borrow(tag: &'static str, - p: *const T, - old_bits: uint, - new_bits: uint, - filename: *c_char, - line: size_t) { +unsafe fn debug_borrow>(tag: &'static str, + p: P, + old_bits: uint, + new_bits: uint, + filename: *c_char, + line: size_t) { //! A useful debugging function that prints a pointer + tag + newline //! without allocating memory. @@ -106,15 +107,15 @@ unsafe fn debug_borrow(tag: &'static str, debug_borrow_slow(tag, p, old_bits, new_bits, filename, line); } - unsafe fn debug_borrow_slow(tag: &'static str, - p: *const T, - old_bits: uint, - new_bits: uint, - filename: *c_char, - line: size_t) { + unsafe fn debug_borrow_slow>(tag: &'static str, + p: P, + old_bits: uint, + new_bits: uint, + filename: *c_char, + line: size_t) { let dbg = STDERR_FILENO as io::fd_t; dbg.write_str(tag); - dbg.write_hex(p as uint); + dbg.write_hex(p.to_uint()); dbg.write_str(" "); dbg.write_hex(old_bits); dbg.write_str(" "); diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs index 7d59627ba399beba5837dd9fb37d635645e3344f..26a3b95abbee35eba74387371257b5447723e6d0 100644 --- a/src/libstd/rt/sched.rs +++ b/src/libstd/rt/sched.rs @@ -554,6 +554,7 @@ pub fn change_task_context(~self, let current_task: &mut Task = match sched.cleanup_job { Some(CleanupJob { task: ref task, _ }) => { + let task_ptr: *~Task = task; transmute_mut_region(*transmute_mut_unsafe(task)) } None => { diff --git a/src/libstd/to_bytes.rs b/src/libstd/to_bytes.rs index 198c09964bb6ff274354d4f8b559afeaaaf5a1ac..01f57c231dadef53cdab7b5ae1e8b05a6ead16b5 100644 --- a/src/libstd/to_bytes.rs +++ b/src/libstd/to_bytes.rs @@ -343,7 +343,14 @@ fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { // NB: raw-pointer IterBytes does _not_ dereference // to the target; it just gives you the pointer-bytes. -impl IterBytes for *const A { +impl IterBytes for *A { + #[inline] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (*self as uint).iter_bytes(lsb0, f) + } +} + +impl IterBytes for *mut A { #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { (*self as uint).iter_bytes(lsb0, f) diff --git a/src/libstd/util.rs b/src/libstd/util.rs index b46876ad3fe44db96389a84194f9be1ac2009680..5085f337d4bba216103ddf9f17c1505dca509123 100644 --- a/src/libstd/util.rs +++ b/src/libstd/util.rs @@ -54,8 +54,10 @@ pub fn swap(x: &mut T, y: &mut T) { let t: *mut T = &mut tmp; // Perform the swap, `&mut` pointers never alias - ptr::copy_nonoverlapping_memory(t, x, 1); - ptr::copy_nonoverlapping_memory(x, y, 1); + let x_raw: *mut T = x; + let y_raw: *mut T = y; + ptr::copy_nonoverlapping_memory(t, x_raw, 1); + ptr::copy_nonoverlapping_memory(x, y_raw, 1); ptr::copy_nonoverlapping_memory(y, t, 1); // y and t now point to the same thing, but we need to completely forget `tmp` diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 556842e6544e7791f385b50aa3633cc96a7ff9d3..8cd1b09468d46c721755f9e5cabc95335351be25 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -1122,14 +1122,7 @@ fn map(&self, f: &fn(t: &T) -> U) -> ~[U] { * foreign interop. */ #[inline] - fn as_imm_buf(&self, - /* NB---this CANNOT be const, see below */ - f: &fn(*T, uint) -> U) -> U { - // NB---Do not change the type of s to `&const [T]`. This is - // unsound. The reason is that we are going to create immutable pointers - // into `s` and pass them to `f()`, but in fact they are potentially - // pointing at *mutable memory*. Use `as_mut_buf` instead! - + fn as_imm_buf(&self, f: &fn(*T, uint) -> U) -> U { let s = self.repr(); f(s.data, s.len / sys::nonzero_size_of::()) } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index f09c7427ecc7f1c1241f955842a220ab71bbce87..8ae9453cf1113c2cdc07ee7681a3ed023b707b84 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -298,7 +298,10 @@ pub enum pat_ { } #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] -pub enum mutability { m_mutbl, m_imm, m_const, } +pub enum mutability { + m_mutbl, + m_imm, +} #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] pub enum Sigil { diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 989a796cbc9127f800b01d8f9ff4cb1d1e18dcdb..ab1bde3a3b9eb357c0089d832c353ff9121e43d9 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -53,7 +53,6 @@ pub enum ObsoleteSyntax { ObsoleteMode, ObsoleteImplicitSelf, ObsoleteLifetimeNotation, - ObsoleteConstManagedPointer, ObsoletePurity, ObsoleteStaticMethod, ObsoleteConstItem, @@ -65,6 +64,7 @@ pub enum ObsoleteSyntax { ObsoleteUnsafeExternFn, ObsoletePrivVisibility, ObsoleteTraitFuncVisibility, + ObsoleteConstPointer, } impl to_bytes::IterBytes for ObsoleteSyntax { @@ -201,10 +201,6 @@ fn obsolete(&self, sp: span, kind: ObsoleteSyntax) { "instead of `&foo/bar`, write `&'foo bar`; instead of \ `bar/&foo`, write `&bar<'foo>" ), - ObsoleteConstManagedPointer => ( - "const `@` pointer", - "instead of `@const Foo`, write `@Foo`" - ), ObsoletePurity => ( "pure function", "remove `pure`" @@ -255,6 +251,11 @@ fn obsolete(&self, sp: span, kind: ObsoleteSyntax) { "visibility not necessary", "trait functions inherit the visibility of the trait itself" ), + ObsoleteConstPointer => ( + "const pointer", + "instead of `&const Foo` or `@const Foo`, write `&Foo` or \ + `@Foo`" + ), }; self.report(sp, kind, kind_str, desc); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 9aa2bf3f0633edb9091068c8e006e823cd503128..fe5e98d6036615e4e8b65702d42f39a1de5cf70b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -38,7 +38,7 @@ use ast::{item_enum, item_fn, item_foreign_mod, item_impl}; use ast::{item_mac, item_mod, item_struct, item_trait, item_ty, lit, lit_}; use ast::{lit_bool, lit_float, lit_float_unsuffixed, lit_int}; -use ast::{lit_int_unsuffixed, lit_nil, lit_str, lit_uint, Local, m_const}; +use ast::{lit_int_unsuffixed, lit_nil, lit_str, lit_uint, Local}; use ast::{m_imm, m_mutbl, mac_, mac_invoc_tt, matcher, match_nonterminal}; use ast::{match_seq, match_tok, method, mt, mul, mutability}; use ast::{named_field, neg, NodeId, noreturn, not, pat, pat_box, pat_enum}; @@ -1153,9 +1153,6 @@ pub fn parse_box_or_uniq_pointee(&self, if mt.mutbl != m_imm && sigil == OwnedSigil { self.obsolete(*self.last_span, ObsoleteMutOwnedPointer); } - if mt.mutbl == m_const && sigil == ManagedSigil { - self.obsolete(*self.last_span, ObsoleteConstManagedPointer); - } ctor(mt) } @@ -1568,7 +1565,8 @@ pub fn parse_mutability(&self) -> mutability { if self.eat_keyword(keywords::Mut) { m_mutbl } else if self.eat_keyword(keywords::Const) { - m_const + self.obsolete(*self.last_span, ObsoleteConstPointer); + m_imm } else { m_imm } @@ -1727,7 +1725,7 @@ pub fn parse_bottom_expr(&self) -> @expr { } else if *self.token == token::LBRACKET { self.bump(); let mutbl = self.parse_mutability(); - if mutbl == m_mutbl || mutbl == m_const { + if mutbl == m_mutbl { self.obsolete(*self.last_span, ObsoleteMutVector); } @@ -2182,10 +2180,6 @@ pub fn parse_prefix_expr(&self) -> @expr { token::AT => { self.bump(); let m = self.parse_mutability(); - if m == m_const { - self.obsolete(*self.last_span, ObsoleteConstManagedPointer); - } - let e = self.parse_prefix_expr(); hi = e.span.hi; // HACK: turn @[...] into a @-evec diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 3bad1ed93842d5d41b997805fa5ce92114fef8a8..ee9b2f4760dbfe2306e853de227bb9d265f1d692 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -386,7 +386,6 @@ pub fn print_type(s: @ps, ty: &ast::Ty) { word(s.s, "["); match mt.mutbl { ast::m_mutbl => word_space(s, "mut"), - ast::m_const => word_space(s, "const"), ast::m_imm => () } print_type(s, mt.ty); @@ -429,7 +428,6 @@ pub fn print_type(s: @ps, ty: &ast::Ty) { word(s.s, "["); match mt.mutbl { ast::m_mutbl => word_space(s, "mut"), - ast::m_const => word_space(s, "const"), ast::m_imm => () } print_type(s, mt.ty); @@ -1882,7 +1880,6 @@ pub fn print_view_item(s: @ps, item: &ast::view_item) { pub fn print_mutability(s: @ps, mutbl: ast::mutability) { match mutbl { ast::m_mutbl => word_nbsp(s, "mut"), - ast::m_const => word_nbsp(s, "const"), ast::m_imm => {/* nothing */ } } } diff --git a/src/test/compile-fail/borrowck-alias-mut-base-ptr.rs b/src/test/compile-fail/borrowck-alias-mut-base-ptr.rs deleted file mode 100644 index c51cf5b9538d9309a45cbcb2583e1dc2854f2071..0000000000000000000000000000000000000000 --- a/src/test/compile-fail/borrowck-alias-mut-base-ptr.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Test that attempt to alias `&mut` pointer while pointee is borrowed -// yields an error. -// -// Example from src/middle/borrowck/doc.rs - -use std::util::swap; - -fn foo(t0: &mut int) { - let p: &int = &*t0; // Freezes `*t0` - let q: &const &mut int = &const t0; //~ ERROR cannot borrow `t0` - **q = 22; //~ ERROR cannot assign to an `&mut` in a `&const` pointer -} - -fn main() { -} \ No newline at end of file diff --git a/src/test/compile-fail/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs b/src/test/compile-fail/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs index 7e9c298ba4732582e7b4ed8799e59f5604290055..843b5436d842c7c89322641dc8c0c70a501df5ef 100644 --- a/src/test/compile-fail/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs +++ b/src/test/compile-fail/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs @@ -11,16 +11,6 @@ fn foo(t0: & &mut int) { **t1 = 22; //~ ERROR cannot assign } -fn foo2(t0: &const &mut int) { - // Note: reborrowing from an &const actually yields two errors, since it - // is unsafe in two ways: we can't control the aliasing, and we can't - // control the mutation. - let t1 = t0; - let p: &int = &**t0; //~ ERROR cannot borrow an `&mut` in a `&const` pointer - //~^ ERROR unsafe borrow of aliasable, const value - **t1 = 22; //~ ERROR cannot assign -} - fn foo3(t0: &mut &mut int) { let t1 = &mut *t0; let p: &int = &**t0; //~ ERROR cannot borrow @@ -28,4 +18,4 @@ fn foo3(t0: &mut &mut int) { } fn main() { -} \ No newline at end of file +} diff --git a/src/test/compile-fail/borrowck-call-method-from-mut-aliasable.rs b/src/test/compile-fail/borrowck-call-method-from-mut-aliasable.rs index 0aa7cbf50b7a327e8a2ec1df94d33123811cadda..537e52120d9f1f2c02712f0037ec5aaf6dc55d65 100644 --- a/src/test/compile-fail/borrowck-call-method-from-mut-aliasable.rs +++ b/src/test/compile-fail/borrowck-call-method-from-mut-aliasable.rs @@ -14,29 +14,18 @@ struct Foo { impl Foo { pub fn f(&self) {} - pub fn g(&const self) {} pub fn h(&mut self) {} } fn a(x: &mut Foo) { x.f(); - x.g(); x.h(); } fn b(x: &Foo) { x.f(); - x.g(); x.h(); //~ ERROR cannot borrow } -fn c(x: &const Foo) { - x.f(); //~ ERROR cannot borrow - //~^ ERROR unsafe borrow - x.g(); - x.h(); //~ ERROR cannot borrow - //~^ ERROR unsafe borrow -} - fn main() { } diff --git a/src/test/compile-fail/borrowck-lend-flow.rs b/src/test/compile-fail/borrowck-lend-flow.rs index 59cac0c5d953a8f8f180f4d533c15ff5eac32d99..ea840a28b4e6ac97efd6fe7ebb3af8bbcbe691a9 100644 --- a/src/test/compile-fail/borrowck-lend-flow.rs +++ b/src/test/compile-fail/borrowck-lend-flow.rs @@ -32,14 +32,6 @@ fn pre_freeze() { borrow_mut(v); //~ ERROR cannot borrow } -fn pre_const() { - // In this instance, the freeze starts before the mut borrow. - - let mut v = ~3; - let _w = &const v; - borrow_mut(v); -} - fn post_freeze() { // In this instance, the const alias starts after the borrow. diff --git a/src/test/compile-fail/borrowck-loan-vec-content.rs b/src/test/compile-fail/borrowck-loan-vec-content.rs index 6a8e64377aab22898a4afd171b5a370c8952cc51..8a4a2cdedb23095987208afbdf2383b9e9c1722f 100644 --- a/src/test/compile-fail/borrowck-loan-vec-content.rs +++ b/src/test/compile-fail/borrowck-loan-vec-content.rs @@ -29,16 +29,5 @@ fn has_mut_vec_but_tries_to_change_it() { } } -fn takes_const_elt(_v: &const int, f: &fn()) { - f(); -} - -fn has_mut_vec_and_tries_to_change_it() { - let mut v = ~[1, 2, 3]; - do takes_const_elt(&const v[0]) { - v[1] = 4; - } -} - fn main() { } diff --git a/src/test/compile-fail/borrowck-pat-by-value-binding.rs b/src/test/compile-fail/borrowck-pat-by-value-binding.rs deleted file mode 100644 index e77f5245d7d8bb14906e6343d1d918599c2e58e2..0000000000000000000000000000000000000000 --- a/src/test/compile-fail/borrowck-pat-by-value-binding.rs +++ /dev/null @@ -1,45 +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. - -fn process(_t: T) {} - -fn match_const_opt_by_mut_ref(v: &const Option) { - match *v { - Some(ref mut i) => process(i), //~ ERROR cannot borrow - //~^ ERROR unsafe borrow of aliasable, const value - None => () - } -} - -fn match_const_opt_by_const_ref(v: &const Option) { - match *v { - Some(ref const i) => process(i), - //~^ ERROR unsafe borrow of aliasable, const value - None => () - } -} - -fn match_const_opt_by_imm_ref(v: &const Option) { - match *v { - Some(ref i) => process(i), //~ ERROR cannot borrow - //~^ ERROR unsafe borrow of aliasable, const value - None => () - } -} - -fn match_const_opt_by_value(v: &const Option) { - match *v { - Some(i) => process(i), - None => () - } -} - -fn main() { -} diff --git a/src/test/compile-fail/borrowck-uniq-via-lend.rs b/src/test/compile-fail/borrowck-uniq-via-lend.rs index 43459acaaf1850d6ee6d01c088fa319bafd86d14..c87428cd300a7ab47bdcb7ca2dc4cac3d0397660 100644 --- a/src/test/compile-fail/borrowck-uniq-via-lend.rs +++ b/src/test/compile-fail/borrowck-uniq-via-lend.rs @@ -35,12 +35,6 @@ fn aliased_imm() { borrow(v); } -fn aliased_const() { - let mut v = ~3; - let _w = &const v; - borrow(v); -} - fn aliased_mut() { let mut v = ~3; let _w = &mut v; diff --git a/src/test/compile-fail/fn-variance-3.rs b/src/test/compile-fail/fn-variance-3.rs index 630eb4b538d58bc93070efde8e8e65a75fb45b28..e42c6b658e4f7b87b5307935c361bc1702e3f940 100644 --- a/src/test/compile-fail/fn-variance-3.rs +++ b/src/test/compile-fail/fn-variance-3.rs @@ -23,13 +23,10 @@ fn main() { // @int <: X // - // This constraint forces X to be - // @const int. - r(@3); + // Here the type check fails because @const is gone and there is no + // supertype. + r(@3); //~ ERROR mismatched types - // Here the type check succeeds but the - // mutability check will fail, because the - // type of r has been inferred to be - // fn(@const int) -> @const int - *r(@mut 3) = 4; //~ ERROR cannot assign to const dereference of @ pointer + // Here the type check succeeds. + *r(@mut 3) = 4; } diff --git a/src/test/compile-fail/issue-3969.rs b/src/test/compile-fail/issue-3969.rs deleted file mode 100644 index b60a54a44bbfdf853fe8874151597b6688813439..0000000000000000000000000000000000000000 --- a/src/test/compile-fail/issue-3969.rs +++ /dev/null @@ -1,25 +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. - -struct Bike { - name: ~str, -} - -trait BikeMethods { - fn woops(&const self) -> ~str; -} - -impl BikeMethods for Bike { - fn woops() -> ~str { ~"foo" } - //~^ ERROR has a `&const self` declaration in the trait, but not in the impl -} - -pub fn main() { -} diff --git a/src/test/compile-fail/mutable-huh-ptr-assign.rs b/src/test/compile-fail/mutable-huh-ptr-assign.rs deleted file mode 100644 index 4460da72e205993ac9e03025a6a9e126502079a0..0000000000000000000000000000000000000000 --- a/src/test/compile-fail/mutable-huh-ptr-assign.rs +++ /dev/null @@ -1,23 +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. - -extern mod extra; - -fn main() { - unsafe fn f(v: *const int) { - *v = 1 //~ ERROR cannot assign - } - - unsafe { - let mut a = 0; - let v = &mut a; - f(v); - } -} diff --git a/src/test/compile-fail/resolve-inconsistent-binding-mode.rs b/src/test/compile-fail/resolve-inconsistent-binding-mode.rs index 65fbbfc6e198582698c20c8084fe73475a2ab936..351daf461d2fea5bfbaf26ca1cbb923c7bb501d6 100644 --- a/src/test/compile-fail/resolve-inconsistent-binding-mode.rs +++ b/src/test/compile-fail/resolve-inconsistent-binding-mode.rs @@ -26,13 +26,6 @@ fn matcher2(x: opts) { } } -fn matcher3(x: opts) { - match x { - a(ref mut i) | b(ref const i) => {} //~ ERROR variable `i` is bound with different mode in pattern #2 than in pattern #1 - c(_) => {} - } -} - fn matcher4(x: opts) { match x { a(ref mut i) | b(ref i) => {} //~ ERROR variable `i` is bound with different mode in pattern #2 than in pattern #1 diff --git a/src/test/run-pass/auto-ref-slice-plus-ref.rs b/src/test/run-pass/auto-ref-slice-plus-ref.rs index 58a477900c3248113495824c2ca5d685d8195516..d35341516f2a73d5b3ab86420cdd5e65587e2d9e 100644 --- a/src/test/run-pass/auto-ref-slice-plus-ref.rs +++ b/src/test/run-pass/auto-ref-slice-plus-ref.rs @@ -13,17 +13,14 @@ trait MyIter { fn test_imm(&self); - fn test_const(&const self); } impl<'self> MyIter for &'self [int] { fn test_imm(&self) { assert_eq!(self[0], 1) } - fn test_const(&const self) { assert_eq!(self[0], 1) } } impl<'self> MyIter for &'self str { fn test_imm(&self) { assert_eq!(*self, "test") } - fn test_const(&const self) { assert_eq!(self[0], 't' as u8) } } pub fn main() { @@ -40,15 +37,6 @@ pub fn main() { // XXX: Other types of mutable vecs don't currently exist - ([1]).test_const(); - (~[1]).test_const(); - (@[1]).test_const(); - (&[1]).test_const(); - ("test").test_const(); - (~"test").test_const(); - (@"test").test_const(); - (&"test").test_const(); - // NB: We don't do this double autoreffing for &mut self because that would // allow creating a mutable pointer to a temporary, which would be a source // of confusion diff --git a/src/test/run-pass/autoderef-and-borrow-method-receiver.rs b/src/test/run-pass/autoderef-and-borrow-method-receiver.rs index b00d8980c69fefbb56eb2be088a7793dbcda5671..fc643ec594089a4cc62f9eca2343f6e4afc6ee01 100644 --- a/src/test/run-pass/autoderef-and-borrow-method-receiver.rs +++ b/src/test/run-pass/autoderef-and-borrow-method-receiver.rs @@ -13,7 +13,7 @@ struct Foo { } impl Foo { - pub fn f(&const self) {} + pub fn f(&self) {} } fn g(x: &mut Foo) { diff --git a/src/test/compile-fail/borrowck-pat-enum.rs b/src/test/run-pass/borrowck-pat-enum.rs similarity index 65% rename from src/test/compile-fail/borrowck-pat-enum.rs rename to src/test/run-pass/borrowck-pat-enum.rs index f1cca89b227d6773c59340949b31dbe3c8e7c7c9..6c00bea28b6e3b6e5ab6d1d02acee0c71b0b9d8c 100644 --- a/src/test/compile-fail/borrowck-pat-enum.rs +++ b/src/test/run-pass/borrowck-pat-enum.rs @@ -24,32 +24,9 @@ fn match_ref_unused(v: Option) { } } -fn match_const_reg(v: &const Option) -> int { - match *v { - Some(ref i) => {*i} //~ ERROR cannot borrow - //~^ ERROR unsafe borrow - None => {0} - } -} - fn impure(_i: int) { } -fn match_const_reg_unused(v: &const Option) { - match *v { - Some(_) => {impure(0)} // OK because nothing is captured - None => {} - } -} - -fn match_const_reg_impure(v: &const Option) { - match *v { - Some(ref i) => {impure(*i)} //~ ERROR cannot borrow - //~^ ERROR unsafe borrow - None => {} - } -} - fn match_imm_reg(v: &Option) { match *v { Some(ref i) => {impure(*i)} // OK because immutable diff --git a/src/test/compile-fail/borrowck-uniq-via-ref.rs b/src/test/run-pass/borrowck-uniq-via-ref.rs similarity index 77% rename from src/test/compile-fail/borrowck-uniq-via-ref.rs rename to src/test/run-pass/borrowck-uniq-via-ref.rs index 8bf627d991911343b24ed042b99581677cf03327..44f3a8f518a15c44273230efbb3f8c8de49bb770 100644 --- a/src/test/compile-fail/borrowck-uniq-via-ref.rs +++ b/src/test/run-pass/borrowck-uniq-via-ref.rs @@ -25,7 +25,6 @@ struct Innermost { } fn borrow(_v: &int) {} -fn borrow_const(_v: &const int) {} fn box_mut(v: &mut ~int) { borrow(*v); // OK: &mut -> &imm @@ -51,17 +50,5 @@ fn box_imm_recs(v: &Outer) { borrow(v.f.g.h); // OK } -fn box_const(v: &const ~int) { - borrow_const(*v); //~ ERROR unsafe borrow -} - -fn box_const_rec(v: &const Rec) { - borrow_const(v.f); //~ ERROR unsafe borrow -} - -fn box_const_recs(v: &const Outer) { - borrow_const(v.f.g.h); //~ ERROR unsafe borrow -} - fn main() { } 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 01907da38ad9da818df8b0f3b5e1aebf6c02c2af..03dd33b08e2350fe167a8421038f78678ebab177 100644 --- a/src/test/run-pass/class-impl-very-parameterized-trait.rs +++ b/src/test/run-pass/class-impl-very-parameterized-trait.rs @@ -49,8 +49,8 @@ pub fn eat(&mut self) -> bool { } impl Container for cat { - fn len(&const self) -> uint { self.meows as uint } - fn is_empty(&const self) -> bool { self.meows == 0 } + fn len(&self) -> uint { self.meows as uint } + fn is_empty(&self) -> bool { self.meows == 0 } } impl Mutable for cat { diff --git a/src/test/run-pass/coerce-reborrow-imm-ptr-rcvr.rs b/src/test/run-pass/coerce-reborrow-imm-ptr-rcvr.rs index 5525062581c1a6676b9caf575e1bebc750872ffe..52fa1399363cdf4de434167400dce4ee8bbb49c3 100644 --- a/src/test/run-pass/coerce-reborrow-imm-ptr-rcvr.rs +++ b/src/test/run-pass/coerce-reborrow-imm-ptr-rcvr.rs @@ -3,14 +3,14 @@ struct SpeechMaker { } impl SpeechMaker { - pub fn how_many(&const self) -> uint { self.speeches } + pub fn how_many(&self) -> uint { self.speeches } } -fn foo(speaker: &const SpeechMaker) -> uint { +fn foo(speaker: &SpeechMaker) -> uint { speaker.how_many() + 33 } pub fn main() { let lincoln = SpeechMaker {speeches: 22}; - assert_eq!(foo(&const lincoln), 55); + assert_eq!(foo(&lincoln), 55); } diff --git a/src/test/run-pass/const-vec-syntax.rs b/src/test/run-pass/const-vec-syntax.rs index 625f6ec30cc13657b3a92490bf89111c90081c83..84ee54cfdde6d548203c8ba43e7b09f61f17ad27 100644 --- a/src/test/run-pass/const-vec-syntax.rs +++ b/src/test/run-pass/const-vec-syntax.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn f(_: &const [int]) {} +fn f(_: &[int]) {} pub fn main() { let v = [ 1, 2, 3 ];