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"]
|
#[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,
|
||||||
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
|
||||||
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 {
|
||||||
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) {
|
||||||
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 @@ use mc = middle::mem_categorization;
|
||||||
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 @@ impl<'self> CheckLoanCtxt<'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 @@ impl<'self> CheckLoanCtxt<'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 @@ impl<'self> CheckLoanCtxt<'self> {
|
||||||
// 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 @@ impl<'self> CheckLoanCtxt<'self> {
|
||||||
|
|
||||||
// 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 @@
|
||||||
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,
|
||||||
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 {
|
||||||
|
|
||||||
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 @@ impl GuaranteeLifetimeContext {
|
||||||
// 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 @@ use middle::ty;
|
||||||
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,
|
||||||
// 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,
|
||||||
// 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 @@ impl GatherLoanCtxt {
|
||||||
|
|
||||||
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 @@ impl GatherLoanCtxt {
|
||||||
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 @@ impl GatherLoanCtxt {
|
||||||
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 @@ impl GatherLoanCtxt {
|
||||||
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 @@ impl GatherLoanCtxt {
|
||||||
// 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 @@ impl GatherLoanCtxt {
|
||||||
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 @@ impl GatherLoanCtxt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 @@ impl GatherLoanCtxt {
|
||||||
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 @@ impl GatherLoanCtxt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
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 @@ impl GatherLoanCtxt {
|
||||||
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 @@ impl GatherLoanCtxt {
|
||||||
// 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 @@ use std::vec;
|
||||||
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 @@ impl RestrictionsContext {
|
||||||
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 {
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// 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 @@ impl ToStr for DynaFreezeKind {
|
||||||
// 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 @@ impl BorrowckCtxt {
|
||||||
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 @@ use middle::typeck;
|
||||||
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 {
|
||||||
#[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 {
|
||||||
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 @@ impl 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 @@ impl 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 @@ impl MutabilityCategory {
|
||||||
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 @@ impl MutabilityCategory {
|
||||||
match *self {
|
match *self {
|
||||||
McDeclared | McInherited => "mutable",
|
McDeclared | McInherited => "mutable",
|
||||||
McImmutable => "immutable",
|
McImmutable => "immutable",
|
||||||
McReadOnly => "const"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -610,7 +606,6 @@ impl mem_categorization_ctxt {
|
||||||
-> 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 @@ impl mem_categorization_ctxt {
|
||||||
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 @@ impl cmt_ {
|
||||||
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 @@ pub fn ast_ty_to_ty<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 @@ use std::vec;
|
||||||
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 @@ impl<'self> LookupContext<'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 @@ impl<'self> LookupContext<'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 @@ impl<'self> LookupContext<'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 @@ impl<'self> LookupContext<'self> {
|
||||||
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 @@ impl<'self> LookupContext<'self> {
|
||||||
}
|
}
|
||||||
|
|
||||||
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 @@ use middle::typeck::infer::{cres, InferCtxt};
|
||||||
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 @@ impl Combine for Glb {
|
||||||
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 @@ impl Combine for Glb {
|
||||||
|
|
||||||
// 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 @@ use middle::typeck::isr_alist;
|
||||||
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 @@ impl Combine for Lub {
|
||||||
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 @@ impl Combine for Lub {
|
||||||
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 @@ use util::ppaux::bound_region_to_str;
|
||||||
|
|
||||||
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 @@ impl Combine for Sub {
|
||||||
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 @@ impl Combine for Sub {
|
||||||
// (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 {
|
||||||
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 @@
|
||||||
|
|
||||||
//! 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 {
|
||||||
|
|
||||||
/// 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 @@
|
||||||
#[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,
|
||||||
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 @@ impl MemoryMap {
|
||||||
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 @@
|
||||||
|
|
||||||
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 @@ use util::swap;
|
||||||
|
|
||||||
/// 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
|
|
||||||
#[inline]
|
|
||||||
pub fn const_offset<T>(ptr: *const T, count: int) -> *const T {
|
|
||||||
unsafe { intrinsics::offset(ptr as *T, count) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculate the offset from a mut pointer
|
/// Calculate the offset from a mut pointer
|
||||||
#[inline]
|
#[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 {
|
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 }
|
||||||
|
|
||||||
/// 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) }
|
||||||
*/
|
*/
|
||||||
#[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) {
|
||||||
*/
|
*/
|
||||||
#[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) {
|
||||||
*/
|
*/
|
||||||
#[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
|
||||||
*/
|
*/
|
||||||
#[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 {
|
||||||
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)) {
|
||||||
|
|
||||||
#[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> {
|
||||||
|
|
||||||
/// 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 @@ impl<T> RawPtr<T> for *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 @@ impl<T> RawPtr<T> for *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]
|
#[inline]
|
||||||
fn eq(&self, other: &*const T) -> bool {
|
fn eq(&self, other: &*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: &*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
|
// Equality for extern "C" fn pointers
|
||||||
|
@ -412,21 +474,41 @@ mod externfnpointers {
|
||||||
|
|
||||||
// Comparison for pointers
|
// Comparison for pointers
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
impl<T> Ord for *const T {
|
impl<T> Ord for *T {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn lt(&self, other: &*const T) -> bool {
|
fn lt(&self, other: &*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: &*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: &*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: &*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)
|
(*self as uint) > (*other as uint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
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,
|
||||||
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 @@ impl Scheduler {
|
||||||
|
|
||||||
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 @@ impl<A:IterBytes> IterBytes for ~A {
|
||||||
|
|
||||||
// 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) {
|
||||||
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 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
|
||||||
* 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_ {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[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 {
|
||||||
ObsoleteMode,
|
ObsoleteMode,
|
||||||
ObsoleteImplicitSelf,
|
ObsoleteImplicitSelf,
|
||||||
ObsoleteLifetimeNotation,
|
ObsoleteLifetimeNotation,
|
||||||
ObsoleteConstManagedPointer,
|
|
||||||
ObsoletePurity,
|
ObsoletePurity,
|
||||||
ObsoleteStaticMethod,
|
ObsoleteStaticMethod,
|
||||||
ObsoleteConstItem,
|
ObsoleteConstItem,
|
||||||
|
@ -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 @@ impl ParserObsoleteMethods for Parser {
|
||||||
"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 @@ impl ParserObsoleteMethods for Parser {
|
||||||
"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 @@ use ast::{ident, impure_fn, inherited, item, item_, item_static};
|
||||||
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 @@ impl Parser {
|
||||||
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 @@ impl Parser {
|
||||||
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 @@ impl Parser {
|
||||||
} 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 @@ impl Parser {
|
||||||
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) {
|
||||||
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) {
|
||||||
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) {
|
||||||
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 */ }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
**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) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
||||||
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() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
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() {
|
||||||
|
|
||||||
// @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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
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 @@
|
||||||
|
|
||||||
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() {
|
||||||
|
|
||||||
// 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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
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>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
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 @@ impl<T> cat<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
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 @@
|
||||||
// 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 ];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue