提交 5c350479 编写于 作者: P Patrick Walton

librustc: Remove `&const` and `*const` from the language.

They are still present as part of the borrow check.
上级 58d6eb50
...@@ -25,13 +25,13 @@ pub mod rustrt { ...@@ -25,13 +25,13 @@ pub mod rustrt {
#[link_name = "rustrt"] #[link_name = "rustrt"]
extern { 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, src_buf_len: size_t,
pout_len: *mut size_t, pout_len: *mut size_t,
flags: c_int) flags: c_int)
-> *c_void; -> *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, src_buf_len: size_t,
pout_len: *mut size_t, pout_len: *mut size_t,
flags: c_int) flags: c_int)
......
...@@ -804,12 +804,9 @@ pub fn get_enum_variants(intr: @ident_interner, cdata: cmd, id: ast::NodeId, ...@@ -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_explicit_self(item: ebml::Doc) -> ast::explicit_self_ {
fn get_mutability(ch: u8) -> ast::mutability { fn get_mutability(ch: u8) -> ast::mutability {
match ch as char { match ch as char {
'i' => { ast::m_imm } 'i' => ast::m_imm,
'm' => { ast::m_mutbl } 'm' => ast::m_mutbl,
'c' => { ast::m_const } _ => fail!("unknown mutability character: `%c`", ch as char),
_ => {
fail!("unknown mutability character: `%c`", ch as char)
}
} }
} }
......
...@@ -635,15 +635,8 @@ fn encode_explicit_self(ebml_w: &mut writer::Encoder, explicit_self: ast::explic ...@@ -635,15 +635,8 @@ fn encode_explicit_self(ebml_w: &mut writer::Encoder, explicit_self: ast::explic
fn encode_mutability(ebml_w: &writer::Encoder, fn encode_mutability(ebml_w: &writer::Encoder,
m: ast::mutability) { m: ast::mutability) {
match m { match m {
m_imm => { m_imm => ebml_w.writer.write(&[ 'i' as u8 ]),
ebml_w.writer.write(&[ 'i' as u8 ]); m_mutbl => ebml_w.writer.write(&[ 'm' as u8 ]),
}
m_mutbl => {
ebml_w.writer.write(&[ 'm' as u8 ]);
}
m_const => {
ebml_w.writer.write(&[ 'c' as u8 ]);
}
} }
} }
} }
......
...@@ -417,7 +417,6 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t { ...@@ -417,7 +417,6 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
fn parse_mutability(st: &mut PState) -> ast::mutability { fn parse_mutability(st: &mut PState) -> ast::mutability {
match peek(st) { match peek(st) {
'm' => { next(st); ast::m_mutbl } 'm' => { next(st); ast::m_mutbl }
'?' => { next(st); ast::m_const }
_ => { ast::m_imm } _ => { ast::m_imm }
} }
} }
......
...@@ -99,7 +99,6 @@ fn enc_mutability(w: @io::Writer, mt: ast::mutability) { ...@@ -99,7 +99,6 @@ fn enc_mutability(w: @io::Writer, mt: ast::mutability) {
match mt { match mt {
m_imm => (), m_imm => (),
m_mutbl => w.write_char('m'), m_mutbl => w.write_char('m'),
m_const => w.write_char('?')
} }
} }
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
use middle::borrowck::*; use middle::borrowck::*;
use middle::moves; use middle::moves;
use middle::ty; use middle::ty;
use syntax::ast::{m_mutbl, m_imm, m_const}; use syntax::ast::m_mutbl;
use syntax::ast; use syntax::ast;
use syntax::ast_util; use syntax::ast_util;
use syntax::codemap::span; use syntax::codemap::span;
...@@ -220,9 +220,9 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self, ...@@ -220,9 +220,9 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
// Restrictions that would cause the new loan to be illegal: // Restrictions that would cause the new loan to be illegal:
let illegal_if = match loan2.mutbl { let illegal_if = match loan2.mutbl {
m_mutbl => RESTR_ALIAS | RESTR_FREEZE | RESTR_CLAIM, MutableMutability => RESTR_ALIAS | RESTR_FREEZE | RESTR_CLAIM,
m_imm => RESTR_ALIAS | RESTR_FREEZE, ImmutableMutability => RESTR_ALIAS | RESTR_FREEZE,
m_const => RESTR_ALIAS, ConstMutability => RESTR_ALIAS,
}; };
debug!("illegal_if=%?", illegal_if); debug!("illegal_if=%?", illegal_if);
...@@ -231,7 +231,7 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self, ...@@ -231,7 +231,7 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
if restr.loan_path != loan2.loan_path { loop; } if restr.loan_path != loan2.loan_path { loop; }
match (new_loan.mutbl, old_loan.mutbl) { match (new_loan.mutbl, old_loan.mutbl) {
(m_mutbl, m_mutbl) => { (MutableMutability, MutableMutability) => {
self.bccx.span_err( self.bccx.span_err(
new_loan.span, new_loan.span,
fmt!("cannot borrow `%s` as mutable \ fmt!("cannot borrow `%s` as mutable \
...@@ -582,7 +582,6 @@ fn check_for_assignment_to_restricted_or_frozen_location( ...@@ -582,7 +582,6 @@ fn check_for_assignment_to_restricted_or_frozen_location(
// Otherwise stop iterating // Otherwise stop iterating
LpExtend(_, mc::McDeclared, _) | LpExtend(_, mc::McDeclared, _) |
LpExtend(_, mc::McImmutable, _) | LpExtend(_, mc::McImmutable, _) |
LpExtend(_, mc::McReadOnly, _) |
LpVar(_) => { LpVar(_) => {
return true; return true;
} }
...@@ -590,8 +589,11 @@ fn check_for_assignment_to_restricted_or_frozen_location( ...@@ -590,8 +589,11 @@ fn check_for_assignment_to_restricted_or_frozen_location(
// Check for a non-const loan of `loan_path` // Check for a non-const loan of `loan_path`
let cont = do this.each_in_scope_loan(expr.id) |loan| { let cont = do this.each_in_scope_loan(expr.id) |loan| {
if loan.loan_path == loan_path && loan.mutbl != m_const { if loan.loan_path == loan_path &&
this.report_illegal_mutation(expr, full_loan_path, loan); loan.mutbl != ConstMutability {
this.report_illegal_mutation(expr,
full_loan_path,
loan);
false false
} else { } else {
true true
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
use middle::borrowck::*; use middle::borrowck::*;
use mc = middle::mem_categorization; use mc = middle::mem_categorization;
use middle::ty; use middle::ty;
use syntax::ast::{m_const, m_imm, m_mutbl}; use syntax::ast::{m_imm, m_mutbl};
use syntax::ast; use syntax::ast;
use syntax::codemap::span; use syntax::codemap::span;
use util::ppaux::{note_and_explain_region}; use util::ppaux::{note_and_explain_region};
...@@ -26,7 +26,7 @@ pub fn guarantee_lifetime(bccx: @BorrowckCtxt, ...@@ -26,7 +26,7 @@ pub fn guarantee_lifetime(bccx: @BorrowckCtxt,
span: span, span: span,
cmt: mc::cmt, cmt: mc::cmt,
loan_region: ty::Region, loan_region: ty::Region,
loan_mutbl: ast::mutability) { loan_mutbl: LoanMutability) {
debug!("guarantee_lifetime(cmt=%s, loan_region=%s)", debug!("guarantee_lifetime(cmt=%s, loan_region=%s)",
cmt.repr(bccx.tcx), loan_region.repr(bccx.tcx)); cmt.repr(bccx.tcx), loan_region.repr(bccx.tcx));
let ctxt = GuaranteeLifetimeContext {bccx: bccx, let ctxt = GuaranteeLifetimeContext {bccx: bccx,
...@@ -54,7 +54,7 @@ struct GuaranteeLifetimeContext { ...@@ -54,7 +54,7 @@ struct GuaranteeLifetimeContext {
span: span, span: span,
loan_region: ty::Region, loan_region: ty::Region,
loan_mutbl: ast::mutability, loan_mutbl: LoanMutability,
cmt_original: mc::cmt cmt_original: mc::cmt
} }
...@@ -235,11 +235,11 @@ fn check_root(&self, ...@@ -235,11 +235,11 @@ fn check_root(&self,
// we need to dynamically mark it to prevent incompatible // we need to dynamically mark it to prevent incompatible
// borrows from happening later. // borrows from happening later.
let opt_dyna = match ptr_mutbl { let opt_dyna = match ptr_mutbl {
m_imm | m_const => None, m_imm => None,
m_mutbl => { m_mutbl => {
match self.loan_mutbl { match self.loan_mutbl {
m_mutbl => Some(DynaMut), MutableMutability => Some(DynaMut),
m_imm | m_const => Some(DynaImm) ImmutableMutability | ConstMutability => Some(DynaImm)
} }
} }
}; };
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
use util::common::indenter; use util::common::indenter;
use util::ppaux::{Repr}; use util::ppaux::{Repr};
use syntax::ast::{m_const, m_imm, m_mutbl};
use syntax::ast; use syntax::ast;
use syntax::ast_util::id_range; use syntax::ast_util::id_range;
use syntax::codemap::span; use syntax::codemap::span;
...@@ -237,7 +236,11 @@ fn gather_loans_in_expr(v: &mut GatherLoanVisitor, ...@@ -237,7 +236,11 @@ fn gather_loans_in_expr(v: &mut GatherLoanVisitor,
// make sure that the thing we are pointing out stays valid // make sure that the thing we are pointing out stays valid
// for the lifetime `scope_r` of the resulting ptr: // for the lifetime `scope_r` of the resulting ptr:
let scope_r = ty_region(tcx, ex.span, ty::expr_ty(tcx, ex)); 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); visit::walk_expr(v, ex, this);
} }
...@@ -278,7 +281,11 @@ fn gather_loans_in_expr(v: &mut GatherLoanVisitor, ...@@ -278,7 +281,11 @@ fn gather_loans_in_expr(v: &mut GatherLoanVisitor,
// adjustments). // adjustments).
let scope_r = ty::re_scope(ex.id); let scope_r = ty::re_scope(ex.id);
let arg_cmt = this.bccx.cat_expr(arg); 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); visit::walk_expr(v, ex, this);
} }
...@@ -357,18 +364,22 @@ pub fn guarantee_adjustments(&mut self, ...@@ -357,18 +364,22 @@ pub fn guarantee_adjustments(&mut self,
match *autoref { match *autoref {
ty::AutoPtr(r, m) => { ty::AutoPtr(r, m) => {
let loan_mutability =
LoanMutability::from_ast_mutability(m);
self.guarantee_valid(expr.id, self.guarantee_valid(expr.id,
expr.span, expr.span,
cmt, cmt,
m, loan_mutability,
r) r)
} }
ty::AutoBorrowVec(r, m) | ty::AutoBorrowVecRef(r, m) => { ty::AutoBorrowVec(r, m) | ty::AutoBorrowVecRef(r, m) => {
let cmt_index = mcx.cat_index(expr, cmt, autoderefs+1); let cmt_index = mcx.cat_index(expr, cmt, autoderefs+1);
let loan_mutability =
LoanMutability::from_ast_mutability(m);
self.guarantee_valid(expr.id, self.guarantee_valid(expr.id,
expr.span, expr.span,
cmt_index, cmt_index,
m, loan_mutability,
r) r)
} }
ty::AutoBorrowFn(r) => { ty::AutoBorrowFn(r) => {
...@@ -376,7 +387,7 @@ pub fn guarantee_adjustments(&mut self, ...@@ -376,7 +387,7 @@ pub fn guarantee_adjustments(&mut self,
self.guarantee_valid(expr.id, self.guarantee_valid(expr.id,
expr.span, expr.span,
cmt_deref, cmt_deref,
m_imm, ImmutableMutability,
r) r)
} }
ty::AutoBorrowObj(r, m) => { ty::AutoBorrowObj(r, m) => {
...@@ -402,7 +413,7 @@ pub fn guarantee_valid(&mut self, ...@@ -402,7 +413,7 @@ pub fn guarantee_valid(&mut self,
borrow_id: ast::NodeId, borrow_id: ast::NodeId,
borrow_span: span, borrow_span: span,
cmt: mc::cmt, cmt: mc::cmt,
req_mutbl: ast::mutability, req_mutbl: LoanMutability,
loan_region: ty::Region) { loan_region: ty::Region) {
debug!("guarantee_valid(borrow_id=%?, cmt=%s, \ debug!("guarantee_valid(borrow_id=%?, cmt=%s, \
req_mutbl=%?, loan_region=%?)", req_mutbl=%?, loan_region=%?)",
...@@ -473,7 +484,7 @@ pub fn guarantee_valid(&mut self, ...@@ -473,7 +484,7 @@ pub fn guarantee_valid(&mut self,
let kill_scope = self.compute_kill_scope(loan_scope, loan_path); let kill_scope = self.compute_kill_scope(loan_scope, loan_path);
debug!("kill_scope = %?", kill_scope); debug!("kill_scope = %?", kill_scope);
if req_mutbl == m_mutbl { if req_mutbl == MutableMutability {
self.mark_loan_path_as_mutated(loan_path); self.mark_loan_path_as_mutated(loan_path);
} }
...@@ -516,7 +527,7 @@ pub fn guarantee_valid(&mut self, ...@@ -516,7 +527,7 @@ pub fn guarantee_valid(&mut self,
// index: all_loans.len(), // index: all_loans.len(),
// loan_path: loan_path, // loan_path: loan_path,
// cmt: cmt, // cmt: cmt,
// mutbl: m_const, // mutbl: ConstMutability,
// gen_scope: borrow_id, // gen_scope: borrow_id,
// kill_scope: kill_scope, // kill_scope: kill_scope,
// span: borrow_span, // span: borrow_span,
...@@ -527,29 +538,20 @@ pub fn guarantee_valid(&mut self, ...@@ -527,29 +538,20 @@ pub fn guarantee_valid(&mut self,
fn check_mutability(bccx: @BorrowckCtxt, fn check_mutability(bccx: @BorrowckCtxt,
borrow_span: span, borrow_span: span,
cmt: mc::cmt, cmt: mc::cmt,
req_mutbl: ast::mutability) { req_mutbl: LoanMutability) {
//! Implements the M-* rules in doc.rs. //! Implements the M-* rules in doc.rs.
match req_mutbl { match req_mutbl {
m_const => { ConstMutability => {
// Data of any mutability can be lent as const. // Data of any mutability can be lent as const.
} }
m_imm => { ImmutableMutability => {
match cmt.mutbl { // both imm and mut data can be lent as imm;
mc::McImmutable | mc::McDeclared | mc::McInherited => { // for mutable data, this is a freeze
// 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)});
}
}
} }
m_mutbl => { MutableMutability => {
// Only mutable data can be lent as mutable. // Only mutable data can be lent as mutable.
if !cmt.mutbl.is_mutable() { if !cmt.mutbl.is_mutable() {
bccx.report(BckError {span: borrow_span, bccx.report(BckError {span: borrow_span,
...@@ -561,12 +563,14 @@ fn check_mutability(bccx: @BorrowckCtxt, ...@@ -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 { -> RestrictionSet {
match req_mutbl { match req_mutbl {
m_const => RESTR_EMPTY, ConstMutability => RESTR_EMPTY,
m_imm => RESTR_EMPTY | RESTR_MUTATE | RESTR_CLAIM, ImmutableMutability => RESTR_EMPTY | RESTR_MUTATE | RESTR_CLAIM,
m_mutbl => RESTR_EMPTY | RESTR_MUTATE | RESTR_CLAIM | RESTR_FREEZE MutableMutability => {
RESTR_EMPTY | RESTR_MUTATE | RESTR_CLAIM | RESTR_FREEZE
}
} }
} }
...@@ -582,8 +586,8 @@ pub fn mark_loan_path_as_mutated(&self, loan_path: @LoanPath) { ...@@ -582,8 +586,8 @@ pub fn mark_loan_path_as_mutated(&self, loan_path: @LoanPath) {
self.mark_loan_path_as_mutated(base); self.mark_loan_path_as_mutated(base);
} }
LpExtend(_, mc::McDeclared, _) | LpExtend(_, mc::McDeclared, _) |
LpExtend(_, mc::McImmutable, _) | LpExtend(_, mc::McImmutable, _) => {
LpExtend(_, mc::McReadOnly, _) => { // Nothing to do.
} }
} }
} }
...@@ -701,8 +705,13 @@ fn gather_pat(&mut self, ...@@ -701,8 +705,13 @@ fn gather_pat(&mut self,
} }
} }
}; };
self.guarantee_valid(pat.id, pat.span, let loan_mutability =
cmt_discr, mutbl, scope_r); LoanMutability::from_ast_mutability(mutbl);
self.guarantee_valid(pat.id,
pat.span,
cmt_discr,
loan_mutability,
scope_r);
} }
ast::bind_infer => { ast::bind_infer => {
// No borrows here, but there may be moves // No borrows here, but there may be moves
...@@ -725,6 +734,8 @@ fn gather_pat(&mut self, ...@@ -725,6 +734,8 @@ fn gather_pat(&mut self,
self.vec_slice_info(slice_pat, slice_ty); self.vec_slice_info(slice_pat, slice_ty);
let mcx = self.bccx.mc_ctxt(); let mcx = self.bccx.mc_ctxt();
let cmt_index = mcx.cat_index(slice_pat, cmt, 0); 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 // Note: We declare here that the borrow occurs upon
// entering the `[...]` pattern. This implies that // entering the `[...]` pattern. This implies that
...@@ -743,8 +754,11 @@ fn gather_pat(&mut self, ...@@ -743,8 +754,11 @@ fn gather_pat(&mut self,
// trans do the right thing, and it would only work // trans do the right thing, and it would only work
// for `~` vectors. It seems simpler to just require // for `~` vectors. It seems simpler to just require
// that people call `vec.pop()` or `vec.unshift()`. // that people call `vec.pop()` or `vec.unshift()`.
self.guarantee_valid(pat.id, pat.span, self.guarantee_valid(pat.id,
cmt_index, slice_mutbl, slice_r); pat.span,
cmt_index,
slice_loan_mutability,
slice_r);
} }
_ => {} _ => {}
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
use middle::borrowck::*; use middle::borrowck::*;
use mc = middle::mem_categorization; use mc = middle::mem_categorization;
use middle::ty; use middle::ty;
use syntax::ast::{m_const, m_imm, m_mutbl}; use syntax::ast::{m_imm, m_mutbl};
use syntax::codemap::span; use syntax::codemap::span;
pub enum RestrictionResult { pub enum RestrictionResult {
...@@ -121,13 +121,6 @@ fn restrict(&self, ...@@ -121,13 +121,6 @@ fn restrict(&self,
Safe 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)) => { mc::cat_deref(cmt_base, _, pk @ mc::gc_ptr(m_mutbl)) => {
// R-Deref-Managed-Borrowed // R-Deref-Managed-Borrowed
// //
......
...@@ -241,12 +241,39 @@ pub enum PartialTotal { ...@@ -241,12 +241,39 @@ pub enum PartialTotal {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Loans and loan paths // 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. /// Record of a loan that was issued.
pub struct Loan { pub struct Loan {
index: uint, index: uint,
loan_path: @LoanPath, loan_path: @LoanPath,
cmt: mc::cmt, cmt: mc::cmt,
mutbl: ast::mutability, mutbl: LoanMutability,
restrictions: ~[Restriction], restrictions: ~[Restriction],
gen_scope: ast::NodeId, gen_scope: ast::NodeId,
kill_scope: ast::NodeId, kill_scope: ast::NodeId,
...@@ -417,7 +444,7 @@ fn to_str(&self) -> ~str { ...@@ -417,7 +444,7 @@ fn to_str(&self) -> ~str {
// Errors that can occur // Errors that can occur
#[deriving(Eq)] #[deriving(Eq)]
pub enum bckerr_code { 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_root_scope(ty::Region, ty::Region), // superscope, subscope
err_out_of_scope(ty::Region, ty::Region), // superscope, subscope err_out_of_scope(ty::Region, ty::Region), // superscope, subscope
err_freeze_aliasable_const err_freeze_aliasable_const
...@@ -794,17 +821,14 @@ pub fn cmt_to_str(&self, cmt: mc::cmt) -> ~str { ...@@ -794,17 +821,14 @@ pub fn cmt_to_str(&self, cmt: mc::cmt) -> ~str {
mc.cmt_to_str(cmt) mc.cmt_to_str(cmt)
} }
pub fn mut_to_str(&self, mutbl: ast::mutability) -> ~str { pub fn mut_to_str(&self, mutbl: LoanMutability) -> ~str {
let mc = &mc::mem_categorization_ctxt {tcx: self.tcx, mutbl.to_str()
method_map: self.method_map};
mc.mut_to_str(mutbl)
} }
pub fn mut_to_keyword(&self, mutbl: ast::mutability) -> &'static str { pub fn mut_to_keyword(&self, mutbl: ast::mutability) -> &'static str {
match mutbl { match mutbl {
ast::m_imm => "", ast::m_imm => "",
ast::m_const => "const", ast::m_mutbl => "mut",
ast::m_mutbl => "mut"
} }
} }
} }
......
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
use util::ppaux::{ty_to_str, region_ptr_to_str, Repr}; use util::ppaux::{ty_to_str, region_ptr_to_str, Repr};
use util::common::indenter; 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::ast;
use syntax::codemap::span; use syntax::codemap::span;
use syntax::print::pprust; use syntax::print::pprust;
...@@ -113,7 +113,6 @@ pub enum ElementKind { ...@@ -113,7 +113,6 @@ pub enum ElementKind {
#[deriving(Eq, IterBytes)] #[deriving(Eq, IterBytes)]
pub enum MutabilityCategory { pub enum MutabilityCategory {
McImmutable, // Immutable. McImmutable, // Immutable.
McReadOnly, // Read-only (`const`)
McDeclared, // Directly declared as mutable. McDeclared, // Directly declared as mutable.
McInherited // Inherited from the fact that owner is mutable. McInherited // Inherited from the fact that owner is mutable.
} }
...@@ -297,7 +296,6 @@ impl MutabilityCategory { ...@@ -297,7 +296,6 @@ impl MutabilityCategory {
pub fn from_mutbl(m: ast::mutability) -> MutabilityCategory { pub fn from_mutbl(m: ast::mutability) -> MutabilityCategory {
match m { match m {
m_imm => McImmutable, m_imm => McImmutable,
m_const => McReadOnly,
m_mutbl => McDeclared m_mutbl => McDeclared
} }
} }
...@@ -305,7 +303,6 @@ pub fn from_mutbl(m: ast::mutability) -> MutabilityCategory { ...@@ -305,7 +303,6 @@ pub fn from_mutbl(m: ast::mutability) -> MutabilityCategory {
pub fn inherit(&self) -> MutabilityCategory { pub fn inherit(&self) -> MutabilityCategory {
match *self { match *self {
McImmutable => McImmutable, McImmutable => McImmutable,
McReadOnly => McReadOnly,
McDeclared => McInherited, McDeclared => McInherited,
McInherited => McInherited McInherited => McInherited
} }
...@@ -313,7 +310,7 @@ pub fn inherit(&self) -> MutabilityCategory { ...@@ -313,7 +310,7 @@ pub fn inherit(&self) -> MutabilityCategory {
pub fn is_mutable(&self) -> bool { pub fn is_mutable(&self) -> bool {
match *self { match *self {
McImmutable | McReadOnly => false, McImmutable => false,
McDeclared | McInherited => true McDeclared | McInherited => true
} }
} }
...@@ -321,7 +318,7 @@ pub fn is_mutable(&self) -> bool { ...@@ -321,7 +318,7 @@ pub fn is_mutable(&self) -> bool {
pub fn is_immutable(&self) -> bool { pub fn is_immutable(&self) -> bool {
match *self { match *self {
McImmutable => true, McImmutable => true,
McReadOnly | McDeclared | McInherited => false McDeclared | McInherited => false
} }
} }
...@@ -329,7 +326,6 @@ pub fn to_user_str(&self) -> &'static str { ...@@ -329,7 +326,6 @@ pub fn to_user_str(&self) -> &'static str {
match *self { match *self {
McDeclared | McInherited => "mutable", McDeclared | McInherited => "mutable",
McImmutable => "immutable", McImmutable => "immutable",
McReadOnly => "const"
} }
} }
} }
...@@ -610,7 +606,6 @@ pub fn inherited_mutability(&self, ...@@ -610,7 +606,6 @@ pub fn inherited_mutability(&self,
-> MutabilityCategory { -> MutabilityCategory {
match interior_m { match interior_m {
m_imm => base_m.inherit(), m_imm => base_m.inherit(),
m_const => McReadOnly,
m_mutbl => McDeclared m_mutbl => McDeclared
} }
} }
...@@ -999,7 +994,6 @@ pub fn cat_pattern(&self, ...@@ -999,7 +994,6 @@ pub fn cat_pattern(&self,
pub fn mut_to_str(&self, mutbl: ast::mutability) -> ~str { pub fn mut_to_str(&self, mutbl: ast::mutability) -> ~str {
match mutbl { match mutbl {
m_mutbl => ~"mutable", m_mutbl => ~"mutable",
m_const => ~"const",
m_imm => ~"immutable" m_imm => ~"immutable"
} }
} }
...@@ -1164,7 +1158,6 @@ pub fn freely_aliasable(&self) -> Option<AliasableReason> { ...@@ -1164,7 +1158,6 @@ pub fn freely_aliasable(&self) -> Option<AliasableReason> {
Some(AliasableManaged(m)) Some(AliasableManaged(m))
} }
cat_deref(_, _, region_ptr(m @ m_const, _)) |
cat_deref(_, _, region_ptr(m @ m_imm, _)) => { cat_deref(_, _, region_ptr(m @ m_imm, _)) => {
Some(AliasableBorrowed(m)) Some(AliasableBorrowed(m))
} }
......
...@@ -272,8 +272,7 @@ fn mk_pointer<AC:AstConv,RS:region_scope + Clone + 'static>( ...@@ -272,8 +272,7 @@ fn mk_pointer<AC:AstConv,RS:region_scope + Clone + 'static>(
match a_seq_ty.ty.node { match a_seq_ty.ty.node {
ast::ty_vec(ref mt) => { ast::ty_vec(ref mt) => {
let mut mt = ast_mt_to_mt(this, rscope, mt); let mut mt = ast_mt_to_mt(this, rscope, mt);
if a_seq_ty.mutbl == ast::m_mutbl || if a_seq_ty.mutbl == ast::m_mutbl {
a_seq_ty.mutbl == ast::m_const {
mt = ty::mt { ty: mt.ty, mutbl: a_seq_ty.mutbl }; mt = ty::mt { ty: mt.ty, mutbl: a_seq_ty.mutbl };
} }
return ty::mk_evec(tcx, mt, vst); return ty::mk_evec(tcx, mt, vst);
......
...@@ -102,7 +102,7 @@ trait `ToStr` imported, and I call `to_str()` on a value of type `T`, ...@@ -102,7 +102,7 @@ trait `ToStr` imported, and I call `to_str()` on a value of type `T`,
use extra::list::Nil; use extra::list::Nil;
use syntax::ast::{def_id, sty_value, sty_region, sty_box}; use syntax::ast::{def_id, sty_value, sty_region, sty_box};
use syntax::ast::{sty_uniq, sty_static, NodeId}; 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;
use syntax::ast_map; use syntax::ast_map;
...@@ -700,7 +700,7 @@ fn search_for_autosliced_method(&self, ...@@ -700,7 +700,7 @@ fn search_for_autosliced_method(&self,
ty_evec(mt, vstore_fixed(_)) => { ty_evec(mt, vstore_fixed(_)) => {
// First try to borrow to a slice // First try to borrow to a slice
let entry = self.search_for_some_kind_of_autorefd_method( 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, |m,r| ty::mk_evec(tcx,
ty::mt {ty:mt.ty, mutbl:m}, ty::mt {ty:mt.ty, mutbl:m},
vstore_slice(r))); vstore_slice(r)));
...@@ -709,7 +709,7 @@ fn search_for_autosliced_method(&self, ...@@ -709,7 +709,7 @@ fn search_for_autosliced_method(&self,
// Then try to borrow to a slice *and* borrow a pointer. // Then try to borrow to a slice *and* borrow a pointer.
self.search_for_some_kind_of_autorefd_method( self.search_for_some_kind_of_autorefd_method(
AutoBorrowVecRef, autoderefs, [m_const, m_imm, m_mutbl], AutoBorrowVecRef, autoderefs, [m_imm, m_mutbl],
|m,r| { |m,r| {
let slice_ty = ty::mk_evec(tcx, let slice_ty = ty::mk_evec(tcx,
ty::mt {ty:mt.ty, mutbl:m}, ty::mt {ty:mt.ty, mutbl:m},
...@@ -744,7 +744,7 @@ fn search_for_autosliced_method(&self, ...@@ -744,7 +744,7 @@ fn search_for_autosliced_method(&self,
// Coerce ~/@/&Trait instances to &Trait. // Coerce ~/@/&Trait instances to &Trait.
self.search_for_some_kind_of_autorefd_method( 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| { |trt_mut, reg| {
ty::mk_trait(tcx, trt_did, trt_substs.clone(), ty::mk_trait(tcx, trt_did, trt_substs.clone(),
RegionTraitStore(reg), trt_mut, b) RegionTraitStore(reg), trt_mut, b)
...@@ -779,7 +779,7 @@ fn search_for_autoptrd_method(&self, self_ty: ty::t, autoderefs: uint) ...@@ -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_float(*) | ty_enum(*) | ty_ptr(*) | ty_struct(*) | ty_tup(*) |
ty_estr(*) | ty_evec(*) | ty_trait(*) | ty_closure(*) => { ty_estr(*) | ty_evec(*) | ty_trait(*) | ty_closure(*) => {
self.search_for_some_kind_of_autorefd_method( 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})) |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, ...@@ -1270,18 +1270,10 @@ fn rcvr_matches_ty(fcx: @mut FnCtxt,
} }
fn mutability_matches(self_mutbl: ast::mutability, fn mutability_matches(self_mutbl: ast::mutability,
candidate_mutbl: ast::mutability) -> bool { candidate_mutbl: ast::mutability)
-> bool {
//! True if `self_mutbl <: candidate_mutbl` //! True if `self_mutbl <: candidate_mutbl`
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,
}
} }
} }
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
use middle::typeck::infer::{TypeTrace, Subtype}; use middle::typeck::infer::{TypeTrace, Subtype};
use middle::typeck::infer::fold_regions_in_sig; use middle::typeck::infer::fold_regions_in_sig;
use middle::typeck::isr_alist; 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::{unsafe_fn};
use syntax::ast::{Onceness, purity}; use syntax::ast::{Onceness, purity};
use util::common::{indenter}; use util::common::{indenter};
...@@ -52,16 +52,6 @@ fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres<ty::mt> { ...@@ -52,16 +52,6 @@ fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres<ty::mt> {
match (a.mutbl, b.mutbl) { match (a.mutbl, b.mutbl) {
// If one side or both is mut, then the GLB must use // If one side or both is mut, then the GLB must use
// the precise type from the mut side. // 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) => { (m_mutbl, m_mutbl) => {
eq_tys(self, a.ty, b.ty).then(|| { eq_tys(self, a.ty, b.ty).then(|| {
Ok(ty::mt {ty: a.ty, mutbl: m_mutbl}) Ok(ty::mt {ty: a.ty, mutbl: m_mutbl})
...@@ -70,22 +60,12 @@ fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres<ty::mt> { ...@@ -70,22 +60,12 @@ fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres<ty::mt> {
// If one side or both is immutable, we can use the GLB of // If one side or both is immutable, we can use the GLB of
// both sides but mutbl must be `m_imm`. // both sides but mutbl must be `m_imm`.
(m_imm, m_const) |
(m_const, m_imm) |
(m_imm, m_imm) => { (m_imm, m_imm) => {
self.tys(a.ty, b.ty).chain(|t| { self.tys(a.ty, b.ty).chain(|t| {
Ok(ty::mt {ty: t, mutbl: m_imm}) 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. // There is no mutual subtype of these combinations.
(m_mutbl, m_imm) | (m_mutbl, m_imm) |
(m_imm, m_mutbl) => { (m_imm, m_mutbl) => {
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
use util::ppaux::mt_to_str; use util::ppaux::mt_to_str;
use extra::list; 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::{unsafe_fn};
use syntax::ast::{Onceness, purity}; use syntax::ast::{Onceness, purity};
...@@ -55,14 +55,13 @@ fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres<ty::mt> { ...@@ -55,14 +55,13 @@ fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres<ty::mt> {
mt_to_str(tcx, a), mt_to_str(tcx, a),
mt_to_str(tcx, b)); mt_to_str(tcx, b));
let m = if a.mutbl == b.mutbl { if a.mutbl != b.mutbl {
a.mutbl return Err(ty::terr_mutability)
} else { }
m_const
};
let m = a.mutbl;
match m { match m {
m_imm | m_const => { m_imm => {
self.tys(a.ty, b.ty).chain(|t| Ok(ty::mt {ty: t, mutbl: m}) ) 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<ty::mt> { ...@@ -71,11 +70,7 @@ fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres<ty::mt> {
eq_tys(self, a.ty, b.ty).then(|| { eq_tys(self, a.ty, b.ty).then(|| {
Ok(ty::mt {ty: a.ty, mutbl: m}) Ok(ty::mt {ty: a.ty, mutbl: m})
}) })
}).chain_err(|_e| { }).chain_err(|e| Err(e))
self.tys(a.ty, b.ty).chain(|t| {
Ok(ty::mt {ty: t, mutbl: m_const})
})
})
} }
} }
} }
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
use extra::list::Nil; use extra::list::Nil;
use extra::list; use extra::list;
use syntax::ast::{Onceness, m_const, purity}; use syntax::ast::{Onceness, purity};
pub struct Sub(CombineFields); // "subtype", "subregion" etc pub struct Sub(CombineFields); // "subtype", "subregion" etc
...@@ -67,7 +67,7 @@ fn regions(&self, a: ty::Region, b: ty::Region) -> cres<ty::Region> { ...@@ -67,7 +67,7 @@ fn regions(&self, a: ty::Region, b: ty::Region) -> cres<ty::Region> {
fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres<ty::mt> { fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres<ty::mt> {
debug!("mts(%s <: %s)", a.inf_str(self.infcx), b.inf_str(self.infcx)); 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); return Err(ty::terr_mutability);
} }
...@@ -77,7 +77,7 @@ fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres<ty::mt> { ...@@ -77,7 +77,7 @@ fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres<ty::mt> {
// (i.e., invariant if mut): // (i.e., invariant if mut):
eq_tys(self, a.ty, b.ty).then(|| Ok(*a)) eq_tys(self, a.ty, b.ty).then(|| Ok(*a))
} }
m_imm | m_const => { m_imm => {
// Otherwise we can be covariant: // Otherwise we can be covariant:
self.tys(a.ty, b.ty).chain(|_t| Ok(*a) ) self.tys(a.ty, b.ty).chain(|_t| Ok(*a) )
} }
......
...@@ -239,7 +239,6 @@ fn mutability_to_str(m: ast::mutability) -> ~str { ...@@ -239,7 +239,6 @@ fn mutability_to_str(m: ast::mutability) -> ~str {
match m { match m {
ast::m_mutbl => ~"mut ", ast::m_mutbl => ~"mut ",
ast::m_imm => ~"", ast::m_imm => ~"",
ast::m_const => ~"const "
} }
} }
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
//! Unsafe casting functions //! Unsafe casting functions
use ptr::RawPtr;
use sys; use sys;
use unstable::intrinsics; use unstable::intrinsics;
...@@ -94,13 +95,13 @@ pub unsafe fn transmute_region<'a,'b,T>(ptr: &'a T) -> &'b T { ...@@ -94,13 +95,13 @@ pub unsafe fn transmute_region<'a,'b,T>(ptr: &'a T) -> &'b T {
/// Coerce an immutable reference to be mutable. /// Coerce an immutable reference to be mutable.
#[inline] #[inline]
pub unsafe fn transmute_mut_unsafe<T>(ptr: *const T) -> *mut T { pub unsafe fn transmute_mut_unsafe<T,P:RawPtr<T>>(ptr: P) -> *mut T {
transmute(ptr) transmute(ptr)
} }
/// Coerce an immutable reference to be mutable. /// Coerce an immutable reference to be mutable.
#[inline] #[inline]
pub unsafe fn transmute_immut_unsafe<T>(ptr: *const T) -> *T { pub unsafe fn transmute_immut_unsafe<T,P:RawPtr<T>>(ptr: P) -> *T {
transmute(ptr) transmute(ptr)
} }
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#[doc(hidden)]; #[doc(hidden)];
use libc::c_void; use libc::c_void;
use ptr::{mut_null}; use ptr::null;
use unstable::intrinsics::TyDesc; use unstable::intrinsics::TyDesc;
use unstable::raw; use unstable::raw;
...@@ -37,7 +37,7 @@ unsafe fn each_live_alloc(read_next_before: bool, ...@@ -37,7 +37,7 @@ unsafe fn each_live_alloc(read_next_before: bool,
use rt::local_heap; use rt::local_heap;
let mut box = local_heap::live_allocs(); let mut box = local_heap::live_allocs();
while box != mut_null() { while box != null() {
let next_before = (*box).next; let next_before = (*box).next;
let uniq = (*box).ref_count == managed::RC_MANAGED_UNIQUE; let uniq = (*box).ref_count == managed::RC_MANAGED_UNIQUE;
......
...@@ -1521,7 +1521,7 @@ pub fn new(min_len: uint, options: ~[MapOption]) -> Result<~MemoryMap, MapError> ...@@ -1521,7 +1521,7 @@ pub fn new(min_len: uint, options: ~[MapOption]) -> Result<~MemoryMap, MapError>
let r = unsafe { let r = unsafe {
libc::mmap(addr, len, prot, flags, fd, offset) 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 { Err(match errno() as c_int {
libc::EACCES => ErrFdNotAvail, libc::EACCES => ErrFdNotAvail,
libc::EBADF => ErrInvalidFd, libc::EBADF => ErrInvalidFd,
......
...@@ -12,8 +12,11 @@ ...@@ -12,8 +12,11 @@
use cast; use cast;
use clone::Clone; use clone::Clone;
use cmp::Equiv;
use iterator::{range, Iterator}; use iterator::{range, Iterator};
use option::{Option, Some, None}; use option::{Option, Some, None};
#[cfg(stage0)]
use sys;
use unstable::intrinsics; use unstable::intrinsics;
use util::swap; use util::swap;
...@@ -24,18 +27,28 @@ ...@@ -24,18 +27,28 @@
/// Calculate the offset from a pointer /// Calculate the offset from a pointer
#[inline] #[inline]
#[cfg(stage0)]
pub fn offset<T>(ptr: *T, count: int) -> *T { pub fn offset<T>(ptr: *T, count: int) -> *T {
unsafe { intrinsics::offset(ptr, count) } (ptr as uint + (count as uint) * sys::size_of::<T>()) as *T
} }
/// Calculate the offset from a const pointer /// Calculate the offset from a mut pointer
#[inline] #[inline]
pub fn const_offset<T>(ptr: *const T, count: int) -> *const T { #[cfg(stage0)]
unsafe { intrinsics::offset(ptr as *T, count) } pub fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T {
(ptr as uint + (count as uint) * sys::size_of::<T>()) as *mut T
}
/// Calculate the offset from a pointer
#[inline]
#[cfg(not(stage0))]
pub fn offset<T>(ptr: *T, count: int) -> *T {
unsafe { intrinsics::offset(ptr, count) }
} }
/// Calculate the offset from a mut pointer /// Calculate the offset from a mut pointer
#[inline] #[inline]
#[cfg(not(stage0))]
pub fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T { pub fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T {
unsafe { intrinsics::offset(ptr as *T, count) as *mut T } unsafe { intrinsics::offset(ptr as *T, count) as *mut T }
} }
...@@ -73,11 +86,11 @@ pub fn mut_null<T>() -> *mut T { 0 as *mut T } ...@@ -73,11 +86,11 @@ pub fn mut_null<T>() -> *mut T { 0 as *mut T }
/// Returns true if the pointer is equal to the null pointer. /// Returns true if the pointer is equal to the null pointer.
#[inline] #[inline]
pub fn is_null<T>(ptr: *const T) -> bool { ptr == null() } pub fn is_null<T,P:RawPtr<T>>(ptr: P) -> bool { ptr.is_null() }
/// Returns true if the pointer is not equal to the null pointer. /// Returns true if the pointer is not equal to the null pointer.
#[inline] #[inline]
pub fn is_not_null<T>(ptr: *const T) -> bool { !is_null(ptr) } pub fn is_not_null<T,P:RawPtr<T>>(ptr: P) -> bool { ptr.is_not_null() }
/** /**
* Copies data from one location to another. * Copies data from one location to another.
...@@ -87,8 +100,10 @@ pub fn is_not_null<T>(ptr: *const T) -> bool { !is_null(ptr) } ...@@ -87,8 +100,10 @@ pub fn is_not_null<T>(ptr: *const T) -> bool { !is_null(ptr) }
*/ */
#[inline] #[inline]
#[cfg(target_word_size = "32")] #[cfg(target_word_size = "32")]
pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) { pub unsafe fn copy_memory<T,P:RawPtr<T>>(dst: *mut T, src: P, count: uint) {
intrinsics::memmove32(dst, src as *T, count as u32); intrinsics::memmove32(dst,
cast::transmute_immut_unsafe(src),
count as u32);
} }
/** /**
...@@ -99,8 +114,10 @@ pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) { ...@@ -99,8 +114,10 @@ pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
*/ */
#[inline] #[inline]
#[cfg(target_word_size = "64")] #[cfg(target_word_size = "64")]
pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) { pub unsafe fn copy_memory<T,P:RawPtr<T>>(dst: *mut T, src: P, count: uint) {
intrinsics::memmove64(dst, src as *T, count as u64); intrinsics::memmove64(dst,
cast::transmute_immut_unsafe(src),
count as u64);
} }
/** /**
...@@ -111,8 +128,12 @@ pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) { ...@@ -111,8 +128,12 @@ pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
*/ */
#[inline] #[inline]
#[cfg(target_word_size = "32")] #[cfg(target_word_size = "32")]
pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint) { pub unsafe fn copy_nonoverlapping_memory<T,P:RawPtr<T>>(dst: *mut T,
intrinsics::memcpy32(dst, src as *T, count as u32); 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<T>(dst: *mut T, src: *const T, count: u ...@@ -123,8 +144,12 @@ pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: u
*/ */
#[inline] #[inline]
#[cfg(target_word_size = "64")] #[cfg(target_word_size = "64")]
pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint) { pub unsafe fn copy_nonoverlapping_memory<T,P:RawPtr<T>>(dst: *mut T,
intrinsics::memcpy64(dst, src as *T, count as u64); src: P,
count: uint) {
intrinsics::memcpy64(dst,
cast::transmute_immut_unsafe(src),
count as u64);
} }
/** /**
...@@ -216,12 +241,6 @@ pub fn to_unsafe_ptr<T>(thing: &T) -> *T { ...@@ -216,12 +241,6 @@ pub fn to_unsafe_ptr<T>(thing: &T) -> *T {
thing as *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<T>(thing: &const T) -> *const T {
thing as *const T
}
/// Transform a mutable region pointer - &mut T - to a mutable unsafe pointer - *mut T. /// Transform a mutable region pointer - &mut T - to a mutable unsafe pointer - *mut T.
#[inline] #[inline]
pub fn to_mut_unsafe_ptr<T>(thing: &mut T) -> *mut T { pub fn to_mut_unsafe_ptr<T>(thing: &mut T) -> *mut T {
...@@ -269,8 +288,10 @@ pub unsafe fn array_each<T>(arr: **T, cb: &fn(*T)) { ...@@ -269,8 +288,10 @@ pub unsafe fn array_each<T>(arr: **T, cb: &fn(*T)) {
#[allow(missing_doc)] #[allow(missing_doc)]
pub trait RawPtr<T> { pub trait RawPtr<T> {
fn null() -> Self;
fn is_null(&self) -> bool; fn is_null(&self) -> bool;
fn is_not_null(&self) -> bool; fn is_not_null(&self) -> bool;
fn to_uint(&self) -> uint;
unsafe fn to_option(&self) -> Option<&T>; unsafe fn to_option(&self) -> Option<&T>;
fn offset(&self, count: int) -> Self; fn offset(&self, count: int) -> Self;
unsafe fn offset_inbounds(self, count: int) -> Self; unsafe fn offset_inbounds(self, count: int) -> Self;
...@@ -278,13 +299,21 @@ pub trait RawPtr<T> { ...@@ -278,13 +299,21 @@ pub trait RawPtr<T> {
/// Extension methods for immutable pointers /// Extension methods for immutable pointers
impl<T> RawPtr<T> for *T { impl<T> RawPtr<T> for *T {
/// Returns the null pointer.
#[inline]
fn null() -> *T { null() }
/// Returns true if the pointer is equal to the null pointer. /// Returns true if the pointer is equal to the null pointer.
#[inline] #[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. /// Returns true if the pointer is not equal to the null pointer.
#[inline] #[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 /// 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 { ...@@ -317,13 +346,21 @@ unsafe fn offset_inbounds(self, count: int) -> *T {
/// Extension methods for mutable pointers /// Extension methods for mutable pointers
impl<T> RawPtr<T> for *mut T { impl<T> RawPtr<T> 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. /// Returns true if the pointer is equal to the null pointer.
#[inline] #[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. /// Returns true if the pointer is not equal to the null pointer.
#[inline] #[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 /// 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 { ...@@ -360,13 +397,38 @@ unsafe fn offset_inbounds(self, count: int) -> *mut T {
// Equality for pointers // Equality for pointers
#[cfg(not(test))] #[cfg(not(test))]
impl<T> Eq for *const T { impl<T> 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<T> Eq for *mut T {
#[inline] #[inline]
fn eq(&self, other: &*const T) -> bool { fn eq(&self, other: &*mut T) -> bool {
(*self as uint) == (*other as uint) (*self as uint) == (*other as uint)
} }
#[inline] #[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<T> Equiv<*mut T> for *T {
fn equiv(&self, other: &*mut T) -> bool {
self.to_uint() == other.to_uint()
}
}
#[cfg(not(test))]
impl<T> Equiv<*T> for *mut T {
fn equiv(&self, other: &*T) -> bool {
self.to_uint() == other.to_uint()
}
} }
// Equality for extern "C" fn pointers // Equality for extern "C" fn pointers
...@@ -412,21 +474,41 @@ fn ne(&self, other: &extern "C" fn($($p),*) -> _R) -> bool { ...@@ -412,21 +474,41 @@ fn ne(&self, other: &extern "C" fn($($p),*) -> _R) -> bool {
// Comparison for pointers // Comparison for pointers
#[cfg(not(test))] #[cfg(not(test))]
impl<T> Ord for *const T { impl<T> 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<T> Ord for *mut T {
#[inline] #[inline]
fn lt(&self, other: &*const T) -> bool { fn lt(&self, other: &*mut T) -> bool {
(*self as uint) < (*other as uint) (*self as uint) < (*other as uint)
} }
#[inline] #[inline]
fn le(&self, other: &*const T) -> bool { fn le(&self, other: &*mut T) -> bool {
(*self as uint) <= (*other as uint) (*self as uint) <= (*other as uint)
} }
#[inline] #[inline]
fn ge(&self, other: &*const T) -> bool { fn ge(&self, other: &*mut T) -> bool {
(*self as uint) >= (*other as uint) (*self as uint) >= (*other as uint)
} }
#[inline] #[inline]
fn gt(&self, other: &*const T) -> bool { fn gt(&self, other: &*mut T) -> bool {
(*self as uint) > (*other as uint) (*self as uint) > (*other as uint)
} }
} }
......
...@@ -11,17 +11,18 @@ ...@@ -11,17 +11,18 @@
use cell::Cell; use cell::Cell;
use c_str::ToCStr; use c_str::ToCStr;
use cast::transmute; use cast::transmute;
use libc::{c_char, size_t, STDERR_FILENO};
use io;
use io::{Writer, WriterUtil}; use io::{Writer, WriterUtil};
use io;
use libc::{c_char, c_void, size_t, STDERR_FILENO};
use option::{Option, None, Some}; use option::{Option, None, Some};
use uint; use ptr::RawPtr;
use rt::env; use rt::env;
use rt::local::Local; use rt::local::Local;
use rt::task::Task; use rt::task::Task;
use str;
use str::{OwnedStr, StrSlice}; use str::{OwnedStr, StrSlice};
use str;
use sys; use sys;
use uint;
use unstable::raw; use unstable::raw;
use vec::ImmutableVector; use vec::ImmutableVector;
...@@ -93,12 +94,12 @@ unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) { ...@@ -93,12 +94,12 @@ unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) {
static ENABLE_DEBUG: bool = false; static ENABLE_DEBUG: bool = false;
#[inline] #[inline]
unsafe fn debug_borrow<T>(tag: &'static str, unsafe fn debug_borrow<T,P:RawPtr<T>>(tag: &'static str,
p: *const T, p: P,
old_bits: uint, old_bits: uint,
new_bits: uint, new_bits: uint,
filename: *c_char, filename: *c_char,
line: size_t) { line: size_t) {
//! A useful debugging function that prints a pointer + tag + newline //! A useful debugging function that prints a pointer + tag + newline
//! without allocating memory. //! without allocating memory.
...@@ -106,15 +107,15 @@ unsafe fn debug_borrow<T>(tag: &'static str, ...@@ -106,15 +107,15 @@ unsafe fn debug_borrow<T>(tag: &'static str,
debug_borrow_slow(tag, p, old_bits, new_bits, filename, line); debug_borrow_slow(tag, p, old_bits, new_bits, filename, line);
} }
unsafe fn debug_borrow_slow<T>(tag: &'static str, unsafe fn debug_borrow_slow<T,P:RawPtr<T>>(tag: &'static str,
p: *const T, p: P,
old_bits: uint, old_bits: uint,
new_bits: uint, new_bits: uint,
filename: *c_char, filename: *c_char,
line: size_t) { line: size_t) {
let dbg = STDERR_FILENO as io::fd_t; let dbg = STDERR_FILENO as io::fd_t;
dbg.write_str(tag); dbg.write_str(tag);
dbg.write_hex(p as uint); dbg.write_hex(p.to_uint());
dbg.write_str(" "); dbg.write_str(" ");
dbg.write_hex(old_bits); dbg.write_hex(old_bits);
dbg.write_str(" "); dbg.write_str(" ");
......
...@@ -554,6 +554,7 @@ pub fn change_task_context(~self, ...@@ -554,6 +554,7 @@ pub fn change_task_context(~self,
let current_task: &mut Task = match sched.cleanup_job { let current_task: &mut Task = match sched.cleanup_job {
Some(CleanupJob { task: ref task, _ }) => { Some(CleanupJob { task: ref task, _ }) => {
let task_ptr: *~Task = task;
transmute_mut_region(*transmute_mut_unsafe(task)) transmute_mut_region(*transmute_mut_unsafe(task))
} }
None => { None => {
......
...@@ -343,7 +343,14 @@ fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { ...@@ -343,7 +343,14 @@ fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
// NB: raw-pointer IterBytes does _not_ dereference // NB: raw-pointer IterBytes does _not_ dereference
// to the target; it just gives you the pointer-bytes. // to the target; it just gives you the pointer-bytes.
impl<A> IterBytes for *const A { impl<A> IterBytes for *A {
#[inline]
fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
(*self as uint).iter_bytes(lsb0, f)
}
}
impl<A> IterBytes for *mut A {
#[inline] #[inline]
fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
(*self as uint).iter_bytes(lsb0, f) (*self as uint).iter_bytes(lsb0, f)
......
...@@ -54,8 +54,10 @@ pub fn swap<T>(x: &mut T, y: &mut T) { ...@@ -54,8 +54,10 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
let t: *mut T = &mut tmp; let t: *mut T = &mut tmp;
// Perform the swap, `&mut` pointers never alias // Perform the swap, `&mut` pointers never alias
ptr::copy_nonoverlapping_memory(t, x, 1); let x_raw: *mut T = x;
ptr::copy_nonoverlapping_memory(x, y, 1); 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); ptr::copy_nonoverlapping_memory(y, t, 1);
// y and t now point to the same thing, but we need to completely forget `tmp` // y and t now point to the same thing, but we need to completely forget `tmp`
......
...@@ -1122,14 +1122,7 @@ fn map<U>(&self, f: &fn(t: &T) -> U) -> ~[U] { ...@@ -1122,14 +1122,7 @@ fn map<U>(&self, f: &fn(t: &T) -> U) -> ~[U] {
* foreign interop. * foreign interop.
*/ */
#[inline] #[inline]
fn as_imm_buf<U>(&self, fn as_imm_buf<U>(&self, f: &fn(*T, uint) -> U) -> U {
/* 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!
let s = self.repr(); let s = self.repr();
f(s.data, s.len / sys::nonzero_size_of::<T>()) f(s.data, s.len / sys::nonzero_size_of::<T>())
} }
......
...@@ -298,7 +298,10 @@ pub enum pat_ { ...@@ -298,7 +298,10 @@ pub enum pat_ {
} }
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] #[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)] #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
pub enum Sigil { pub enum Sigil {
......
...@@ -53,7 +53,6 @@ pub enum ObsoleteSyntax { ...@@ -53,7 +53,6 @@ pub enum ObsoleteSyntax {
ObsoleteMode, ObsoleteMode,
ObsoleteImplicitSelf, ObsoleteImplicitSelf,
ObsoleteLifetimeNotation, ObsoleteLifetimeNotation,
ObsoleteConstManagedPointer,
ObsoletePurity, ObsoletePurity,
ObsoleteStaticMethod, ObsoleteStaticMethod,
ObsoleteConstItem, ObsoleteConstItem,
...@@ -65,6 +64,7 @@ pub enum ObsoleteSyntax { ...@@ -65,6 +64,7 @@ pub enum ObsoleteSyntax {
ObsoleteUnsafeExternFn, ObsoleteUnsafeExternFn,
ObsoletePrivVisibility, ObsoletePrivVisibility,
ObsoleteTraitFuncVisibility, ObsoleteTraitFuncVisibility,
ObsoleteConstPointer,
} }
impl to_bytes::IterBytes for ObsoleteSyntax { impl to_bytes::IterBytes for ObsoleteSyntax {
...@@ -201,10 +201,6 @@ fn obsolete(&self, sp: span, kind: ObsoleteSyntax) { ...@@ -201,10 +201,6 @@ fn obsolete(&self, sp: span, kind: ObsoleteSyntax) {
"instead of `&foo/bar`, write `&'foo bar`; instead of \ "instead of `&foo/bar`, write `&'foo bar`; instead of \
`bar/&foo`, write `&bar<'foo>" `bar/&foo`, write `&bar<'foo>"
), ),
ObsoleteConstManagedPointer => (
"const `@` pointer",
"instead of `@const Foo`, write `@Foo`"
),
ObsoletePurity => ( ObsoletePurity => (
"pure function", "pure function",
"remove `pure`" "remove `pure`"
...@@ -255,6 +251,11 @@ fn obsolete(&self, sp: span, kind: ObsoleteSyntax) { ...@@ -255,6 +251,11 @@ fn obsolete(&self, sp: span, kind: ObsoleteSyntax) {
"visibility not necessary", "visibility not necessary",
"trait functions inherit the visibility of the trait itself" "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); self.report(sp, kind, kind_str, desc);
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
use ast::{item_enum, item_fn, item_foreign_mod, item_impl}; 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::{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_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::{m_imm, m_mutbl, mac_, mac_invoc_tt, matcher, match_nonterminal};
use ast::{match_seq, match_tok, method, mt, mul, mutability}; use ast::{match_seq, match_tok, method, mt, mul, mutability};
use ast::{named_field, neg, NodeId, noreturn, not, pat, pat_box, pat_enum}; 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, ...@@ -1153,9 +1153,6 @@ pub fn parse_box_or_uniq_pointee(&self,
if mt.mutbl != m_imm && sigil == OwnedSigil { if mt.mutbl != m_imm && sigil == OwnedSigil {
self.obsolete(*self.last_span, ObsoleteMutOwnedPointer); self.obsolete(*self.last_span, ObsoleteMutOwnedPointer);
} }
if mt.mutbl == m_const && sigil == ManagedSigil {
self.obsolete(*self.last_span, ObsoleteConstManagedPointer);
}
ctor(mt) ctor(mt)
} }
...@@ -1568,7 +1565,8 @@ pub fn parse_mutability(&self) -> mutability { ...@@ -1568,7 +1565,8 @@ pub fn parse_mutability(&self) -> mutability {
if self.eat_keyword(keywords::Mut) { if self.eat_keyword(keywords::Mut) {
m_mutbl m_mutbl
} else if self.eat_keyword(keywords::Const) { } else if self.eat_keyword(keywords::Const) {
m_const self.obsolete(*self.last_span, ObsoleteConstPointer);
m_imm
} else { } else {
m_imm m_imm
} }
...@@ -1727,7 +1725,7 @@ pub fn parse_bottom_expr(&self) -> @expr { ...@@ -1727,7 +1725,7 @@ pub fn parse_bottom_expr(&self) -> @expr {
} else if *self.token == token::LBRACKET { } else if *self.token == token::LBRACKET {
self.bump(); self.bump();
let mutbl = self.parse_mutability(); let mutbl = self.parse_mutability();
if mutbl == m_mutbl || mutbl == m_const { if mutbl == m_mutbl {
self.obsolete(*self.last_span, ObsoleteMutVector); self.obsolete(*self.last_span, ObsoleteMutVector);
} }
...@@ -2182,10 +2180,6 @@ pub fn parse_prefix_expr(&self) -> @expr { ...@@ -2182,10 +2180,6 @@ pub fn parse_prefix_expr(&self) -> @expr {
token::AT => { token::AT => {
self.bump(); self.bump();
let m = self.parse_mutability(); let m = self.parse_mutability();
if m == m_const {
self.obsolete(*self.last_span, ObsoleteConstManagedPointer);
}
let e = self.parse_prefix_expr(); let e = self.parse_prefix_expr();
hi = e.span.hi; hi = e.span.hi;
// HACK: turn @[...] into a @-evec // HACK: turn @[...] into a @-evec
......
...@@ -386,7 +386,6 @@ pub fn print_type(s: @ps, ty: &ast::Ty) { ...@@ -386,7 +386,6 @@ pub fn print_type(s: @ps, ty: &ast::Ty) {
word(s.s, "["); word(s.s, "[");
match mt.mutbl { match mt.mutbl {
ast::m_mutbl => word_space(s, "mut"), ast::m_mutbl => word_space(s, "mut"),
ast::m_const => word_space(s, "const"),
ast::m_imm => () ast::m_imm => ()
} }
print_type(s, mt.ty); print_type(s, mt.ty);
...@@ -429,7 +428,6 @@ pub fn print_type(s: @ps, ty: &ast::Ty) { ...@@ -429,7 +428,6 @@ pub fn print_type(s: @ps, ty: &ast::Ty) {
word(s.s, "["); word(s.s, "[");
match mt.mutbl { match mt.mutbl {
ast::m_mutbl => word_space(s, "mut"), ast::m_mutbl => word_space(s, "mut"),
ast::m_const => word_space(s, "const"),
ast::m_imm => () ast::m_imm => ()
} }
print_type(s, mt.ty); print_type(s, mt.ty);
...@@ -1882,7 +1880,6 @@ pub fn print_view_item(s: @ps, item: &ast::view_item) { ...@@ -1882,7 +1880,6 @@ pub fn print_view_item(s: @ps, item: &ast::view_item) {
pub fn print_mutability(s: @ps, mutbl: ast::mutability) { pub fn print_mutability(s: @ps, mutbl: ast::mutability) {
match mutbl { match mutbl {
ast::m_mutbl => word_nbsp(s, "mut"), ast::m_mutbl => word_nbsp(s, "mut"),
ast::m_const => word_nbsp(s, "const"),
ast::m_imm => {/* nothing */ } ast::m_imm => {/* nothing */ }
} }
} }
......
// 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
...@@ -11,16 +11,6 @@ fn foo(t0: & &mut int) { ...@@ -11,16 +11,6 @@ fn foo(t0: & &mut int) {
**t1 = 22; //~ ERROR cannot assign **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) { fn foo3(t0: &mut &mut int) {
let t1 = &mut *t0; let t1 = &mut *t0;
let p: &int = &**t0; //~ ERROR cannot borrow let p: &int = &**t0; //~ ERROR cannot borrow
...@@ -28,4 +18,4 @@ fn foo3(t0: &mut &mut int) { ...@@ -28,4 +18,4 @@ fn foo3(t0: &mut &mut int) {
} }
fn main() { fn main() {
} }
\ No newline at end of file
...@@ -14,29 +14,18 @@ struct Foo { ...@@ -14,29 +14,18 @@ struct Foo {
impl Foo { impl Foo {
pub fn f(&self) {} pub fn f(&self) {}
pub fn g(&const self) {}
pub fn h(&mut self) {} pub fn h(&mut self) {}
} }
fn a(x: &mut Foo) { fn a(x: &mut Foo) {
x.f(); x.f();
x.g();
x.h(); x.h();
} }
fn b(x: &Foo) { fn b(x: &Foo) {
x.f(); x.f();
x.g();
x.h(); //~ ERROR cannot borrow 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() { fn main() {
} }
...@@ -32,14 +32,6 @@ fn pre_freeze() { ...@@ -32,14 +32,6 @@ fn pre_freeze() {
borrow_mut(v); //~ ERROR cannot borrow 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() { fn post_freeze() {
// In this instance, the const alias starts after the borrow. // In this instance, the const alias starts after the borrow.
......
...@@ -29,16 +29,5 @@ fn has_mut_vec_but_tries_to_change_it() { ...@@ -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() { fn main() {
} }
// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn process<T>(_t: T) {}
fn match_const_opt_by_mut_ref(v: &const Option<int>) {
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<int>) {
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<int>) {
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<int>) {
match *v {
Some(i) => process(i),
None => ()
}
}
fn main() {
}
...@@ -35,12 +35,6 @@ fn aliased_imm() { ...@@ -35,12 +35,6 @@ fn aliased_imm() {
borrow(v); borrow(v);
} }
fn aliased_const() {
let mut v = ~3;
let _w = &const v;
borrow(v);
}
fn aliased_mut() { fn aliased_mut() {
let mut v = ~3; let mut v = ~3;
let _w = &mut v; let _w = &mut v;
......
...@@ -23,13 +23,10 @@ fn main() { ...@@ -23,13 +23,10 @@ fn main() {
// @int <: X // @int <: X
// //
// This constraint forces X to be // Here the type check fails because @const is gone and there is no
// @const int. // supertype.
r(@3); r(@3); //~ ERROR mismatched types
// Here the type check succeeds but the // Here the type check succeeds.
// mutability check will fail, because the *r(@mut 3) = 4;
// 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
} }
// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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() {
}
// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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);
}
}
...@@ -26,13 +26,6 @@ fn matcher2(x: opts) { ...@@ -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) { fn matcher4(x: opts) {
match x { match x {
a(ref mut i) | b(ref i) => {} //~ ERROR variable `i` is bound with different mode in pattern #2 than in pattern #1 a(ref mut i) | b(ref i) => {} //~ ERROR variable `i` is bound with different mode in pattern #2 than in pattern #1
......
...@@ -13,17 +13,14 @@ ...@@ -13,17 +13,14 @@
trait MyIter { trait MyIter {
fn test_imm(&self); fn test_imm(&self);
fn test_const(&const self);
} }
impl<'self> MyIter for &'self [int] { impl<'self> MyIter for &'self [int] {
fn test_imm(&self) { assert_eq!(self[0], 1) } 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 { impl<'self> MyIter for &'self str {
fn test_imm(&self) { assert_eq!(*self, "test") } fn test_imm(&self) { assert_eq!(*self, "test") }
fn test_const(&const self) { assert_eq!(self[0], 't' as u8) }
} }
pub fn main() { pub fn main() {
...@@ -40,15 +37,6 @@ pub fn main() { ...@@ -40,15 +37,6 @@ pub fn main() {
// XXX: Other types of mutable vecs don't currently exist // 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 // 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 // allow creating a mutable pointer to a temporary, which would be a source
// of confusion // of confusion
......
...@@ -13,7 +13,7 @@ struct Foo { ...@@ -13,7 +13,7 @@ struct Foo {
} }
impl Foo { impl Foo {
pub fn f(&const self) {} pub fn f(&self) {}
} }
fn g(x: &mut Foo) { fn g(x: &mut Foo) {
......
...@@ -24,32 +24,9 @@ fn match_ref_unused(v: Option<int>) { ...@@ -24,32 +24,9 @@ fn match_ref_unused(v: Option<int>) {
} }
} }
fn match_const_reg(v: &const Option<int>) -> int {
match *v {
Some(ref i) => {*i} //~ ERROR cannot borrow
//~^ ERROR unsafe borrow
None => {0}
}
}
fn impure(_i: int) { fn impure(_i: int) {
} }
fn match_const_reg_unused(v: &const Option<int>) {
match *v {
Some(_) => {impure(0)} // OK because nothing is captured
None => {}
}
}
fn match_const_reg_impure(v: &const Option<int>) {
match *v {
Some(ref i) => {impure(*i)} //~ ERROR cannot borrow
//~^ ERROR unsafe borrow
None => {}
}
}
fn match_imm_reg(v: &Option<int>) { fn match_imm_reg(v: &Option<int>) {
match *v { match *v {
Some(ref i) => {impure(*i)} // OK because immutable Some(ref i) => {impure(*i)} // OK because immutable
......
...@@ -25,7 +25,6 @@ struct Innermost { ...@@ -25,7 +25,6 @@ struct Innermost {
} }
fn borrow(_v: &int) {} fn borrow(_v: &int) {}
fn borrow_const(_v: &const int) {}
fn box_mut(v: &mut ~int) { fn box_mut(v: &mut ~int) {
borrow(*v); // OK: &mut -> &imm borrow(*v); // OK: &mut -> &imm
...@@ -51,17 +50,5 @@ fn box_imm_recs(v: &Outer) { ...@@ -51,17 +50,5 @@ fn box_imm_recs(v: &Outer) {
borrow(v.f.g.h); // OK 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() { fn main() {
} }
...@@ -49,8 +49,8 @@ pub fn eat(&mut self) -> bool { ...@@ -49,8 +49,8 @@ pub fn eat(&mut self) -> bool {
} }
impl<T> Container for cat<T> { impl<T> Container for cat<T> {
fn len(&const self) -> uint { self.meows as uint } fn len(&self) -> uint { self.meows as uint }
fn is_empty(&const self) -> bool { self.meows == 0 } fn is_empty(&self) -> bool { self.meows == 0 }
} }
impl<T> Mutable for cat<T> { impl<T> Mutable for cat<T> {
......
...@@ -3,14 +3,14 @@ struct SpeechMaker { ...@@ -3,14 +3,14 @@ struct SpeechMaker {
} }
impl 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 speaker.how_many() + 33
} }
pub fn main() { pub fn main() {
let lincoln = SpeechMaker {speeches: 22}; let lincoln = SpeechMaker {speeches: 22};
assert_eq!(foo(&const lincoln), 55); assert_eq!(foo(&lincoln), 55);
} }
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
fn f(_: &const [int]) {} fn f(_: &[int]) {}
pub fn main() { pub fn main() {
let v = [ 1, 2, 3 ]; let v = [ 1, 2, 3 ];
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册