librustc: Remove &const
and *const
from the language.
They are still present as part of the borrow check.
This commit is contained in:
parent
58d6eb5048
commit
5c3504799d
48 changed files with 309 additions and 460 deletions
|
@ -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)
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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('?')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ use mc = middle::mem_categorization;
|
|||
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 @@ impl<'self> CheckLoanCtxt<'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 @@ impl<'self> CheckLoanCtxt<'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 @@ impl<'self> CheckLoanCtxt<'self> {
|
|||
// Otherwise stop iterating
|
||||
LpExtend(_, mc::McDeclared, _) |
|
||||
LpExtend(_, mc::McImmutable, _) |
|
||||
LpExtend(_, mc::McReadOnly, _) |
|
||||
LpVar(_) => {
|
||||
return true;
|
||||
}
|
||||
|
@ -590,8 +589,11 @@ impl<'self> CheckLoanCtxt<'self> {
|
|||
|
||||
// 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
|
||||
|
|
|
@ -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 @@ impl GuaranteeLifetimeContext {
|
|||
// 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)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -26,7 +26,6 @@ use middle::ty;
|
|||
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 @@ impl GatherLoanCtxt {
|
|||
|
||||
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 @@ impl GatherLoanCtxt {
|
|||
self.guarantee_valid(expr.id,
|
||||
expr.span,
|
||||
cmt_deref,
|
||||
m_imm,
|
||||
ImmutableMutability,
|
||||
r)
|
||||
}
|
||||
ty::AutoBorrowObj(r, m) => {
|
||||
|
@ -402,7 +413,7 @@ impl GatherLoanCtxt {
|
|||
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 @@ impl GatherLoanCtxt {
|
|||
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 @@ impl GatherLoanCtxt {
|
|||
// 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 @@ impl GatherLoanCtxt {
|
|||
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 => {
|
||||
ImmutableMutability => {
|
||||
// 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.
|
||||
if !cmt.mutbl.is_mutable() {
|
||||
bccx.report(BckError {span: borrow_span,
|
||||
|
@ -561,12 +563,14 @@ impl GatherLoanCtxt {
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ impl GatherLoanCtxt {
|
|||
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 @@ impl GatherLoanCtxt {
|
|||
}
|
||||
}
|
||||
};
|
||||
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 @@ impl GatherLoanCtxt {
|
|||
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 @@ impl GatherLoanCtxt {
|
|||
// 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);
|
||||
}
|
||||
|
||||
_ => {}
|
||||
|
|
|
@ -15,7 +15,7 @@ use std::vec;
|
|||
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 @@ impl RestrictionsContext {
|
|||
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
|
||||
//
|
||||
|
|
|
@ -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 @@ impl ToStr for DynaFreezeKind {
|
|||
// 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 @@ impl BorrowckCtxt {
|
|||
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",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ use middle::typeck;
|
|||
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 @@ impl MutabilityCategory {
|
|||
pub fn inherit(&self) -> MutabilityCategory {
|
||||
match *self {
|
||||
McImmutable => McImmutable,
|
||||
McReadOnly => McReadOnly,
|
||||
McDeclared => McInherited,
|
||||
McInherited => McInherited
|
||||
}
|
||||
|
@ -313,7 +310,7 @@ impl MutabilityCategory {
|
|||
|
||||
pub fn is_mutable(&self) -> bool {
|
||||
match *self {
|
||||
McImmutable | McReadOnly => false,
|
||||
McImmutable => false,
|
||||
McDeclared | McInherited => true
|
||||
}
|
||||
}
|
||||
|
@ -321,7 +318,7 @@ impl MutabilityCategory {
|
|||
pub fn is_immutable(&self) -> bool {
|
||||
match *self {
|
||||
McImmutable => true,
|
||||
McReadOnly | McDeclared | McInherited => false
|
||||
McDeclared | McInherited => false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,7 +326,6 @@ impl MutabilityCategory {
|
|||
match *self {
|
||||
McDeclared | McInherited => "mutable",
|
||||
McImmutable => "immutable",
|
||||
McReadOnly => "const"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -610,7 +606,6 @@ impl mem_categorization_ctxt {
|
|||
-> MutabilityCategory {
|
||||
match interior_m {
|
||||
m_imm => base_m.inherit(),
|
||||
m_const => McReadOnly,
|
||||
m_mutbl => McDeclared
|
||||
}
|
||||
}
|
||||
|
@ -999,7 +994,6 @@ impl mem_categorization_ctxt {
|
|||
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 @@ impl cmt_ {
|
|||
Some(AliasableManaged(m))
|
||||
}
|
||||
|
||||
cat_deref(_, _, region_ptr(m @ m_const, _)) |
|
||||
cat_deref(_, _, region_ptr(m @ m_imm, _)) => {
|
||||
Some(AliasableBorrowed(m))
|
||||
}
|
||||
|
|
|
@ -272,8 +272,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Clone + 'static>(
|
|||
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);
|
||||
|
|
|
@ -102,7 +102,7 @@ use std::vec;
|
|||
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 @@ impl<'self> LookupContext<'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 @@ impl<'self> LookupContext<'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 @@ impl<'self> LookupContext<'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 @@ impl<'self> LookupContext<'self> {
|
|||
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 @@ impl<'self> LookupContext<'self> {
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ use middle::typeck::infer::{cres, InferCtxt};
|
|||
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 @@ impl Combine for Glb {
|
|||
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 @@ impl Combine for Glb {
|
|||
|
||||
// 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) => {
|
||||
|
|
|
@ -24,7 +24,7 @@ use middle::typeck::isr_alist;
|
|||
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 @@ impl Combine for Lub {
|
|||
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 @@ impl Combine for Lub {
|
|||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ use util::ppaux::bound_region_to_str;
|
|||
|
||||
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 @@ impl Combine for Sub {
|
|||
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));
|
||||
|
||||
if a.mutbl != b.mutbl && b.mutbl != m_const {
|
||||
if a.mutbl != b.mutbl {
|
||||
return Err(ty::terr_mutability);
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ impl Combine for Sub {
|
|||
// (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) )
|
||||
}
|
||||
|
|
|
@ -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 "
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<T>(ptr: *const T) -> *mut T {
|
||||
pub unsafe fn transmute_mut_unsafe<T,P:RawPtr<T>>(ptr: P) -> *mut T {
|
||||
transmute(ptr)
|
||||
}
|
||||
|
||||
/// Coerce an immutable reference to be mutable.
|
||||
#[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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -1521,7 +1521,7 @@ impl MemoryMap {
|
|||
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,
|
||||
|
|
|
@ -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 @@ use util::swap;
|
|||
|
||||
/// Calculate the offset from a pointer
|
||||
#[inline]
|
||||
#[cfg(stage0)]
|
||||
pub fn offset<T>(ptr: *T, count: int) -> *T {
|
||||
unsafe { intrinsics::offset(ptr, count) }
|
||||
}
|
||||
|
||||
/// Calculate the offset from a const pointer
|
||||
#[inline]
|
||||
pub fn const_offset<T>(ptr: *const T, count: int) -> *const T {
|
||||
unsafe { intrinsics::offset(ptr as *T, count) }
|
||||
(ptr as uint + (count as uint) * sys::size_of::<T>()) as *T
|
||||
}
|
||||
|
||||
/// Calculate the offset from a mut pointer
|
||||
#[inline]
|
||||
#[cfg(stage0)]
|
||||
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
|
||||
#[inline]
|
||||
#[cfg(not(stage0))]
|
||||
pub fn mut_offset<T>(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<T>() -> *mut T { 0 as *mut T }
|
|||
|
||||
/// Returns true if the pointer is equal to the null pointer.
|
||||
#[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.
|
||||
#[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.
|
||||
|
@ -87,8 +100,10 @@ pub fn is_not_null<T>(ptr: *const T) -> bool { !is_null(ptr) }
|
|||
*/
|
||||
#[inline]
|
||||
#[cfg(target_word_size = "32")]
|
||||
pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
|
||||
intrinsics::memmove32(dst, src as *T, count as u32);
|
||||
pub unsafe fn copy_memory<T,P:RawPtr<T>>(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<T>(dst: *mut T, src: *const T, count: uint) {
|
|||
*/
|
||||
#[inline]
|
||||
#[cfg(target_word_size = "64")]
|
||||
pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
|
||||
intrinsics::memmove64(dst, src as *T, count as u64);
|
||||
pub unsafe fn copy_memory<T,P:RawPtr<T>>(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<T>(dst: *mut T, src: *const T, count: uint) {
|
|||
*/
|
||||
#[inline]
|
||||
#[cfg(target_word_size = "32")]
|
||||
pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint) {
|
||||
intrinsics::memcpy32(dst, src as *T, count as u32);
|
||||
pub unsafe fn copy_nonoverlapping_memory<T,P:RawPtr<T>>(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<T>(dst: *mut T, src: *const T, count: u
|
|||
*/
|
||||
#[inline]
|
||||
#[cfg(target_word_size = "64")]
|
||||
pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint) {
|
||||
intrinsics::memcpy64(dst, src as *T, count as u64);
|
||||
pub unsafe fn copy_nonoverlapping_memory<T,P:RawPtr<T>>(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<T>(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<T>(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<T>(thing: &mut T) -> *mut T {
|
||||
|
@ -269,8 +288,10 @@ pub unsafe fn array_each<T>(arr: **T, cb: &fn(*T)) {
|
|||
|
||||
#[allow(missing_doc)]
|
||||
pub trait RawPtr<T> {
|
||||
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<T> {
|
|||
|
||||
/// Extension methods for immutable pointers
|
||||
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.
|
||||
#[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 @@ impl<T> RawPtr<T> for *T {
|
|||
|
||||
/// Extension methods for mutable pointers
|
||||
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.
|
||||
#[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 @@ impl<T> RawPtr<T> for *mut T {
|
|||
|
||||
// Equality for pointers
|
||||
#[cfg(not(test))]
|
||||
impl<T> Eq for *const T {
|
||||
impl<T> Eq for *T {
|
||||
#[inline]
|
||||
fn eq(&self, other: &*const T) -> bool {
|
||||
fn eq(&self, other: &*T) -> bool {
|
||||
(*self as uint) == (*other as uint)
|
||||
}
|
||||
#[inline]
|
||||
fn ne(&self, other: &*const T) -> bool { !self.eq(other) }
|
||||
fn ne(&self, other: &*T) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl<T> Eq for *mut T {
|
||||
#[inline]
|
||||
fn eq(&self, other: &*mut T) -> bool {
|
||||
(*self as uint) == (*other as uint)
|
||||
}
|
||||
#[inline]
|
||||
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
|
||||
|
@ -412,21 +474,41 @@ mod externfnpointers {
|
|||
|
||||
// Comparison for pointers
|
||||
#[cfg(not(test))]
|
||||
impl<T> Ord for *const T {
|
||||
impl<T> Ord for *T {
|
||||
#[inline]
|
||||
fn lt(&self, other: &*const T) -> bool {
|
||||
fn lt(&self, other: &*T) -> bool {
|
||||
(*self as uint) < (*other as uint)
|
||||
}
|
||||
#[inline]
|
||||
fn le(&self, other: &*const T) -> bool {
|
||||
fn le(&self, other: &*T) -> bool {
|
||||
(*self as uint) <= (*other as uint)
|
||||
}
|
||||
#[inline]
|
||||
fn ge(&self, other: &*const T) -> bool {
|
||||
fn ge(&self, other: &*T) -> bool {
|
||||
(*self as uint) >= (*other as uint)
|
||||
}
|
||||
#[inline]
|
||||
fn gt(&self, other: &*const T) -> bool {
|
||||
fn gt(&self, other: &*T) -> bool {
|
||||
(*self as uint) > (*other as uint)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl<T> Ord for *mut T {
|
||||
#[inline]
|
||||
fn lt(&self, other: &*mut T) -> bool {
|
||||
(*self as uint) < (*other as uint)
|
||||
}
|
||||
#[inline]
|
||||
fn le(&self, other: &*mut T) -> bool {
|
||||
(*self as uint) <= (*other as uint)
|
||||
}
|
||||
#[inline]
|
||||
fn ge(&self, other: &*mut T) -> bool {
|
||||
(*self as uint) >= (*other as uint)
|
||||
}
|
||||
#[inline]
|
||||
fn gt(&self, other: &*mut T) -> bool {
|
||||
(*self as uint) > (*other as uint)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,8 +94,8 @@ unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) {
|
|||
static ENABLE_DEBUG: bool = false;
|
||||
|
||||
#[inline]
|
||||
unsafe fn debug_borrow<T>(tag: &'static str,
|
||||
p: *const T,
|
||||
unsafe fn debug_borrow<T,P:RawPtr<T>>(tag: &'static str,
|
||||
p: P,
|
||||
old_bits: uint,
|
||||
new_bits: uint,
|
||||
filename: *c_char,
|
||||
|
@ -106,15 +107,15 @@ unsafe fn debug_borrow<T>(tag: &'static str,
|
|||
debug_borrow_slow(tag, p, old_bits, new_bits, filename, line);
|
||||
}
|
||||
|
||||
unsafe fn debug_borrow_slow<T>(tag: &'static str,
|
||||
p: *const T,
|
||||
unsafe fn debug_borrow_slow<T,P:RawPtr<T>>(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(" ");
|
||||
|
|
|
@ -554,6 +554,7 @@ impl Scheduler {
|
|||
|
||||
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 => {
|
||||
|
|
|
@ -343,7 +343,14 @@ impl<A:IterBytes> IterBytes for ~A {
|
|||
|
||||
// NB: raw-pointer IterBytes does _not_ dereference
|
||||
// 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]
|
||||
fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
|
||||
(*self as uint).iter_bytes(lsb0, f)
|
||||
|
|
|
@ -54,8 +54,10 @@ pub fn swap<T>(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`
|
||||
|
|
|
@ -1122,14 +1122,7 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
|
|||
* foreign interop.
|
||||
*/
|
||||
#[inline]
|
||||
fn as_imm_buf<U>(&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<U>(&self, f: &fn(*T, uint) -> U) -> U {
|
||||
let s = self.repr();
|
||||
f(s.data, s.len / sys::nonzero_size_of::<T>())
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 @@ impl ParserObsoleteMethods for Parser {
|
|||
"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 @@ impl ParserObsoleteMethods for Parser {
|
|||
"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);
|
||||
|
|
|
@ -38,7 +38,7 @@ use ast::{ident, impure_fn, inherited, item, item_, item_static};
|
|||
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 @@ impl Parser {
|
|||
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 @@ impl Parser {
|
|||
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 @@ impl Parser {
|
|||
} 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 @@ impl Parser {
|
|||
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
|
||||
|
|
|
@ -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 */ }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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() {
|
||||
}
|
||||
|
|
|
@ -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 <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() {
|
|||
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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 <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() {
|
||||
}
|
|
@ -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 <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) {
|
|||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -13,7 +13,7 @@ struct Foo {
|
|||
}
|
||||
|
||||
impl Foo {
|
||||
pub fn f(&const self) {}
|
||||
pub fn f(&self) {}
|
||||
}
|
||||
|
||||
fn g(x: &mut Foo) {
|
||||
|
|
|
@ -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 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>) {
|
||||
match *v {
|
||||
Some(ref i) => {impure(*i)} // OK because immutable
|
|
@ -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() {
|
||||
}
|
|
@ -49,8 +49,8 @@ impl<T> cat<T> {
|
|||
}
|
||||
|
||||
impl<T> Container for cat<T> {
|
||||
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<T> Mutable for cat<T> {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 ];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue