mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-21 19:33:16 +00:00
librustc: Make self
and static
into keywords
This commit is contained in:
parent
06ef889cdc
commit
5d3559e645
@ -44,21 +44,21 @@ pub fn empty_cell<T>() -> Cell<T> {
|
||||
pub impl<T> Cell<T> {
|
||||
/// Yields the value, failing if the cell is empty.
|
||||
fn take(&self) -> T {
|
||||
let self = unsafe { transmute_mut(self) };
|
||||
if self.is_empty() {
|
||||
let this = unsafe { transmute_mut(self) };
|
||||
if this.is_empty() {
|
||||
fail!(~"attempt to take an empty cell");
|
||||
}
|
||||
|
||||
replace(&mut self.value, None).unwrap()
|
||||
replace(&mut this.value, None).unwrap()
|
||||
}
|
||||
|
||||
/// Returns the value, failing if the cell is full.
|
||||
fn put_back(&self, value: T) {
|
||||
let self = unsafe { transmute_mut(self) };
|
||||
if !self.is_empty() {
|
||||
let this = unsafe { transmute_mut(self) };
|
||||
if !this.is_empty() {
|
||||
fail!(~"attempt to put a value back into a full cell");
|
||||
}
|
||||
self.value = Some(value);
|
||||
this.value = Some(value);
|
||||
}
|
||||
|
||||
/// Returns true if the cell is empty and false if the cell is full.
|
||||
|
@ -116,10 +116,12 @@ pub trait Buildable<A> {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn _eachi<A,IA:BaseIter<A>>(self: &IA, blk: &fn(uint, &A) -> bool) -> bool {
|
||||
pub fn _eachi<A,IA:BaseIter<A>>(this: &IA, blk: &fn(uint, &A) -> bool) -> bool {
|
||||
let mut i = 0;
|
||||
for self.each |a| {
|
||||
if !blk(i, a) { return false; }
|
||||
for this.each |a| {
|
||||
if !blk(i, a) {
|
||||
return false;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
return true;
|
||||
@ -135,47 +137,47 @@ pub fn eachi<A,IA:BaseIter<A>>(self: &IA, blk: &fn(uint, &A) -> bool) -> bool {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn all<A,IA:BaseIter<A>>(self: &IA, blk: &fn(&A) -> bool) -> bool {
|
||||
for self.each |a| {
|
||||
pub fn all<A,IA:BaseIter<A>>(this: &IA, blk: &fn(&A) -> bool) -> bool {
|
||||
for this.each |a| {
|
||||
if !blk(a) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn any<A,IA:BaseIter<A>>(self: &IA, blk: &fn(&A) -> bool) -> bool {
|
||||
for self.each |a| {
|
||||
pub fn any<A,IA:BaseIter<A>>(this: &IA, blk: &fn(&A) -> bool) -> bool {
|
||||
for this.each |a| {
|
||||
if blk(a) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn filter_to_vec<A:Copy,IA:BaseIter<A>>(self: &IA,
|
||||
pub fn filter_to_vec<A:Copy,IA:BaseIter<A>>(this: &IA,
|
||||
prd: &fn(&A) -> bool)
|
||||
-> ~[A] {
|
||||
do vec::build_sized_opt(self.size_hint()) |push| {
|
||||
for self.each |a| {
|
||||
do vec::build_sized_opt(this.size_hint()) |push| {
|
||||
for this.each |a| {
|
||||
if prd(a) { push(*a); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn map_to_vec<A,B,IA:BaseIter<A>>(self: &IA, op: &fn(&A) -> B) -> ~[B] {
|
||||
do vec::build_sized_opt(self.size_hint()) |push| {
|
||||
for self.each |a| {
|
||||
pub fn map_to_vec<A,B,IA:BaseIter<A>>(this: &IA, op: &fn(&A) -> B) -> ~[B] {
|
||||
do vec::build_sized_opt(this.size_hint()) |push| {
|
||||
for this.each |a| {
|
||||
push(op(a));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn flat_map_to_vec<A,B,IA:BaseIter<A>,IB:BaseIter<B>>(self: &IA,
|
||||
pub fn flat_map_to_vec<A,B,IA:BaseIter<A>,IB:BaseIter<B>>(this: &IA,
|
||||
op: &fn(&A) -> IB)
|
||||
-> ~[B] {
|
||||
do vec::build |push| {
|
||||
for self.each |a| {
|
||||
for this.each |a| {
|
||||
for op(a).each |&b| {
|
||||
push(b);
|
||||
}
|
||||
@ -184,31 +186,31 @@ pub fn flat_map_to_vec<A,B,IA:BaseIter<A>,IB:BaseIter<B>>(self: &IA,
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn foldl<A,B,IA:BaseIter<A>>(self: &IA, b0: B, blk: &fn(&B, &A) -> B)
|
||||
pub fn foldl<A,B,IA:BaseIter<A>>(this: &IA, b0: B, blk: &fn(&B, &A) -> B)
|
||||
-> B {
|
||||
let mut b = b0;
|
||||
for self.each |a| {
|
||||
for this.each |a| {
|
||||
b = blk(&b, a);
|
||||
}
|
||||
b
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_vec<A:Copy,IA:BaseIter<A>>(self: &IA) -> ~[A] {
|
||||
map_to_vec(self, |&x| x)
|
||||
pub fn to_vec<A:Copy,IA:BaseIter<A>>(this: &IA) -> ~[A] {
|
||||
map_to_vec(this, |&x| x)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn contains<A:Eq,IA:BaseIter<A>>(self: &IA, x: &A) -> bool {
|
||||
for self.each |a| {
|
||||
pub fn contains<A:Eq,IA:BaseIter<A>>(this: &IA, x: &A) -> bool {
|
||||
for this.each |a| {
|
||||
if *a == *x { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn count<A:Eq,IA:BaseIter<A>>(self: &IA, x: &A) -> uint {
|
||||
do foldl(self, 0) |count, value| {
|
||||
pub fn count<A:Eq,IA:BaseIter<A>>(this: &IA, x: &A) -> uint {
|
||||
do foldl(this, 0) |count, value| {
|
||||
if *value == *x {
|
||||
*count + 1
|
||||
} else {
|
||||
@ -218,10 +220,10 @@ pub fn count<A:Eq,IA:BaseIter<A>>(self: &IA, x: &A) -> uint {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn position<A,IA:BaseIter<A>>(self: &IA, f: &fn(&A) -> bool)
|
||||
pub fn position<A,IA:BaseIter<A>>(this: &IA, f: &fn(&A) -> bool)
|
||||
-> Option<uint> {
|
||||
let mut i = 0;
|
||||
for self.each |a| {
|
||||
for this.each |a| {
|
||||
if f(a) { return Some(i); }
|
||||
i += 1;
|
||||
}
|
||||
@ -253,8 +255,8 @@ pub fn repeat(times: uint, blk: &fn() -> bool) -> bool {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn min<A:Copy + Ord,IA:BaseIter<A>>(self: &IA) -> A {
|
||||
match do foldl::<A,Option<A>,IA>(self, None) |a, b| {
|
||||
pub fn min<A:Copy + Ord,IA:BaseIter<A>>(this: &IA) -> A {
|
||||
match do foldl::<A,Option<A>,IA>(this, None) |a, b| {
|
||||
match a {
|
||||
&Some(ref a_) if *a_ < *b => {
|
||||
*(a)
|
||||
@ -268,8 +270,8 @@ pub fn min<A:Copy + Ord,IA:BaseIter<A>>(self: &IA) -> A {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn max<A:Copy + Ord,IA:BaseIter<A>>(self: &IA) -> A {
|
||||
match do foldl::<A,Option<A>,IA>(self, None) |a, b| {
|
||||
pub fn max<A:Copy + Ord,IA:BaseIter<A>>(this: &IA) -> A {
|
||||
match do foldl::<A,Option<A>,IA>(this, None) |a, b| {
|
||||
match a {
|
||||
&Some(ref a_) if *a_ > *b => {
|
||||
*(a)
|
||||
@ -283,9 +285,9 @@ pub fn max<A:Copy + Ord,IA:BaseIter<A>>(self: &IA) -> A {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn find<A:Copy,IA:BaseIter<A>>(self: &IA, f: &fn(&A) -> bool)
|
||||
pub fn find<A:Copy,IA:BaseIter<A>>(this: &IA, f: &fn(&A) -> bool)
|
||||
-> Option<A> {
|
||||
for self.each |i| {
|
||||
for this.each |i| {
|
||||
if f(i) { return Some(*i) }
|
||||
}
|
||||
return None;
|
||||
|
@ -118,15 +118,15 @@ pub impl Scheduler {
|
||||
fn resume_task_from_queue(~self) -> bool {
|
||||
assert!(!self.in_task_context());
|
||||
|
||||
let mut self = self;
|
||||
match self.task_queue.pop_front() {
|
||||
let mut this = self;
|
||||
match this.task_queue.pop_front() {
|
||||
Some(task) => {
|
||||
self.resume_task_immediately(task);
|
||||
this.resume_task_immediately(task);
|
||||
return true;
|
||||
}
|
||||
None => {
|
||||
rtdebug!("no tasks in queue");
|
||||
local_sched::put(self);
|
||||
local_sched::put(this);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -165,16 +165,16 @@ pub impl Scheduler {
|
||||
// Core scheduling ops
|
||||
|
||||
fn resume_task_immediately(~self, task: ~Task) {
|
||||
let mut self = self;
|
||||
assert!(!self.in_task_context());
|
||||
let mut this = self;
|
||||
assert!(!this.in_task_context());
|
||||
|
||||
rtdebug!("scheduling a task");
|
||||
|
||||
// Store the task in the scheduler so it can be grabbed later
|
||||
self.current_task = Some(task);
|
||||
self.enqueue_cleanup_job(DoNothing);
|
||||
this.current_task = Some(task);
|
||||
this.enqueue_cleanup_job(DoNothing);
|
||||
|
||||
local_sched::put(self);
|
||||
local_sched::put(this);
|
||||
|
||||
// Take pointers to both the task and scheduler's saved registers.
|
||||
unsafe {
|
||||
@ -203,17 +203,17 @@ pub impl Scheduler {
|
||||
/// running task. It gets transmuted to the scheduler's lifetime
|
||||
/// and called while the task is blocked.
|
||||
fn deschedule_running_task_and_then(~self, f: &fn(~Task)) {
|
||||
let mut self = self;
|
||||
assert!(self.in_task_context());
|
||||
let mut this = self;
|
||||
assert!(this.in_task_context());
|
||||
|
||||
rtdebug!("blocking task");
|
||||
|
||||
let blocked_task = self.current_task.swap_unwrap();
|
||||
let blocked_task = this.current_task.swap_unwrap();
|
||||
let f_fake_region = unsafe { transmute::<&fn(~Task), &fn(~Task)>(f) };
|
||||
let f_opaque = ClosureConverter::from_fn(f_fake_region);
|
||||
self.enqueue_cleanup_job(GiveTask(blocked_task, f_opaque));
|
||||
this.enqueue_cleanup_job(GiveTask(blocked_task, f_opaque));
|
||||
|
||||
local_sched::put(self);
|
||||
local_sched::put(this);
|
||||
|
||||
let sched = unsafe { local_sched::unsafe_borrow() };
|
||||
let (sched_context, last_task_context, _) = sched.get_contexts();
|
||||
@ -229,18 +229,18 @@ pub impl Scheduler {
|
||||
/// You would want to think hard about doing this, e.g. if there are
|
||||
/// pending I/O events it would be a bad idea.
|
||||
fn switch_running_tasks_and_then(~self, next_task: ~Task, f: &fn(~Task)) {
|
||||
let mut self = self;
|
||||
assert!(self.in_task_context());
|
||||
let mut this = self;
|
||||
assert!(this.in_task_context());
|
||||
|
||||
rtdebug!("switching tasks");
|
||||
|
||||
let old_running_task = self.current_task.swap_unwrap();
|
||||
let old_running_task = this.current_task.swap_unwrap();
|
||||
let f_fake_region = unsafe { transmute::<&fn(~Task), &fn(~Task)>(f) };
|
||||
let f_opaque = ClosureConverter::from_fn(f_fake_region);
|
||||
self.enqueue_cleanup_job(GiveTask(old_running_task, f_opaque));
|
||||
self.current_task = Some(next_task);
|
||||
this.enqueue_cleanup_job(GiveTask(old_running_task, f_opaque));
|
||||
this.current_task = Some(next_task);
|
||||
|
||||
local_sched::put(self);
|
||||
local_sched::put(this);
|
||||
|
||||
unsafe {
|
||||
let sched = local_sched::unsafe_borrow();
|
||||
|
@ -141,8 +141,8 @@ pub impl StreamWatcher {
|
||||
|
||||
fn close(self, cb: NullCallback) {
|
||||
{
|
||||
let mut self = self;
|
||||
let data = get_watcher_data(&mut self);
|
||||
let mut this = self;
|
||||
let data = get_watcher_data(&mut this);
|
||||
assert!(data.close_cb.is_none());
|
||||
data.close_cb = Some(cb);
|
||||
}
|
||||
|
@ -43,10 +43,10 @@ pub impl UvEventLoop {
|
||||
impl Drop for UvEventLoop {
|
||||
fn finalize(&self) {
|
||||
// XXX: Need mutable finalizer
|
||||
let self = unsafe {
|
||||
let this = unsafe {
|
||||
transmute::<&UvEventLoop, &mut UvEventLoop>(self)
|
||||
};
|
||||
self.uvio.uv_loop().close();
|
||||
this.uvio.uv_loop().close();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -632,7 +632,7 @@ pub fn build_session_options(binary: @~str,
|
||||
let extra_debuginfo = debugging_opts & session::extra_debug_info != 0;
|
||||
let debuginfo = debugging_opts & session::debug_info != 0 ||
|
||||
extra_debuginfo;
|
||||
let static = debugging_opts & session::static != 0;
|
||||
let statik = debugging_opts & session::statik != 0;
|
||||
let target =
|
||||
match target_opt {
|
||||
None => host_triple(),
|
||||
@ -660,7 +660,7 @@ pub fn build_session_options(binary: @~str,
|
||||
|
||||
let sopts = @session::options {
|
||||
crate_type: crate_type,
|
||||
is_static: static,
|
||||
is_static: statik,
|
||||
gc: gc,
|
||||
optimize: opt_level,
|
||||
debuginfo: debuginfo,
|
||||
|
@ -62,7 +62,7 @@ pub static gc: uint = 1 << 18;
|
||||
pub static jit: uint = 1 << 19;
|
||||
pub static debug_info: uint = 1 << 20;
|
||||
pub static extra_debug_info: uint = 1 << 21;
|
||||
pub static static: uint = 1 << 22;
|
||||
pub static statik: uint = 1 << 22;
|
||||
pub static print_link_args: uint = 1 << 23;
|
||||
|
||||
pub fn debugging_opts_map() -> ~[(~str, ~str, uint)] {
|
||||
@ -98,7 +98,7 @@ pub fn debugging_opts_map() -> ~[(~str, ~str, uint)] {
|
||||
extra_debug_info),
|
||||
(~"debug-info", ~"Produce debug info (experimental)", debug_info),
|
||||
(~"static", ~"Use or produce static libraries or binaries " +
|
||||
"(experimental)", static)
|
||||
"(experimental)", statik)
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -359,7 +359,7 @@ pub impl<'self> CheckLoanCtxt<'self> {
|
||||
self, expr, cmt);
|
||||
}
|
||||
|
||||
fn mark_variable_as_used_mut(self: &CheckLoanCtxt,
|
||||
fn mark_variable_as_used_mut(this: &CheckLoanCtxt,
|
||||
cmt: mc::cmt) {
|
||||
//! If the mutability of the `cmt` being written is inherited
|
||||
//! from a local variable, liveness will
|
||||
@ -370,12 +370,12 @@ pub impl<'self> CheckLoanCtxt<'self> {
|
||||
let mut cmt = cmt;
|
||||
loop {
|
||||
debug!("mark_writes_through_upvars_as_used_mut(cmt=%s)",
|
||||
cmt.repr(self.tcx()));
|
||||
cmt.repr(this.tcx()));
|
||||
match cmt.cat {
|
||||
mc::cat_local(id) |
|
||||
mc::cat_arg(id) |
|
||||
mc::cat_self(id) => {
|
||||
self.tcx().used_mut_nodes.insert(id);
|
||||
this.tcx().used_mut_nodes.insert(id);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -411,14 +411,14 @@ pub impl<'self> CheckLoanCtxt<'self> {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_for_aliasable_mutable_writes(self: &CheckLoanCtxt,
|
||||
fn check_for_aliasable_mutable_writes(this: &CheckLoanCtxt,
|
||||
expr: @ast::expr,
|
||||
cmt: mc::cmt) -> bool {
|
||||
//! Safety checks related to writes to aliasable, mutable locations
|
||||
|
||||
let guarantor = cmt.guarantor();
|
||||
debug!("check_for_aliasable_mutable_writes(cmt=%s, guarantor=%s)",
|
||||
cmt.repr(self.tcx()), guarantor.repr(self.tcx()));
|
||||
cmt.repr(this.tcx()), guarantor.repr(this.tcx()));
|
||||
match guarantor.cat {
|
||||
mc::cat_deref(b, _, mc::region_ptr(m_mutbl, _)) => {
|
||||
// Statically prohibit writes to `&mut` when aliasable
|
||||
@ -426,7 +426,7 @@ pub impl<'self> CheckLoanCtxt<'self> {
|
||||
match b.freely_aliasable() {
|
||||
None => {}
|
||||
Some(cause) => {
|
||||
self.bccx.report_aliasability_violation(
|
||||
this.bccx.report_aliasability_violation(
|
||||
expr.span,
|
||||
MutabilityViolation,
|
||||
cause);
|
||||
@ -442,7 +442,7 @@ pub impl<'self> CheckLoanCtxt<'self> {
|
||||
derefs: deref_count
|
||||
};
|
||||
debug!("Inserting write guard at %?", key);
|
||||
self.bccx.write_guard_map.insert(key);
|
||||
this.bccx.write_guard_map.insert(key);
|
||||
}
|
||||
|
||||
_ => {}
|
||||
@ -452,7 +452,7 @@ pub impl<'self> CheckLoanCtxt<'self> {
|
||||
}
|
||||
|
||||
fn check_for_assignment_to_restricted_or_frozen_location(
|
||||
self: &CheckLoanCtxt,
|
||||
this: &CheckLoanCtxt,
|
||||
expr: @ast::expr,
|
||||
cmt: mc::cmt) -> bool
|
||||
{
|
||||
@ -494,11 +494,11 @@ pub impl<'self> CheckLoanCtxt<'self> {
|
||||
// `RESTR_MUTATE` restriction whenever the contents of an
|
||||
// owned pointer are borrowed, and hence while `v[*]` is not
|
||||
// restricted from being written, `v` is.
|
||||
for self.each_in_scope_restriction(expr.id, loan_path)
|
||||
for this.each_in_scope_restriction(expr.id, loan_path)
|
||||
|loan, restr|
|
||||
{
|
||||
if restr.set.intersects(RESTR_MUTATE) {
|
||||
self.report_illegal_mutation(expr, loan_path, loan);
|
||||
this.report_illegal_mutation(expr, loan_path, loan);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -557,9 +557,9 @@ pub impl<'self> CheckLoanCtxt<'self> {
|
||||
}
|
||||
|
||||
// Check for a non-const loan of `loan_path`
|
||||
for self.each_in_scope_loan(expr.id) |loan| {
|
||||
for this.each_in_scope_loan(expr.id) |loan| {
|
||||
if loan.loan_path == loan_path && loan.mutbl != m_const {
|
||||
self.report_illegal_mutation(expr, full_loan_path, loan);
|
||||
this.report_illegal_mutation(expr, full_loan_path, loan);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -674,7 +674,7 @@ fn check_loans_in_fn<'a>(fk: &visit::fn_kind,
|
||||
body: &ast::blk,
|
||||
sp: span,
|
||||
id: ast::node_id,
|
||||
self: @mut CheckLoanCtxt<'a>,
|
||||
this: @mut CheckLoanCtxt<'a>,
|
||||
visitor: visit::vt<@mut CheckLoanCtxt<'a>>) {
|
||||
match *fk {
|
||||
visit::fk_item_fn(*) |
|
||||
@ -685,48 +685,48 @@ fn check_loans_in_fn<'a>(fk: &visit::fn_kind,
|
||||
|
||||
visit::fk_anon(*) |
|
||||
visit::fk_fn_block(*) => {
|
||||
let fty = ty::node_id_to_type(self.tcx(), id);
|
||||
let fty = ty::node_id_to_type(this.tcx(), id);
|
||||
let fty_sigil = ty::ty_closure_sigil(fty);
|
||||
check_moves_from_captured_variables(self, id, fty_sigil);
|
||||
check_moves_from_captured_variables(this, id, fty_sigil);
|
||||
}
|
||||
}
|
||||
|
||||
visit::visit_fn(fk, decl, body, sp, id, self, visitor);
|
||||
visit::visit_fn(fk, decl, body, sp, id, this, visitor);
|
||||
|
||||
fn check_moves_from_captured_variables(self: @mut CheckLoanCtxt,
|
||||
fn check_moves_from_captured_variables(this: @mut CheckLoanCtxt,
|
||||
id: ast::node_id,
|
||||
fty_sigil: ast::Sigil) {
|
||||
match fty_sigil {
|
||||
ast::ManagedSigil | ast::OwnedSigil => {
|
||||
let cap_vars = self.bccx.capture_map.get(&id);
|
||||
let cap_vars = this.bccx.capture_map.get(&id);
|
||||
for cap_vars.each |cap_var| {
|
||||
match cap_var.mode {
|
||||
moves::CapRef | moves::CapCopy => { loop; }
|
||||
moves::CapMove => { }
|
||||
}
|
||||
let def_id = ast_util::def_id_of_def(cap_var.def).node;
|
||||
let ty = ty::node_id_to_type(self.tcx(), def_id);
|
||||
let cmt = self.bccx.cat_def(id, cap_var.span,
|
||||
let ty = ty::node_id_to_type(this.tcx(), def_id);
|
||||
let cmt = this.bccx.cat_def(id, cap_var.span,
|
||||
ty, cap_var.def);
|
||||
let move_err = self.analyze_move_out_from_cmt(cmt);
|
||||
let move_err = this.analyze_move_out_from_cmt(cmt);
|
||||
match move_err {
|
||||
MoveOk => {}
|
||||
MoveFromIllegalCmt(move_cmt) => {
|
||||
self.bccx.span_err(
|
||||
this.bccx.span_err(
|
||||
cap_var.span,
|
||||
fmt!("illegal by-move capture of %s",
|
||||
self.bccx.cmt_to_str(move_cmt)));
|
||||
this.bccx.cmt_to_str(move_cmt)));
|
||||
}
|
||||
MoveWhileBorrowed(loan_path, loan_span) => {
|
||||
self.bccx.span_err(
|
||||
this.bccx.span_err(
|
||||
cap_var.span,
|
||||
fmt!("cannot move `%s` into closure \
|
||||
because it is borrowed",
|
||||
self.bccx.loan_path_to_str(loan_path)));
|
||||
self.bccx.span_note(
|
||||
this.bccx.loan_path_to_str(loan_path)));
|
||||
this.bccx.span_note(
|
||||
loan_span,
|
||||
fmt!("borrow of `%s` occurs here",
|
||||
self.bccx.loan_path_to_str(loan_path)));
|
||||
this.bccx.loan_path_to_str(loan_path)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -738,48 +738,48 @@ fn check_loans_in_fn<'a>(fk: &visit::fn_kind,
|
||||
}
|
||||
|
||||
fn check_loans_in_local<'a>(local: @ast::local,
|
||||
self: @mut CheckLoanCtxt<'a>,
|
||||
this: @mut CheckLoanCtxt<'a>,
|
||||
vt: visit::vt<@mut CheckLoanCtxt<'a>>) {
|
||||
visit::visit_local(local, self, vt);
|
||||
visit::visit_local(local, this, vt);
|
||||
}
|
||||
|
||||
fn check_loans_in_expr<'a>(expr: @ast::expr,
|
||||
self: @mut CheckLoanCtxt<'a>,
|
||||
this: @mut CheckLoanCtxt<'a>,
|
||||
vt: visit::vt<@mut CheckLoanCtxt<'a>>) {
|
||||
debug!("check_loans_in_expr(expr=%s)",
|
||||
expr.repr(self.tcx()));
|
||||
expr.repr(this.tcx()));
|
||||
|
||||
visit::visit_expr(expr, self, vt);
|
||||
visit::visit_expr(expr, this, vt);
|
||||
|
||||
self.check_for_conflicting_loans(expr.id);
|
||||
this.check_for_conflicting_loans(expr.id);
|
||||
|
||||
if self.bccx.moves_map.contains(&expr.id) {
|
||||
self.check_move_out_from_expr(expr);
|
||||
if this.bccx.moves_map.contains(&expr.id) {
|
||||
this.check_move_out_from_expr(expr);
|
||||
}
|
||||
|
||||
match expr.node {
|
||||
ast::expr_assign(dest, _) |
|
||||
ast::expr_assign_op(_, dest, _) => {
|
||||
self.check_assignment(dest);
|
||||
this.check_assignment(dest);
|
||||
}
|
||||
ast::expr_call(f, ref args, _) => {
|
||||
self.check_call(expr, Some(f), f.id, f.span, *args);
|
||||
this.check_call(expr, Some(f), f.id, f.span, *args);
|
||||
}
|
||||
ast::expr_method_call(_, _, _, ref args, _) => {
|
||||
self.check_call(expr, None, expr.callee_id, expr.span, *args);
|
||||
this.check_call(expr, None, expr.callee_id, expr.span, *args);
|
||||
}
|
||||
ast::expr_index(_, rval) |
|
||||
ast::expr_binary(_, _, rval)
|
||||
if self.bccx.method_map.contains_key(&expr.id) => {
|
||||
self.check_call(expr,
|
||||
if this.bccx.method_map.contains_key(&expr.id) => {
|
||||
this.check_call(expr,
|
||||
None,
|
||||
expr.callee_id,
|
||||
expr.span,
|
||||
~[rval]);
|
||||
}
|
||||
ast::expr_unary(*) | ast::expr_index(*)
|
||||
if self.bccx.method_map.contains_key(&expr.id) => {
|
||||
self.check_call(expr,
|
||||
if this.bccx.method_map.contains_key(&expr.id) => {
|
||||
this.check_call(expr,
|
||||
None,
|
||||
expr.callee_id,
|
||||
expr.span,
|
||||
@ -790,10 +790,10 @@ fn check_loans_in_expr<'a>(expr: @ast::expr,
|
||||
}
|
||||
|
||||
fn check_loans_in_pat<'a>(pat: @ast::pat,
|
||||
self: @mut CheckLoanCtxt<'a>,
|
||||
this: @mut CheckLoanCtxt<'a>,
|
||||
vt: visit::vt<@mut CheckLoanCtxt<'a>>)
|
||||
{
|
||||
self.check_for_conflicting_loans(pat.id);
|
||||
this.check_for_conflicting_loans(pat.id);
|
||||
|
||||
// Note: moves out of pattern bindings are not checked by
|
||||
// the borrow checker, at least not directly. What happens
|
||||
@ -806,13 +806,14 @@ fn check_loans_in_pat<'a>(pat: @ast::pat,
|
||||
// rewalk the patterns and rebuild the pattern
|
||||
// categorizations.
|
||||
|
||||
visit::visit_pat(pat, self, vt);
|
||||
visit::visit_pat(pat, this, vt);
|
||||
}
|
||||
|
||||
fn check_loans_in_block<'a>(blk: &ast::blk,
|
||||
self: @mut CheckLoanCtxt<'a>,
|
||||
this: @mut CheckLoanCtxt<'a>,
|
||||
vt: visit::vt<@mut CheckLoanCtxt<'a>>)
|
||||
{
|
||||
visit::visit_block(blk, self, vt);
|
||||
self.check_for_conflicting_loans(blk.node.id);
|
||||
visit::visit_block(blk, this, vt);
|
||||
this.check_for_conflicting_loans(blk.node.id);
|
||||
}
|
||||
|
||||
|
@ -90,14 +90,14 @@ pub fn gather_loans(bccx: @BorrowckCtxt,
|
||||
}
|
||||
|
||||
fn add_pat_to_id_range(p: @ast::pat,
|
||||
self: @mut GatherLoanCtxt,
|
||||
this: @mut GatherLoanCtxt,
|
||||
v: visit::vt<@mut GatherLoanCtxt>) {
|
||||
// NB: This visitor function just adds the pat ids into the id
|
||||
// range. We gather loans that occur in patterns using the
|
||||
// `gather_pat()` method below. Eventually these two should be
|
||||
// brought together.
|
||||
self.id_range.add(p.id);
|
||||
visit::visit_pat(p, self, v);
|
||||
this.id_range.add(p.id);
|
||||
visit::visit_pat(p, this, v);
|
||||
}
|
||||
|
||||
fn gather_loans_in_fn(fk: &visit::fn_kind,
|
||||
@ -105,7 +105,7 @@ fn gather_loans_in_fn(fk: &visit::fn_kind,
|
||||
body: &ast::blk,
|
||||
sp: span,
|
||||
id: ast::node_id,
|
||||
self: @mut GatherLoanCtxt,
|
||||
this: @mut GatherLoanCtxt,
|
||||
v: visit::vt<@mut GatherLoanCtxt>) {
|
||||
match fk {
|
||||
// Do not visit items here, the outer loop in borrowck/mod
|
||||
@ -116,95 +116,95 @@ fn gather_loans_in_fn(fk: &visit::fn_kind,
|
||||
|
||||
// Visit closures as part of the containing item.
|
||||
&visit::fk_anon(*) | &visit::fk_fn_block(*) => {
|
||||
self.push_repeating_id(body.node.id);
|
||||
visit::visit_fn(fk, decl, body, sp, id, self, v);
|
||||
self.pop_repeating_id(body.node.id);
|
||||
this.push_repeating_id(body.node.id);
|
||||
visit::visit_fn(fk, decl, body, sp, id, this, v);
|
||||
this.pop_repeating_id(body.node.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn gather_loans_in_block(blk: &ast::blk,
|
||||
self: @mut GatherLoanCtxt,
|
||||
this: @mut GatherLoanCtxt,
|
||||
vt: visit::vt<@mut GatherLoanCtxt>) {
|
||||
self.id_range.add(blk.node.id);
|
||||
visit::visit_block(blk, self, vt);
|
||||
this.id_range.add(blk.node.id);
|
||||
visit::visit_block(blk, this, vt);
|
||||
}
|
||||
|
||||
fn gather_loans_in_expr(ex: @ast::expr,
|
||||
self: @mut GatherLoanCtxt,
|
||||
this: @mut GatherLoanCtxt,
|
||||
vt: visit::vt<@mut GatherLoanCtxt>) {
|
||||
let bccx = self.bccx;
|
||||
let bccx = this.bccx;
|
||||
let tcx = bccx.tcx;
|
||||
|
||||
debug!("gather_loans_in_expr(expr=%?/%s)",
|
||||
ex.id, pprust::expr_to_str(ex, tcx.sess.intr()));
|
||||
|
||||
self.id_range.add(ex.id);
|
||||
self.id_range.add(ex.callee_id);
|
||||
this.id_range.add(ex.id);
|
||||
this.id_range.add(ex.callee_id);
|
||||
|
||||
// If this expression is borrowed, have to ensure it remains valid:
|
||||
for tcx.adjustments.find(&ex.id).each |&adjustments| {
|
||||
self.guarantee_adjustments(ex, *adjustments);
|
||||
this.guarantee_adjustments(ex, *adjustments);
|
||||
}
|
||||
|
||||
// Special checks for various kinds of expressions:
|
||||
match ex.node {
|
||||
ast::expr_addr_of(mutbl, base) => {
|
||||
let base_cmt = self.bccx.cat_expr(base);
|
||||
let base_cmt = this.bccx.cat_expr(base);
|
||||
|
||||
// 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));
|
||||
self.guarantee_valid(ex.id, ex.span, base_cmt, mutbl, scope_r);
|
||||
visit::visit_expr(ex, self, vt);
|
||||
this.guarantee_valid(ex.id, ex.span, base_cmt, mutbl, scope_r);
|
||||
visit::visit_expr(ex, this, vt);
|
||||
}
|
||||
|
||||
ast::expr_match(ex_v, ref arms) => {
|
||||
let cmt = self.bccx.cat_expr(ex_v);
|
||||
let cmt = this.bccx.cat_expr(ex_v);
|
||||
for arms.each |arm| {
|
||||
for arm.pats.each |pat| {
|
||||
self.gather_pat(cmt, *pat, arm.body.node.id, ex.id);
|
||||
this.gather_pat(cmt, *pat, arm.body.node.id, ex.id);
|
||||
}
|
||||
}
|
||||
visit::visit_expr(ex, self, vt);
|
||||
visit::visit_expr(ex, this, vt);
|
||||
}
|
||||
|
||||
ast::expr_index(_, arg) |
|
||||
ast::expr_binary(_, _, arg)
|
||||
if self.bccx.method_map.contains_key(&ex.id) => {
|
||||
if this.bccx.method_map.contains_key(&ex.id) => {
|
||||
// Arguments in method calls are always passed by ref.
|
||||
//
|
||||
// Currently these do not use adjustments, so we have to
|
||||
// hardcode this check here (note that the receiver DOES use
|
||||
// adjustments).
|
||||
let scope_r = ty::re_scope(ex.id);
|
||||
let arg_cmt = self.bccx.cat_expr(arg);
|
||||
self.guarantee_valid(arg.id, arg.span, arg_cmt, m_imm, scope_r);
|
||||
visit::visit_expr(ex, self, vt);
|
||||
let arg_cmt = this.bccx.cat_expr(arg);
|
||||
this.guarantee_valid(arg.id, arg.span, arg_cmt, m_imm, scope_r);
|
||||
visit::visit_expr(ex, this, vt);
|
||||
}
|
||||
|
||||
// see explanation attached to the `root_ub` field:
|
||||
ast::expr_while(cond, ref body) => {
|
||||
// during the condition, can only root for the condition
|
||||
self.push_repeating_id(cond.id);
|
||||
(vt.visit_expr)(cond, self, vt);
|
||||
self.pop_repeating_id(cond.id);
|
||||
this.push_repeating_id(cond.id);
|
||||
(vt.visit_expr)(cond, this, vt);
|
||||
this.pop_repeating_id(cond.id);
|
||||
|
||||
// during body, can only root for the body
|
||||
self.push_repeating_id(body.node.id);
|
||||
(vt.visit_block)(body, self, vt);
|
||||
self.pop_repeating_id(body.node.id);
|
||||
this.push_repeating_id(body.node.id);
|
||||
(vt.visit_block)(body, this, vt);
|
||||
this.pop_repeating_id(body.node.id);
|
||||
}
|
||||
|
||||
// see explanation attached to the `root_ub` field:
|
||||
ast::expr_loop(ref body, _) => {
|
||||
self.push_repeating_id(body.node.id);
|
||||
visit::visit_expr(ex, self, vt);
|
||||
self.pop_repeating_id(body.node.id);
|
||||
this.push_repeating_id(body.node.id);
|
||||
visit::visit_expr(ex, this, vt);
|
||||
this.pop_repeating_id(body.node.id);
|
||||
}
|
||||
|
||||
_ => {
|
||||
visit::visit_expr(ex, self, vt);
|
||||
visit::visit_expr(ex, this, vt);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -624,13 +624,14 @@ pub impl GatherLoanCtxt {
|
||||
// Setting up info that preserve needs.
|
||||
// This is just the most convenient place to do it.
|
||||
fn add_stmt_to_map(stmt: @ast::stmt,
|
||||
self: @mut GatherLoanCtxt,
|
||||
this: @mut GatherLoanCtxt,
|
||||
vt: visit::vt<@mut GatherLoanCtxt>) {
|
||||
match stmt.node {
|
||||
ast::stmt_expr(_, id) | ast::stmt_semi(_, id) => {
|
||||
self.bccx.stmt_map.insert(id);
|
||||
this.bccx.stmt_map.insert(id);
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
visit::visit_stmt(stmt, self, vt);
|
||||
visit::visit_stmt(stmt, this, vt);
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ fn borrowck_fn(fk: &visit::fn_kind,
|
||||
body: &ast::blk,
|
||||
sp: span,
|
||||
id: ast::node_id,
|
||||
self: @BorrowckCtxt,
|
||||
this: @BorrowckCtxt,
|
||||
v: visit::vt<@BorrowckCtxt>) {
|
||||
match fk {
|
||||
&visit::fk_anon(*) |
|
||||
@ -124,11 +124,11 @@ fn borrowck_fn(fk: &visit::fn_kind,
|
||||
|
||||
// Check the body of fn items.
|
||||
let (id_range, all_loans) =
|
||||
gather_loans::gather_loans(self, body);
|
||||
gather_loans::gather_loans(this, body);
|
||||
let all_loans: &~[Loan] = &*all_loans; // FIXME(#5074)
|
||||
let mut dfcx =
|
||||
DataFlowContext::new(self.tcx,
|
||||
self.method_map,
|
||||
DataFlowContext::new(this.tcx,
|
||||
this.method_map,
|
||||
LoanDataFlowOperator,
|
||||
id_range,
|
||||
all_loans.len());
|
||||
@ -137,11 +137,11 @@ fn borrowck_fn(fk: &visit::fn_kind,
|
||||
dfcx.add_kill(loan.kill_scope, loan_idx);
|
||||
}
|
||||
dfcx.propagate(body);
|
||||
check_loans::check_loans(self, &dfcx, *all_loans, body);
|
||||
check_loans::check_loans(this, &dfcx, *all_loans, body);
|
||||
}
|
||||
}
|
||||
|
||||
visit::visit_fn(fk, decl, body, sp, id, self, v);
|
||||
visit::visit_fn(fk, decl, body, sp, id, this, v);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
@ -753,7 +753,8 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> {
|
||||
}
|
||||
|
||||
ast::expr_lit(*) |
|
||||
ast::expr_path(*) => {
|
||||
ast::expr_path(*) |
|
||||
ast::expr_self => {
|
||||
}
|
||||
|
||||
ast::expr_addr_of(_, e) |
|
||||
|
@ -45,7 +45,7 @@ fn collect_freevars(def_map: resolve::DefMap, blk: &ast::blk)
|
||||
|expr, depth, v| {
|
||||
match expr.node {
|
||||
ast::expr_fn_block(*) => visit::visit_expr(expr, depth + 1, v),
|
||||
ast::expr_path(*) => {
|
||||
ast::expr_path(*) | ast::expr_self => {
|
||||
let mut i = 0;
|
||||
match def_map.find(&expr.id) {
|
||||
None => fail!(~"path not found"),
|
||||
|
@ -341,11 +341,11 @@ pub impl IrMaps {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_item(item: @item, self: @mut IrMaps, v: vt<@mut IrMaps>) {
|
||||
let old_cur_item = self.cur_item;
|
||||
self.cur_item = item.id;
|
||||
visit::visit_item(item, self, v);
|
||||
self.cur_item = old_cur_item;
|
||||
fn visit_item(item: @item, this: @mut IrMaps, v: vt<@mut IrMaps>) {
|
||||
let old_cur_item = this.cur_item;
|
||||
this.cur_item = item.id;
|
||||
visit::visit_item(item, this, v);
|
||||
this.cur_item = old_cur_item;
|
||||
}
|
||||
|
||||
fn visit_fn(fk: &visit::fn_kind,
|
||||
@ -353,24 +353,24 @@ fn visit_fn(fk: &visit::fn_kind,
|
||||
body: &blk,
|
||||
sp: span,
|
||||
id: node_id,
|
||||
self: @mut IrMaps,
|
||||
this: @mut IrMaps,
|
||||
v: vt<@mut IrMaps>) {
|
||||
debug!("visit_fn: id=%d", id);
|
||||
let _i = ::util::common::indenter();
|
||||
|
||||
// swap in a new set of IR maps for this function body:
|
||||
let fn_maps = @mut IrMaps(self.tcx,
|
||||
self.method_map,
|
||||
self.variable_moves_map,
|
||||
self.capture_map,
|
||||
self.cur_item);
|
||||
let fn_maps = @mut IrMaps(this.tcx,
|
||||
this.method_map,
|
||||
this.variable_moves_map,
|
||||
this.capture_map,
|
||||
this.cur_item);
|
||||
|
||||
unsafe {
|
||||
debug!("creating fn_maps: %x", transmute(&*fn_maps));
|
||||
}
|
||||
|
||||
for decl.inputs.each |arg| {
|
||||
do pat_util::pat_bindings(self.tcx.def_map, arg.pat)
|
||||
do pat_util::pat_bindings(this.tcx.def_map, arg.pat)
|
||||
|_bm, arg_id, _x, path| {
|
||||
debug!("adding argument %d", arg_id);
|
||||
let ident = ast_util::path_to_ident(path);
|
||||
@ -378,7 +378,7 @@ fn visit_fn(fk: &visit::fn_kind,
|
||||
}
|
||||
};
|
||||
|
||||
// Add `self`, whether explicit or implicit.
|
||||
// Add `this`, whether explicit or implicit.
|
||||
match *fk {
|
||||
fk_method(_, _, method) => {
|
||||
match method.self_ty.node {
|
||||
@ -423,35 +423,35 @@ fn visit_fn(fk: &visit::fn_kind,
|
||||
lsets.warn_about_unused_args(decl, entry_ln);
|
||||
}
|
||||
|
||||
fn visit_local(local: @local, self: @mut IrMaps, vt: vt<@mut IrMaps>) {
|
||||
let def_map = self.tcx.def_map;
|
||||
fn visit_local(local: @local, this: @mut IrMaps, vt: vt<@mut IrMaps>) {
|
||||
let def_map = this.tcx.def_map;
|
||||
do pat_util::pat_bindings(def_map, local.node.pat) |_bm, p_id, sp, path| {
|
||||
debug!("adding local variable %d", p_id);
|
||||
let name = ast_util::path_to_ident(path);
|
||||
self.add_live_node_for_node(p_id, VarDefNode(sp));
|
||||
this.add_live_node_for_node(p_id, VarDefNode(sp));
|
||||
let kind = match local.node.init {
|
||||
Some(_) => FromLetWithInitializer,
|
||||
None => FromLetNoInitializer
|
||||
};
|
||||
self.add_variable(Local(LocalInfo {
|
||||
this.add_variable(Local(LocalInfo {
|
||||
id: p_id,
|
||||
ident: name,
|
||||
is_mutbl: local.node.is_mutbl,
|
||||
kind: kind
|
||||
}));
|
||||
}
|
||||
visit::visit_local(local, self, vt);
|
||||
visit::visit_local(local, this, vt);
|
||||
}
|
||||
|
||||
fn visit_arm(arm: &arm, self: @mut IrMaps, vt: vt<@mut IrMaps>) {
|
||||
let def_map = self.tcx.def_map;
|
||||
fn visit_arm(arm: &arm, this: @mut IrMaps, vt: vt<@mut IrMaps>) {
|
||||
let def_map = this.tcx.def_map;
|
||||
for arm.pats.each |pat| {
|
||||
do pat_util::pat_bindings(def_map, *pat) |bm, p_id, sp, path| {
|
||||
debug!("adding local variable %d from match with bm %?",
|
||||
p_id, bm);
|
||||
let name = ast_util::path_to_ident(path);
|
||||
self.add_live_node_for_node(p_id, VarDefNode(sp));
|
||||
self.add_variable(Local(LocalInfo {
|
||||
this.add_live_node_for_node(p_id, VarDefNode(sp));
|
||||
this.add_variable(Local(LocalInfo {
|
||||
id: p_id,
|
||||
ident: name,
|
||||
is_mutbl: false,
|
||||
@ -459,35 +459,35 @@ fn visit_arm(arm: &arm, self: @mut IrMaps, vt: vt<@mut IrMaps>) {
|
||||
}));
|
||||
}
|
||||
}
|
||||
visit::visit_arm(arm, self, vt);
|
||||
visit::visit_arm(arm, this, vt);
|
||||
}
|
||||
|
||||
fn visit_expr(expr: @expr, self: @mut IrMaps, vt: vt<@mut IrMaps>) {
|
||||
fn visit_expr(expr: @expr, this: @mut IrMaps, vt: vt<@mut IrMaps>) {
|
||||
match expr.node {
|
||||
// live nodes required for uses or definitions of variables:
|
||||
expr_path(_) => {
|
||||
let def = self.tcx.def_map.get_copy(&expr.id);
|
||||
expr_path(_) | expr_self => {
|
||||
let def = this.tcx.def_map.get_copy(&expr.id);
|
||||
debug!("expr %d: path that leads to %?", expr.id, def);
|
||||
if moves::moved_variable_node_id_from_def(def).is_some() {
|
||||
self.add_live_node_for_node(expr.id, ExprNode(expr.span));
|
||||
this.add_live_node_for_node(expr.id, ExprNode(expr.span));
|
||||
}
|
||||
visit::visit_expr(expr, self, vt);
|
||||
visit::visit_expr(expr, this, vt);
|
||||
}
|
||||
expr_fn_block(*) => {
|
||||
// Interesting control flow (for loops can contain labeled
|
||||
// breaks or continues)
|
||||
self.add_live_node_for_node(expr.id, ExprNode(expr.span));
|
||||
this.add_live_node_for_node(expr.id, ExprNode(expr.span));
|
||||
|
||||
// Make a live_node for each captured variable, with the span
|
||||
// being the location that the variable is used. This results
|
||||
// in better error messages than just pointing at the closure
|
||||
// construction site.
|
||||
let cvs = self.capture_map.get(&expr.id);
|
||||
let cvs = this.capture_map.get(&expr.id);
|
||||
let mut call_caps = ~[];
|
||||
for cvs.each |cv| {
|
||||
match moves::moved_variable_node_id_from_def(cv.def) {
|
||||
Some(rv) => {
|
||||
let cv_ln = self.add_live_node(FreeVarNode(cv.span));
|
||||
let cv_ln = this.add_live_node(FreeVarNode(cv.span));
|
||||
let is_move = match cv.mode {
|
||||
// var must be dead afterwards
|
||||
moves::CapMove => true,
|
||||
@ -502,19 +502,19 @@ fn visit_expr(expr: @expr, self: @mut IrMaps, vt: vt<@mut IrMaps>) {
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
self.set_captures(expr.id, call_caps);
|
||||
this.set_captures(expr.id, call_caps);
|
||||
|
||||
visit::visit_expr(expr, self, vt);
|
||||
visit::visit_expr(expr, this, vt);
|
||||
}
|
||||
|
||||
// live nodes required for interesting control flow:
|
||||
expr_if(*) | expr_match(*) | expr_while(*) | expr_loop(*) => {
|
||||
self.add_live_node_for_node(expr.id, ExprNode(expr.span));
|
||||
visit::visit_expr(expr, self, vt);
|
||||
this.add_live_node_for_node(expr.id, ExprNode(expr.span));
|
||||
visit::visit_expr(expr, this, vt);
|
||||
}
|
||||
expr_binary(op, _, _) if ast_util::lazy_binop(op) => {
|
||||
self.add_live_node_for_node(expr.id, ExprNode(expr.span));
|
||||
visit::visit_expr(expr, self, vt);
|
||||
this.add_live_node_for_node(expr.id, ExprNode(expr.span));
|
||||
visit::visit_expr(expr, this, vt);
|
||||
}
|
||||
|
||||
// otherwise, live nodes are not required:
|
||||
@ -526,7 +526,7 @@ fn visit_expr(expr: @expr, self: @mut IrMaps, vt: vt<@mut IrMaps>) {
|
||||
expr_assign(*) | expr_assign_op(*) | expr_mac(*) |
|
||||
expr_struct(*) | expr_repeat(*) | expr_paren(*) |
|
||||
expr_inline_asm(*) => {
|
||||
visit::visit_expr(expr, self, vt);
|
||||
visit::visit_expr(expr, this, vt);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1006,7 +1006,7 @@ pub impl Liveness {
|
||||
match expr.node {
|
||||
// Interesting cases with control flow or which gen/kill
|
||||
|
||||
expr_path(_) => {
|
||||
expr_path(_) | expr_self => {
|
||||
self.access_path(expr, succ, ACC_READ | ACC_USE)
|
||||
}
|
||||
|
||||
@ -1409,13 +1409,13 @@ pub impl Liveness {
|
||||
// _______________________________________________________________________
|
||||
// Checking for error conditions
|
||||
|
||||
fn check_local(local: @local, self: @Liveness, vt: vt<@Liveness>) {
|
||||
fn check_local(local: @local, this: @Liveness, vt: vt<@Liveness>) {
|
||||
match local.node.init {
|
||||
Some(_) => {
|
||||
|
||||
// Initializer:
|
||||
self.warn_about_unused_or_dead_vars_in_pat(local.node.pat);
|
||||
self.check_for_reassignments_in_pat(local.node.pat,
|
||||
this.warn_about_unused_or_dead_vars_in_pat(local.node.pat);
|
||||
this.check_for_reassignments_in_pat(local.node.pat,
|
||||
local.node.is_mutbl);
|
||||
}
|
||||
None => {
|
||||
@ -1424,12 +1424,12 @@ fn check_local(local: @local, self: @Liveness, vt: vt<@Liveness>) {
|
||||
// should not be live at this point.
|
||||
|
||||
debug!("check_local() with no initializer");
|
||||
do self.pat_bindings(local.node.pat) |ln, var, sp, id| {
|
||||
if !self.warn_about_unused(sp, id, ln, var) {
|
||||
match self.live_on_exit(ln, var) {
|
||||
do this.pat_bindings(local.node.pat) |ln, var, sp, id| {
|
||||
if !this.warn_about_unused(sp, id, ln, var) {
|
||||
match this.live_on_exit(ln, var) {
|
||||
None => { /* not live: good */ }
|
||||
Some(lnk) => {
|
||||
self.report_illegal_read(
|
||||
this.report_illegal_read(
|
||||
local.span, lnk, var,
|
||||
PossiblyUninitializedVariable);
|
||||
}
|
||||
@ -1439,77 +1439,77 @@ fn check_local(local: @local, self: @Liveness, vt: vt<@Liveness>) {
|
||||
}
|
||||
}
|
||||
|
||||
visit::visit_local(local, self, vt);
|
||||
visit::visit_local(local, this, vt);
|
||||
}
|
||||
|
||||
fn check_arm(arm: &arm, self: @Liveness, vt: vt<@Liveness>) {
|
||||
do self.arm_pats_bindings(arm.pats) |ln, var, sp, id| {
|
||||
self.warn_about_unused(sp, id, ln, var);
|
||||
fn check_arm(arm: &arm, this: @Liveness, vt: vt<@Liveness>) {
|
||||
do this.arm_pats_bindings(arm.pats) |ln, var, sp, id| {
|
||||
this.warn_about_unused(sp, id, ln, var);
|
||||
}
|
||||
visit::visit_arm(arm, self, vt);
|
||||
visit::visit_arm(arm, this, vt);
|
||||
}
|
||||
|
||||
fn check_expr(expr: @expr, self: @Liveness, vt: vt<@Liveness>) {
|
||||
fn check_expr(expr: @expr, this: @Liveness, vt: vt<@Liveness>) {
|
||||
match expr.node {
|
||||
expr_path(_) => {
|
||||
for self.variable_from_def_map(expr.id, expr.span).each |var| {
|
||||
let ln = self.live_node(expr.id, expr.span);
|
||||
expr_path(_) | expr_self => {
|
||||
for this.variable_from_def_map(expr.id, expr.span).each |var| {
|
||||
let ln = this.live_node(expr.id, expr.span);
|
||||
|
||||
match self.ir.variable_moves_map.find(&expr.id) {
|
||||
match this.ir.variable_moves_map.find(&expr.id) {
|
||||
None => {}
|
||||
Some(&entire_expr) => {
|
||||
debug!("(checking expr) is a move: `%s`",
|
||||
expr_to_str(expr, self.tcx.sess.intr()));
|
||||
self.check_move_from_var(ln, *var, entire_expr);
|
||||
expr_to_str(expr, this.tcx.sess.intr()));
|
||||
this.check_move_from_var(ln, *var, entire_expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
visit::visit_expr(expr, self, vt);
|
||||
visit::visit_expr(expr, this, vt);
|
||||
}
|
||||
|
||||
expr_fn_block(*) => {
|
||||
let caps = self.ir.captures(expr);
|
||||
let caps = this.ir.captures(expr);
|
||||
for caps.each |cap| {
|
||||
let var = self.variable(cap.var_nid, expr.span);
|
||||
let var = this.variable(cap.var_nid, expr.span);
|
||||
if cap.is_move {
|
||||
self.check_move_from_var(cap.ln, var, expr);
|
||||
this.check_move_from_var(cap.ln, var, expr);
|
||||
}
|
||||
}
|
||||
|
||||
visit::visit_expr(expr, self, vt);
|
||||
visit::visit_expr(expr, this, vt);
|
||||
}
|
||||
|
||||
expr_assign(l, r) => {
|
||||
self.check_lvalue(l, vt);
|
||||
(vt.visit_expr)(r, self, vt);
|
||||
this.check_lvalue(l, vt);
|
||||
(vt.visit_expr)(r, this, vt);
|
||||
|
||||
visit::visit_expr(expr, self, vt);
|
||||
visit::visit_expr(expr, this, vt);
|
||||
}
|
||||
|
||||
expr_assign_op(_, l, _) => {
|
||||
self.check_lvalue(l, vt);
|
||||
this.check_lvalue(l, vt);
|
||||
|
||||
visit::visit_expr(expr, self, vt);
|
||||
visit::visit_expr(expr, this, vt);
|
||||
}
|
||||
|
||||
expr_inline_asm(ref ia) => {
|
||||
for ia.inputs.each |&(_, in)| {
|
||||
(vt.visit_expr)(in, self, vt);
|
||||
(vt.visit_expr)(in, this, vt);
|
||||
}
|
||||
|
||||
// Output operands must be lvalues
|
||||
for ia.outputs.each |&(_, out)| {
|
||||
match out.node {
|
||||
expr_addr_of(_, inner) => {
|
||||
self.check_lvalue(inner, vt);
|
||||
this.check_lvalue(inner, vt);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
(vt.visit_expr)(out, self, vt);
|
||||
(vt.visit_expr)(out, this, vt);
|
||||
}
|
||||
|
||||
visit::visit_expr(expr, self, vt);
|
||||
visit::visit_expr(expr, this, vt);
|
||||
}
|
||||
|
||||
// no correctness conditions related to liveness
|
||||
@ -1521,7 +1521,7 @@ fn check_expr(expr: @expr, self: @Liveness, vt: vt<@Liveness>) {
|
||||
expr_again(*) | expr_lit(_) | expr_block(*) |
|
||||
expr_mac(*) | expr_addr_of(*) | expr_struct(*) | expr_repeat(*) |
|
||||
expr_paren(*) => {
|
||||
visit::visit_expr(expr, self, vt);
|
||||
visit::visit_expr(expr, this, vt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -406,7 +406,7 @@ pub impl mem_categorization_ctxt {
|
||||
self.cat_index(expr, base_cmt, 0)
|
||||
}
|
||||
|
||||
ast::expr_path(_) => {
|
||||
ast::expr_path(_) | ast::expr_self => {
|
||||
let def = self.tcx.def_map.get_copy(&expr.id);
|
||||
self.cat_def(expr.id, expr.span, expr_ty, def)
|
||||
}
|
||||
|
@ -435,7 +435,7 @@ pub impl VisitContext {
|
||||
debug!("comp_mode = %?", comp_mode);
|
||||
|
||||
match expr.node {
|
||||
expr_path(*) => {
|
||||
expr_path(*) | expr_self => {
|
||||
match comp_mode {
|
||||
MoveInPart(entire_expr) => {
|
||||
self.move_maps.variable_moves_map.insert(
|
||||
|
@ -310,14 +310,14 @@ pub impl RegionMaps {
|
||||
}
|
||||
}
|
||||
|
||||
fn ancestors_of(self: &RegionMaps, scope: ast::node_id)
|
||||
fn ancestors_of(this: &RegionMaps, scope: ast::node_id)
|
||||
-> ~[ast::node_id]
|
||||
{
|
||||
// debug!("ancestors_of(scope=%d)", scope);
|
||||
let mut result = ~[scope];
|
||||
let mut scope = scope;
|
||||
loop {
|
||||
match self.scope_map.find(&scope) {
|
||||
match this.scope_map.find(&scope) {
|
||||
None => return result,
|
||||
Some(&superscope) => {
|
||||
result.push(superscope);
|
||||
@ -685,7 +685,7 @@ pub impl DetermineRpCtxt {
|
||||
None => {
|
||||
self.anon_implies_rp
|
||||
}
|
||||
Some(ref l) if l.ident == special_idents::static => {
|
||||
Some(ref l) if l.ident == special_idents::statik => {
|
||||
false
|
||||
}
|
||||
Some(ref l) if l.ident == special_idents::self_ => {
|
||||
|
@ -35,7 +35,7 @@ use syntax::ast::{def_prim_ty, def_region, def_self, def_ty, def_ty_param};
|
||||
use syntax::ast::{def_upvar, def_use, def_variant, div, eq};
|
||||
use syntax::ast::{expr, expr_again, expr_assign_op};
|
||||
use syntax::ast::{expr_index, expr_loop};
|
||||
use syntax::ast::{expr_path, expr_struct, expr_unary, fn_decl};
|
||||
use syntax::ast::{expr_path, expr_self, expr_struct, expr_unary, fn_decl};
|
||||
use syntax::ast::{foreign_item, foreign_item_const, foreign_item_fn, ge};
|
||||
use syntax::ast::Generics;
|
||||
use syntax::ast::{gt, ident, inherited, item, item_struct};
|
||||
@ -326,12 +326,14 @@ pub fn namespace_for_duplicate_checking_mode(mode: DuplicateCheckingMode)
|
||||
/// One local scope.
|
||||
pub struct Rib {
|
||||
bindings: @mut HashMap<ident,def_like>,
|
||||
self_binding: @mut Option<def_like>,
|
||||
kind: RibKind,
|
||||
}
|
||||
|
||||
pub fn Rib(kind: RibKind) -> Rib {
|
||||
Rib {
|
||||
bindings: @mut HashMap::new(),
|
||||
self_binding: @mut None,
|
||||
kind: kind
|
||||
}
|
||||
}
|
||||
@ -762,7 +764,7 @@ pub fn Resolver(session: Session,
|
||||
|
||||
let current_module = graph_root.get_module();
|
||||
|
||||
let self = Resolver {
|
||||
let this = Resolver {
|
||||
session: @session,
|
||||
lang_items: copy lang_items,
|
||||
crate: crate,
|
||||
@ -800,7 +802,7 @@ pub fn Resolver(session: Session,
|
||||
intr: session.intr()
|
||||
};
|
||||
|
||||
self
|
||||
this
|
||||
}
|
||||
|
||||
/// The main resolver class.
|
||||
@ -3655,8 +3657,7 @@ pub impl Resolver {
|
||||
HasSelfBinding(self_node_id, is_implicit) => {
|
||||
let def_like = dl_def(def_self(self_node_id,
|
||||
is_implicit));
|
||||
(*function_value_rib).bindings.insert(self.self_ident,
|
||||
def_like);
|
||||
*function_value_rib.self_binding = Some(def_like);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4562,7 +4563,7 @@ pub impl Resolver {
|
||||
ident: ident,
|
||||
namespace: Namespace,
|
||||
span: span)
|
||||
-> Option<def> {
|
||||
-> Option<def> {
|
||||
// Check the local set of ribs.
|
||||
let search_result;
|
||||
match namespace {
|
||||
@ -4591,6 +4592,35 @@ pub impl Resolver {
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_self_value_in_local_ribs(@mut self, span: span)
|
||||
-> Option<def> {
|
||||
// FIXME #4950: This should not use a while loop.
|
||||
let ribs = &mut self.value_ribs;
|
||||
let mut i = ribs.len();
|
||||
while i != 0 {
|
||||
i -= 1;
|
||||
match *ribs[i].self_binding {
|
||||
Some(def_like) => {
|
||||
match self.upvarify(*ribs,
|
||||
i,
|
||||
def_like,
|
||||
span,
|
||||
DontAllowCapturingSelf) {
|
||||
Some(dl_def(def)) => return Some(def),
|
||||
_ => {
|
||||
self.session.span_bug(span,
|
||||
~"self wasn't mapped to a \
|
||||
def?!")
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn resolve_item_by_identifier_in_lexical_scope(@mut self,
|
||||
ident: ident,
|
||||
namespace: Namespace)
|
||||
@ -4805,12 +4835,25 @@ pub impl Resolver {
|
||||
`%s`",
|
||||
*self.session.str_of(
|
||||
label))),
|
||||
Some(dl_def(def @ def_label(_))) =>
|
||||
self.record_def(expr.id, def),
|
||||
Some(_) =>
|
||||
Some(dl_def(def @ def_label(_))) => {
|
||||
self.record_def(expr.id, def)
|
||||
}
|
||||
Some(_) => {
|
||||
self.session.span_bug(expr.span,
|
||||
~"label wasn't mapped to a \
|
||||
label def!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expr_self => {
|
||||
match self.resolve_self_value_in_local_ribs(expr.span) {
|
||||
None => {
|
||||
self.session.span_err(expr.span,
|
||||
~"`self` is not allowed in \
|
||||
this context")
|
||||
}
|
||||
Some(def) => self.record_def(expr.id, def),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ use syntax::ast::{def_prim_ty, def_region, def_self, def_ty, def_ty_param};
|
||||
use syntax::ast::{def_upvar, def_use, def_variant, div, eq};
|
||||
use syntax::ast::{expr, expr_again, expr_assign_op};
|
||||
use syntax::ast::{expr_index, expr_loop};
|
||||
use syntax::ast::{expr_path, expr_struct, expr_unary, fn_decl};
|
||||
use syntax::ast::{expr_path, expr_self, expr_struct, expr_unary, fn_decl};
|
||||
use syntax::ast::{foreign_item, foreign_item_const, foreign_item_fn, ge};
|
||||
use syntax::ast::Generics;
|
||||
use syntax::ast::{gt, ident, inherited, item, item_struct};
|
||||
@ -327,12 +327,14 @@ pub fn namespace_for_duplicate_checking_mode(mode: DuplicateCheckingMode)
|
||||
/// One local scope.
|
||||
pub struct Rib {
|
||||
bindings: @mut HashMap<ident,def_like>,
|
||||
self_binding: @mut Option<def_like>,
|
||||
kind: RibKind,
|
||||
}
|
||||
|
||||
pub fn Rib(kind: RibKind) -> Rib {
|
||||
Rib {
|
||||
bindings: @mut HashMap::new(),
|
||||
self_binding: @mut None,
|
||||
kind: kind
|
||||
}
|
||||
}
|
||||
@ -763,7 +765,7 @@ pub fn Resolver(session: Session,
|
||||
|
||||
let current_module = graph_root.get_module();
|
||||
|
||||
let self = Resolver {
|
||||
let this = Resolver {
|
||||
session: @session,
|
||||
lang_items: copy lang_items,
|
||||
crate: crate,
|
||||
@ -806,7 +808,7 @@ pub fn Resolver(session: Session,
|
||||
intr: session.intr()
|
||||
};
|
||||
|
||||
self
|
||||
this
|
||||
}
|
||||
|
||||
/// The main resolver class.
|
||||
@ -3695,8 +3697,7 @@ pub impl Resolver {
|
||||
HasSelfBinding(self_node_id, is_implicit) => {
|
||||
let def_like = dl_def(def_self(self_node_id,
|
||||
is_implicit));
|
||||
(*function_value_rib).bindings.insert(self.self_ident,
|
||||
def_like);
|
||||
*function_value_rib.self_binding = Some(def_like);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4603,7 +4604,7 @@ pub impl Resolver {
|
||||
ident: ident,
|
||||
namespace: Namespace,
|
||||
span: span)
|
||||
-> Option<def> {
|
||||
-> Option<def> {
|
||||
// Check the local set of ribs.
|
||||
let search_result;
|
||||
match namespace {
|
||||
@ -4632,6 +4633,35 @@ pub impl Resolver {
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_self_value_in_local_ribs(@mut self, span: span)
|
||||
-> Option<def> {
|
||||
// FIXME #4950: This should not use a while loop.
|
||||
let ribs = &mut self.value_ribs;
|
||||
let mut i = ribs.len();
|
||||
while i != 0 {
|
||||
i -= 1;
|
||||
match *ribs[i].self_binding {
|
||||
Some(def_like) => {
|
||||
match self.upvarify(ribs,
|
||||
i,
|
||||
def_like,
|
||||
span,
|
||||
DontAllowCapturingSelf) {
|
||||
Some(dl_def(def)) => return Some(def),
|
||||
_ => {
|
||||
self.session.span_bug(span,
|
||||
~"self wasn't mapped to a \
|
||||
def?!")
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn resolve_item_by_identifier_in_lexical_scope(@mut self,
|
||||
ident: ident,
|
||||
namespace: Namespace)
|
||||
@ -4845,12 +4875,25 @@ pub impl Resolver {
|
||||
`%s`",
|
||||
*self.session.str_of(
|
||||
label))),
|
||||
Some(dl_def(def @ def_label(_))) =>
|
||||
self.record_def(expr.id, def),
|
||||
Some(_) =>
|
||||
Some(dl_def(def @ def_label(_))) => {
|
||||
self.record_def(expr.id, def)
|
||||
}
|
||||
Some(_) => {
|
||||
self.session.span_bug(expr.span,
|
||||
~"label wasn't mapped to a \
|
||||
label def!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expr_self => {
|
||||
match self.resolve_self_value_in_local_ribs(expr.span) {
|
||||
None => {
|
||||
self.session.span_err(expr.span,
|
||||
~"`self` is not allowed in \
|
||||
this context")
|
||||
}
|
||||
Some(def) => self.record_def(expr.id, def),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -426,10 +426,10 @@ pub fn enter_match<'r>(bcx: block,
|
||||
vec::append(sub, vec::slice(br.pats, 0u, col)),
|
||||
vec::slice(br.pats, col + 1u, br.pats.len()));
|
||||
|
||||
let self = br.pats[col];
|
||||
match self.node {
|
||||
let this = br.pats[col];
|
||||
match this.node {
|
||||
ast::pat_ident(_, path, None) => {
|
||||
if pat_is_binding(dm, self) {
|
||||
if pat_is_binding(dm, this) {
|
||||
let binding_info =
|
||||
br.data.bindings_map.get(
|
||||
&path_to_ident(path));
|
||||
|
@ -256,13 +256,11 @@ pub impl param_substs {
|
||||
}
|
||||
}
|
||||
|
||||
fn param_substs_to_str(self: ¶m_substs,
|
||||
tcx: ty::ctxt) -> ~str
|
||||
{
|
||||
fn param_substs_to_str(this: ¶m_substs, tcx: ty::ctxt) -> ~str {
|
||||
fmt!("param_substs {tys:%s, vtables:%s, type_param_defs:%s}",
|
||||
self.tys.repr(tcx),
|
||||
self.vtables.repr(tcx),
|
||||
self.type_param_defs.repr(tcx))
|
||||
this.tys.repr(tcx),
|
||||
this.vtables.repr(tcx),
|
||||
this.type_param_defs.repr(tcx))
|
||||
}
|
||||
|
||||
impl Repr for param_substs {
|
||||
|
@ -451,7 +451,7 @@ fn trans_rvalue_datum_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
|
||||
trace_span!(bcx, expr.span, @shorten(bcx.expr_to_str(expr)));
|
||||
|
||||
match expr.node {
|
||||
ast::expr_path(_) => {
|
||||
ast::expr_path(_) | ast::expr_self => {
|
||||
return trans_def_datum_unadjusted(bcx, expr, bcx.def(expr.id));
|
||||
}
|
||||
ast::expr_vstore(contents, ast::expr_vstore_box) |
|
||||
@ -558,7 +558,7 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
|
||||
ast::expr_paren(e) => {
|
||||
return trans_rvalue_dps_unadjusted(bcx, e, dest);
|
||||
}
|
||||
ast::expr_path(_) => {
|
||||
ast::expr_path(_) | ast::expr_self => {
|
||||
return trans_def_dps_unadjusted(bcx, expr,
|
||||
bcx.def(expr.id), dest);
|
||||
}
|
||||
@ -810,7 +810,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
|
||||
ast::expr_paren(e) => {
|
||||
trans_lvalue_unadjusted(bcx, e)
|
||||
}
|
||||
ast::expr_path(_) => {
|
||||
ast::expr_path(_) | ast::expr_self => {
|
||||
trans_def_lvalue(bcx, expr, bcx.def(expr.id))
|
||||
}
|
||||
ast::expr_field(base, ident, _) => {
|
||||
|
@ -174,14 +174,15 @@ pub fn trans_self_arg(bcx: block,
|
||||
|
||||
pub fn trans_method_callee(bcx: block,
|
||||
callee_id: ast::node_id,
|
||||
self: @ast::expr,
|
||||
this: @ast::expr,
|
||||
mentry: typeck::method_map_entry)
|
||||
-> Callee {
|
||||
-> Callee {
|
||||
let _icx = bcx.insn_ctxt("impl::trans_method_callee");
|
||||
let tcx = bcx.tcx();
|
||||
|
||||
debug!("trans_method_callee(callee_id=%?, self=%s, mentry=%s)",
|
||||
callee_id, bcx.expr_to_str(self),
|
||||
debug!("trans_method_callee(callee_id=%?, this=%s, mentry=%s)",
|
||||
callee_id,
|
||||
bcx.expr_to_str(this),
|
||||
mentry.repr(bcx.tcx()));
|
||||
|
||||
// Replace method_self with method_static here.
|
||||
@ -202,7 +203,7 @@ pub fn trans_method_callee(bcx: block,
|
||||
}
|
||||
typeck::method_super(trait_id, method_index) => {
|
||||
// <self_ty> is the self type for this method call
|
||||
let self_ty = node_id_type(bcx, self.id);
|
||||
let self_ty = node_id_type(bcx, this.id);
|
||||
// <impl_id> is the ID of the implementation of
|
||||
// trait <trait_id> for type <self_ty>
|
||||
let impl_id = ty::get_impl_id(tcx, trait_id, self_ty);
|
||||
@ -232,13 +233,13 @@ pub fn trans_method_callee(bcx: block,
|
||||
match origin {
|
||||
typeck::method_static(did) => {
|
||||
let callee_fn = callee::trans_fn_ref(bcx, did, callee_id);
|
||||
let Result {bcx, val} = trans_self_arg(bcx, self, mentry);
|
||||
let Result {bcx, val} = trans_self_arg(bcx, this, mentry);
|
||||
Callee {
|
||||
bcx: bcx,
|
||||
data: Method(MethodData {
|
||||
llfn: callee_fn.llfn,
|
||||
llself: val,
|
||||
self_ty: node_id_type(bcx, self.id),
|
||||
self_ty: node_id_type(bcx, this.id),
|
||||
self_mode: mentry.self_mode,
|
||||
})
|
||||
}
|
||||
@ -252,7 +253,7 @@ pub fn trans_method_callee(bcx: block,
|
||||
match bcx.fcx.param_substs {
|
||||
Some(substs) => {
|
||||
let vtbl = find_vtable(bcx.tcx(), substs, p, b);
|
||||
trans_monomorphized_callee(bcx, callee_id, self, mentry,
|
||||
trans_monomorphized_callee(bcx, callee_id, this, mentry,
|
||||
trait_id, off, vtbl)
|
||||
}
|
||||
// how to get rid of this?
|
||||
@ -263,7 +264,7 @@ pub fn trans_method_callee(bcx: block,
|
||||
trans_trait_callee(bcx,
|
||||
callee_id,
|
||||
off,
|
||||
self,
|
||||
this,
|
||||
store,
|
||||
mentry.explicit_self)
|
||||
}
|
||||
|
@ -293,7 +293,7 @@ pub fn mark_for_expr(cx: Context, e: @expr) {
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
expr_path(_) => {
|
||||
expr_path(_) | expr_self => {
|
||||
let opt_ts = cx.ccx.tcx.node_type_substs.find_copy(&e.id);
|
||||
for opt_ts.each |ts| {
|
||||
let id = ast_util::def_id_of_def(cx.ccx.tcx.def_map.get_copy(&e.id));
|
||||
|
@ -3383,7 +3383,7 @@ pub fn expr_kind(tcx: ctxt,
|
||||
}
|
||||
|
||||
match expr.node {
|
||||
ast::expr_path(*) => {
|
||||
ast::expr_path(*) | ast::expr_self => {
|
||||
match resolve_expr(tcx, expr) {
|
||||
ast::def_variant(*) | ast::def_struct(*) => RvalueDpsExpr,
|
||||
|
||||
|
@ -102,7 +102,7 @@ pub fn get_region_reporting_err(
|
||||
}
|
||||
|
||||
pub fn ast_region_to_region<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
self: &AC,
|
||||
this: &AC,
|
||||
rscope: &RS,
|
||||
default_span: span,
|
||||
opt_lifetime: Option<@ast::Lifetime>) -> ty::Region
|
||||
@ -111,7 +111,7 @@ pub fn ast_region_to_region<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
None => {
|
||||
(default_span, rscope.anon_region(default_span))
|
||||
}
|
||||
Some(ref lifetime) if lifetime.ident == special_idents::static => {
|
||||
Some(ref lifetime) if lifetime.ident == special_idents::statik => {
|
||||
(lifetime.span, Ok(ty::re_static))
|
||||
}
|
||||
Some(ref lifetime) if lifetime.ident == special_idents::self_ => {
|
||||
@ -123,11 +123,11 @@ pub fn ast_region_to_region<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
}
|
||||
};
|
||||
|
||||
get_region_reporting_err(self.tcx(), span, opt_lifetime, res)
|
||||
get_region_reporting_err(this.tcx(), span, opt_lifetime, res)
|
||||
}
|
||||
|
||||
fn ast_path_substs<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
self: &AC,
|
||||
this: &AC,
|
||||
rscope: &RS,
|
||||
def_id: ast::def_id,
|
||||
decl_generics: &ty::Generics,
|
||||
@ -141,9 +141,9 @@ fn ast_path_substs<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
* set of substitutions for this particular reference to `I`.
|
||||
*/
|
||||
|
||||
let tcx = self.tcx();
|
||||
let tcx = this.tcx();
|
||||
|
||||
// If the type is parameterized by the self region, then replace self
|
||||
// If the type is parameterized by the this region, then replace this
|
||||
// region with the current anon region binding (in other words,
|
||||
// whatever & would get replaced with).
|
||||
let self_r = match (&decl_generics.region_param, &path.rp) {
|
||||
@ -160,55 +160,55 @@ fn ast_path_substs<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
}
|
||||
(&Some(_), &None) => {
|
||||
let res = rscope.anon_region(path.span);
|
||||
let r = get_region_reporting_err(self.tcx(), path.span, None, res);
|
||||
let r = get_region_reporting_err(this.tcx(), path.span, None, res);
|
||||
Some(r)
|
||||
}
|
||||
(&Some(_), &Some(_)) => {
|
||||
Some(ast_region_to_region(self, rscope, path.span, path.rp))
|
||||
Some(ast_region_to_region(this, rscope, path.span, path.rp))
|
||||
}
|
||||
};
|
||||
|
||||
// Convert the type parameters supplied by the user.
|
||||
if !vec::same_length(*decl_generics.type_param_defs, path.types) {
|
||||
self.tcx().sess.span_fatal(
|
||||
this.tcx().sess.span_fatal(
|
||||
path.span,
|
||||
fmt!("wrong number of type arguments: expected %u but found %u",
|
||||
decl_generics.type_param_defs.len(), path.types.len()));
|
||||
}
|
||||
let tps = path.types.map(|a_t| ast_ty_to_ty(self, rscope, *a_t));
|
||||
let tps = path.types.map(|a_t| ast_ty_to_ty(this, rscope, *a_t));
|
||||
|
||||
substs {self_r:self_r, self_ty:self_ty, tps:tps}
|
||||
}
|
||||
|
||||
pub fn ast_path_to_substs_and_ty<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
self: &AC,
|
||||
this: &AC,
|
||||
rscope: &RS,
|
||||
did: ast::def_id,
|
||||
path: @ast::Path) -> ty_param_substs_and_ty
|
||||
{
|
||||
let tcx = self.tcx();
|
||||
let tcx = this.tcx();
|
||||
let ty::ty_param_bounds_and_ty {
|
||||
generics: generics,
|
||||
ty: decl_ty
|
||||
} = self.get_item_ty(did);
|
||||
} = this.get_item_ty(did);
|
||||
|
||||
let substs = ast_path_substs(self, rscope, did, &generics, None, path);
|
||||
let substs = ast_path_substs(this, rscope, did, &generics, None, path);
|
||||
let ty = ty::subst(tcx, &substs, decl_ty);
|
||||
ty_param_substs_and_ty { substs: substs, ty: ty }
|
||||
}
|
||||
|
||||
pub fn ast_path_to_trait_ref<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
self: &AC,
|
||||
this: &AC,
|
||||
rscope: &RS,
|
||||
trait_def_id: ast::def_id,
|
||||
self_ty: Option<ty::t>,
|
||||
path: @ast::Path) -> @ty::TraitRef
|
||||
{
|
||||
let trait_def =
|
||||
self.get_trait_def(trait_def_id);
|
||||
this.get_trait_def(trait_def_id);
|
||||
let substs =
|
||||
ast_path_substs(
|
||||
self,
|
||||
this,
|
||||
rscope,
|
||||
trait_def.trait_ref.def_id,
|
||||
&trait_def.generics,
|
||||
@ -222,7 +222,7 @@ pub fn ast_path_to_trait_ref<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
|
||||
|
||||
pub fn ast_path_to_ty<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
self: &AC,
|
||||
this: &AC,
|
||||
rscope: &RS,
|
||||
did: ast::def_id,
|
||||
path: @ast::Path)
|
||||
@ -233,7 +233,7 @@ pub fn ast_path_to_ty<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
let ty::ty_param_substs_and_ty {
|
||||
substs: substs,
|
||||
ty: ty
|
||||
} = ast_path_to_substs_and_ty(self, rscope, did, path);
|
||||
} = ast_path_to_substs_and_ty(this, rscope, did, path);
|
||||
ty_param_substs_and_ty { substs: substs, ty: ty }
|
||||
}
|
||||
|
||||
@ -244,29 +244,29 @@ pub static NO_TPS: uint = 2;
|
||||
// internal notion of a type. `getter` is a function that returns the type
|
||||
// corresponding to a definition ID:
|
||||
pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
|
||||
self: &AC, rscope: &RS, ast_ty: @ast::Ty) -> ty::t {
|
||||
this: &AC, rscope: &RS, ast_ty: @ast::Ty) -> ty::t {
|
||||
|
||||
fn ast_mt_to_mt<AC:AstConv, RS:region_scope + Copy + 'static>(
|
||||
self: &AC, rscope: &RS, mt: &ast::mt) -> ty::mt {
|
||||
this: &AC, rscope: &RS, mt: &ast::mt) -> ty::mt {
|
||||
|
||||
ty::mt {ty: ast_ty_to_ty(self, rscope, mt.ty), mutbl: mt.mutbl}
|
||||
ty::mt {ty: ast_ty_to_ty(this, rscope, mt.ty), mutbl: mt.mutbl}
|
||||
}
|
||||
|
||||
// Handle @, ~, and & being able to mean estrs and evecs.
|
||||
// If a_seq_ty is a str or a vec, make it an estr/evec.
|
||||
// Also handle first-class trait types.
|
||||
fn mk_pointer<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
self: &AC,
|
||||
this: &AC,
|
||||
rscope: &RS,
|
||||
a_seq_ty: &ast::mt,
|
||||
vst: ty::vstore,
|
||||
constr: &fn(ty::mt) -> ty::t) -> ty::t
|
||||
{
|
||||
let tcx = self.tcx();
|
||||
let tcx = this.tcx();
|
||||
|
||||
match a_seq_ty.ty.node {
|
||||
ast::ty_vec(ref mt) => {
|
||||
let mut mt = ast_mt_to_mt(self, rscope, 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 {
|
||||
mt = ty::mt { ty: mt.ty, mutbl: a_seq_ty.mutbl };
|
||||
@ -281,7 +281,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
|
||||
}
|
||||
Some(&ast::def_trait(trait_def_id)) => {
|
||||
let result = ast_path_to_trait_ref(
|
||||
self, rscope, trait_def_id, None, path);
|
||||
this, rscope, trait_def_id, None, path);
|
||||
let trait_store = match vst {
|
||||
ty::vstore_box => ty::BoxTraitStore,
|
||||
ty::vstore_uniq => ty::UniqTraitStore,
|
||||
@ -308,7 +308,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let seq_ty = ast_mt_to_mt(self, rscope, a_seq_ty);
|
||||
let seq_ty = ast_mt_to_mt(this, rscope, a_seq_ty);
|
||||
return constr(seq_ty);
|
||||
}
|
||||
|
||||
@ -332,7 +332,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
|
||||
}
|
||||
}
|
||||
|
||||
let tcx = self.tcx();
|
||||
let tcx = this.tcx();
|
||||
|
||||
match tcx.ast_ty_to_ty_cache.find(&ast_ty.id) {
|
||||
Some(&ty::atttce_resolved(ty)) => return ty,
|
||||
@ -348,36 +348,36 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
|
||||
ast::ty_nil => ty::mk_nil(),
|
||||
ast::ty_bot => ty::mk_bot(),
|
||||
ast::ty_box(ref mt) => {
|
||||
mk_pointer(self, rscope, mt, ty::vstore_box,
|
||||
mk_pointer(this, rscope, mt, ty::vstore_box,
|
||||
|tmt| ty::mk_box(tcx, tmt))
|
||||
}
|
||||
ast::ty_uniq(ref mt) => {
|
||||
mk_pointer(self, rscope, mt, ty::vstore_uniq,
|
||||
mk_pointer(this, rscope, mt, ty::vstore_uniq,
|
||||
|tmt| ty::mk_uniq(tcx, tmt))
|
||||
}
|
||||
ast::ty_vec(ref mt) => {
|
||||
tcx.sess.span_err(ast_ty.span, "bare `[]` is not a type");
|
||||
// return /something/ so they can at least get more errors
|
||||
ty::mk_evec(tcx, ast_mt_to_mt(self, rscope, mt), ty::vstore_uniq)
|
||||
ty::mk_evec(tcx, ast_mt_to_mt(this, rscope, mt), ty::vstore_uniq)
|
||||
}
|
||||
ast::ty_ptr(ref mt) => {
|
||||
ty::mk_ptr(tcx, ast_mt_to_mt(self, rscope, mt))
|
||||
ty::mk_ptr(tcx, ast_mt_to_mt(this, rscope, mt))
|
||||
}
|
||||
ast::ty_rptr(region, ref mt) => {
|
||||
let r = ast_region_to_region(self, rscope, ast_ty.span, region);
|
||||
mk_pointer(self, rscope, mt, ty::vstore_slice(r),
|
||||
let r = ast_region_to_region(this, rscope, ast_ty.span, region);
|
||||
mk_pointer(this, rscope, mt, ty::vstore_slice(r),
|
||||
|tmt| ty::mk_rptr(tcx, r, tmt))
|
||||
}
|
||||
ast::ty_tup(ref fields) => {
|
||||
let flds = fields.map(|t| ast_ty_to_ty(self, rscope, *t));
|
||||
let flds = fields.map(|t| ast_ty_to_ty(this, rscope, *t));
|
||||
ty::mk_tup(tcx, flds)
|
||||
}
|
||||
ast::ty_bare_fn(ref bf) => {
|
||||
ty::mk_bare_fn(tcx, ty_of_bare_fn(self, rscope, bf.purity,
|
||||
ty::mk_bare_fn(tcx, ty_of_bare_fn(this, rscope, bf.purity,
|
||||
bf.abis, &bf.lifetimes, &bf.decl))
|
||||
}
|
||||
ast::ty_closure(ref f) => {
|
||||
let fn_decl = ty_of_closure(self,
|
||||
let fn_decl = ty_of_closure(this,
|
||||
rscope,
|
||||
f.sigil,
|
||||
f.purity,
|
||||
@ -407,7 +407,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
|
||||
ty::mk_err()
|
||||
}
|
||||
ast::def_ty(did) | ast::def_struct(did) => {
|
||||
ast_path_to_ty(self, rscope, did, path).ty
|
||||
ast_path_to_ty(this, rscope, did, path).ty
|
||||
}
|
||||
ast::def_prim_ty(nty) => {
|
||||
match nty {
|
||||
@ -440,7 +440,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
|
||||
ty::mk_param(tcx, n, id)
|
||||
}
|
||||
ast::def_self_ty(id) => {
|
||||
// n.b.: resolve guarantees that the self type only appears in a
|
||||
// n.b.: resolve guarantees that the this type only appears in a
|
||||
// trait, which we rely upon in various places when creating
|
||||
// substs
|
||||
check_path_args(tcx, path, NO_TPS | NO_REGIONS);
|
||||
@ -458,10 +458,10 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
|
||||
Ok(ref r) => {
|
||||
match *r {
|
||||
const_eval::const_int(i) =>
|
||||
ty::mk_evec(tcx, ast_mt_to_mt(self, rscope, a_mt),
|
||||
ty::mk_evec(tcx, ast_mt_to_mt(this, rscope, a_mt),
|
||||
ty::vstore_fixed(i as uint)),
|
||||
const_eval::const_uint(i) =>
|
||||
ty::mk_evec(tcx, ast_mt_to_mt(self, rscope, a_mt),
|
||||
ty::mk_evec(tcx, ast_mt_to_mt(this, rscope, a_mt),
|
||||
ty::vstore_fixed(i as uint)),
|
||||
_ => {
|
||||
tcx.sess.span_fatal(
|
||||
@ -482,7 +482,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
|
||||
// values in a fn_expr, or as the type of local variables. Both of
|
||||
// these cases are handled specially and should not descend into this
|
||||
// routine.
|
||||
self.tcx().sess.span_bug(
|
||||
this.tcx().sess.span_bug(
|
||||
ast_ty.span,
|
||||
"found `ty_infer` in unexpected place");
|
||||
}
|
||||
@ -498,15 +498,15 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
|
||||
|
||||
pub fn ty_of_arg<AC:AstConv,
|
||||
RS:region_scope + Copy + 'static>(
|
||||
self: &AC,
|
||||
this: &AC,
|
||||
rscope: &RS,
|
||||
a: ast::arg,
|
||||
expected_ty: Option<ty::arg>)
|
||||
-> ty::arg {
|
||||
let ty = match a.ty.node {
|
||||
ast::ty_infer if expected_ty.is_some() => expected_ty.get().ty,
|
||||
ast::ty_infer => self.ty_infer(a.ty.span),
|
||||
_ => ast_ty_to_ty(self, rscope, a.ty),
|
||||
ast::ty_infer => this.ty_infer(a.ty.span),
|
||||
_ => ast_ty_to_ty(this, rscope, a.ty),
|
||||
};
|
||||
|
||||
arg {
|
||||
@ -515,28 +515,28 @@ pub fn ty_of_arg<AC:AstConv,
|
||||
}
|
||||
|
||||
pub fn bound_lifetimes<AC:AstConv>(
|
||||
self: &AC,
|
||||
this: &AC,
|
||||
ast_lifetimes: &OptVec<ast::Lifetime>) -> OptVec<ast::ident>
|
||||
{
|
||||
/*!
|
||||
*
|
||||
* Converts a list of lifetimes into a list of bound identifier
|
||||
* names. Does not permit special names like 'static or 'self to
|
||||
* names. Does not permit special names like 'static or 'this to
|
||||
* be bound. Note that this function is for use in closures,
|
||||
* methods, and fn definitions. It is legal to bind 'self in a
|
||||
* methods, and fn definitions. It is legal to bind 'this in a
|
||||
* type. Eventually this distinction should go away and the same
|
||||
* rules should apply everywhere ('self would not be a special name
|
||||
* rules should apply everywhere ('this would not be a special name
|
||||
* at that point).
|
||||
*/
|
||||
|
||||
let special_idents = [special_idents::static, special_idents::self_];
|
||||
let special_idents = [special_idents::statik, special_idents::self_];
|
||||
let mut bound_lifetime_names = opt_vec::Empty;
|
||||
ast_lifetimes.map_to_vec(|ast_lifetime| {
|
||||
if special_idents.any(|&i| i == ast_lifetime.ident) {
|
||||
self.tcx().sess.span_err(
|
||||
this.tcx().sess.span_err(
|
||||
ast_lifetime.span,
|
||||
fmt!("illegal lifetime parameter name: `%s`",
|
||||
lifetime_to_str(ast_lifetime, self.tcx().sess.intr())));
|
||||
lifetime_to_str(ast_lifetime, this.tcx().sess.intr())));
|
||||
} else {
|
||||
bound_lifetime_names.push(ast_lifetime.ident);
|
||||
}
|
||||
@ -550,7 +550,7 @@ struct SelfInfo {
|
||||
}
|
||||
|
||||
pub fn ty_of_method<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
self: &AC,
|
||||
this: &AC,
|
||||
rscope: &RS,
|
||||
purity: ast::purity,
|
||||
lifetimes: &OptVec<ast::Lifetime>,
|
||||
@ -563,12 +563,12 @@ pub fn ty_of_method<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
self_transform: self_transform
|
||||
};
|
||||
let (a, b) = ty_of_method_or_bare_fn(
|
||||
self, rscope, purity, AbiSet::Rust(), lifetimes, Some(&self_info), decl);
|
||||
this, rscope, purity, AbiSet::Rust(), lifetimes, Some(&self_info), decl);
|
||||
(a.get(), b)
|
||||
}
|
||||
|
||||
pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
self: &AC,
|
||||
this: &AC,
|
||||
rscope: &RS,
|
||||
purity: ast::purity,
|
||||
abi: AbiSet,
|
||||
@ -576,12 +576,12 @@ pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
decl: &ast::fn_decl) -> ty::BareFnTy
|
||||
{
|
||||
let (_, b) = ty_of_method_or_bare_fn(
|
||||
self, rscope, purity, abi, lifetimes, None, decl);
|
||||
this, rscope, purity, abi, lifetimes, None, decl);
|
||||
b
|
||||
}
|
||||
|
||||
fn ty_of_method_or_bare_fn<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
self: &AC,
|
||||
this: &AC,
|
||||
rscope: &RS,
|
||||
purity: ast::purity,
|
||||
abi: AbiSet,
|
||||
@ -593,18 +593,18 @@ fn ty_of_method_or_bare_fn<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
|
||||
// new region names that appear inside of the fn decl are bound to
|
||||
// that function type
|
||||
let bound_lifetime_names = bound_lifetimes(self, lifetimes);
|
||||
let bound_lifetime_names = bound_lifetimes(this, lifetimes);
|
||||
let rb = in_binding_rscope(rscope, RegionParamNames(copy bound_lifetime_names));
|
||||
|
||||
let opt_transformed_self_ty = opt_self_info.map(|&self_info| {
|
||||
transform_self_ty(self, &rb, self_info)
|
||||
transform_self_ty(this, &rb, self_info)
|
||||
});
|
||||
|
||||
let input_tys = decl.inputs.map(|a| ty_of_arg(self, &rb, *a, None));
|
||||
let input_tys = decl.inputs.map(|a| ty_of_arg(this, &rb, *a, None));
|
||||
|
||||
let output_ty = match decl.output.node {
|
||||
ast::ty_infer => self.ty_infer(decl.output.span),
|
||||
_ => ast_ty_to_ty(self, &rb, decl.output)
|
||||
ast::ty_infer => this.ty_infer(decl.output.span),
|
||||
_ => ast_ty_to_ty(this, &rb, decl.output)
|
||||
};
|
||||
|
||||
return (opt_transformed_self_ty,
|
||||
@ -617,7 +617,7 @@ fn ty_of_method_or_bare_fn<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
});
|
||||
|
||||
fn transform_self_ty<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
self: &AC,
|
||||
this: &AC,
|
||||
rscope: &RS,
|
||||
self_info: &SelfInfo) -> Option<ty::t>
|
||||
{
|
||||
@ -628,20 +628,20 @@ fn ty_of_method_or_bare_fn<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
}
|
||||
ast::sty_region(lifetime, mutability) => {
|
||||
let region =
|
||||
ast_region_to_region(self, rscope,
|
||||
ast_region_to_region(this, rscope,
|
||||
self_info.self_transform.span,
|
||||
lifetime);
|
||||
Some(ty::mk_rptr(self.tcx(), region,
|
||||
Some(ty::mk_rptr(this.tcx(), region,
|
||||
ty::mt {ty: self_info.untransformed_self_ty,
|
||||
mutbl: mutability}))
|
||||
}
|
||||
ast::sty_box(mutability) => {
|
||||
Some(ty::mk_box(self.tcx(),
|
||||
Some(ty::mk_box(this.tcx(),
|
||||
ty::mt {ty: self_info.untransformed_self_ty,
|
||||
mutbl: mutability}))
|
||||
}
|
||||
ast::sty_uniq(mutability) => {
|
||||
Some(ty::mk_uniq(self.tcx(),
|
||||
Some(ty::mk_uniq(this.tcx(),
|
||||
ty::mt {ty: self_info.untransformed_self_ty,
|
||||
mutbl: mutability}))
|
||||
}
|
||||
@ -650,7 +650,7 @@ fn ty_of_method_or_bare_fn<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
}
|
||||
|
||||
pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
self: &AC,
|
||||
this: &AC,
|
||||
rscope: &RS,
|
||||
sigil: ast::Sigil,
|
||||
purity: ast::purity,
|
||||
@ -674,7 +674,7 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
// scope `rscope`, not the scope of the function parameters
|
||||
let bound_region = match opt_lifetime {
|
||||
Some(_) => {
|
||||
ast_region_to_region(self, rscope, span, opt_lifetime)
|
||||
ast_region_to_region(this, rscope, span, opt_lifetime)
|
||||
}
|
||||
None => {
|
||||
match sigil {
|
||||
@ -685,7 +685,7 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
}
|
||||
ast::BorrowedSigil => {
|
||||
// &fn() defaults as normal for an omitted lifetime:
|
||||
ast_region_to_region(self, rscope, span, opt_lifetime)
|
||||
ast_region_to_region(this, rscope, span, opt_lifetime)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -693,7 +693,7 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
|
||||
// new region names that appear inside of the fn decl are bound to
|
||||
// that function type
|
||||
let bound_lifetime_names = bound_lifetimes(self, lifetimes);
|
||||
let bound_lifetime_names = bound_lifetimes(this, lifetimes);
|
||||
let rb = in_binding_rscope(rscope, RegionParamNames(copy bound_lifetime_names));
|
||||
|
||||
let input_tys = do decl.inputs.mapi |i, a| {
|
||||
@ -702,14 +702,14 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||
// were supplied
|
||||
if i < e.inputs.len() {Some(e.inputs[i])} else {None}
|
||||
};
|
||||
ty_of_arg(self, &rb, *a, expected_arg_ty)
|
||||
ty_of_arg(this, &rb, *a, expected_arg_ty)
|
||||
};
|
||||
|
||||
let expected_ret_ty = expected_sig.map(|e| e.output);
|
||||
let output_ty = match decl.output.node {
|
||||
ast::ty_infer if expected_ret_ty.is_some() => expected_ret_ty.get(),
|
||||
ast::ty_infer => self.ty_infer(decl.output.span),
|
||||
_ => ast_ty_to_ty(self, &rb, decl.output)
|
||||
ast::ty_infer => this.ty_infer(decl.output.span),
|
||||
_ => ast_ty_to_ty(this, &rb, decl.output)
|
||||
};
|
||||
|
||||
ty::ClosureTy {
|
||||
|
@ -2391,6 +2391,12 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
|
||||
let tpt = ty_param_bounds_and_ty_for_def(fcx, expr.span, defn);
|
||||
instantiate_path(fcx, pth, tpt, expr.span, expr.id);
|
||||
}
|
||||
ast::expr_self => {
|
||||
let definition = lookup_def(fcx, expr.span, id);
|
||||
let ty_param_bounds_and_ty =
|
||||
ty_param_bounds_and_ty_for_def(fcx, expr.span, definition);
|
||||
fcx.write_ty(id, ty_param_bounds_and_ty.ty);
|
||||
}
|
||||
ast::expr_inline_asm(ref ia) => {
|
||||
fcx.require_unsafe(expr.span, ~"use of inline assembly");
|
||||
|
||||
|
@ -993,7 +993,7 @@ pub mod guarantor {
|
||||
guarantor(rcx, e)
|
||||
}
|
||||
|
||||
ast::expr_path(*) => {
|
||||
ast::expr_path(*) | ast::expr_self => {
|
||||
// Either a variable or constant and hence resides
|
||||
// in constant memory or on the stack frame. Either way,
|
||||
// not guaranteed by a region pointer.
|
||||
|
@ -370,7 +370,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
|
||||
});
|
||||
}
|
||||
|
||||
fn ty_method_of_trait_method(self: &CrateCtxt,
|
||||
fn ty_method_of_trait_method(this: &CrateCtxt,
|
||||
trait_id: ast::node_id,
|
||||
trait_rp: Option<ty::region_variance>,
|
||||
trait_generics: &ast::Generics,
|
||||
@ -381,15 +381,15 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
|
||||
m_purity: &ast::purity,
|
||||
m_decl: &ast::fn_decl) -> ty::method
|
||||
{
|
||||
let trait_self_ty = ty::mk_self(self.tcx, local_def(trait_id));
|
||||
let trait_self_ty = ty::mk_self(this.tcx, local_def(trait_id));
|
||||
let rscope = MethodRscope::new(m_self_ty.node, trait_rp, trait_generics);
|
||||
let (transformed_self_ty, fty) =
|
||||
astconv::ty_of_method(self, &rscope, *m_purity, &m_generics.lifetimes,
|
||||
astconv::ty_of_method(this, &rscope, *m_purity, &m_generics.lifetimes,
|
||||
trait_self_ty, *m_self_ty, m_decl);
|
||||
let num_trait_type_params = trait_generics.ty_params.len();
|
||||
ty::method {
|
||||
ident: *m_ident,
|
||||
generics: ty_generics(self, None, m_generics, num_trait_type_params),
|
||||
generics: ty_generics(this, None, m_generics, num_trait_type_params),
|
||||
transformed_self_ty: transformed_self_ty,
|
||||
fty: fty,
|
||||
self_ty: m_self_ty.node,
|
||||
|
@ -120,31 +120,31 @@ pub struct CombineFields {
|
||||
}
|
||||
|
||||
pub fn expected_found<C:Combine,T>(
|
||||
self: &C, a: T, b: T) -> ty::expected_found<T> {
|
||||
if self.a_is_expected() {
|
||||
this: &C, a: T, b: T) -> ty::expected_found<T> {
|
||||
if this.a_is_expected() {
|
||||
ty::expected_found {expected: a, found: b}
|
||||
} else {
|
||||
ty::expected_found {expected: b, found: a}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eq_tys<C:Combine>(self: &C, a: ty::t, b: ty::t) -> ures {
|
||||
let suber = self.sub();
|
||||
do self.infcx().try {
|
||||
pub fn eq_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> ures {
|
||||
let suber = this.sub();
|
||||
do this.infcx().try {
|
||||
do suber.tys(a, b).chain |_ok| {
|
||||
suber.contratys(a, b)
|
||||
}.to_ures()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eq_regions<C:Combine>(self: &C, a: ty::Region, b: ty::Region)
|
||||
pub fn eq_regions<C:Combine>(this: &C, a: ty::Region, b: ty::Region)
|
||||
-> ures {
|
||||
debug!("eq_regions(%s, %s)",
|
||||
a.inf_str(self.infcx()),
|
||||
b.inf_str(self.infcx()));
|
||||
let sub = self.sub();
|
||||
a.inf_str(this.infcx()),
|
||||
b.inf_str(this.infcx()));
|
||||
let sub = this.sub();
|
||||
do indent {
|
||||
self.infcx().try(|| {
|
||||
this.infcx().try(|| {
|
||||
do sub.regions(a, b).chain |_r| {
|
||||
sub.contraregions(a, b)
|
||||
}
|
||||
@ -161,7 +161,7 @@ pub fn eq_regions<C:Combine>(self: &C, a: ty::Region, b: ty::Region)
|
||||
}
|
||||
|
||||
pub fn eq_opt_regions<C:Combine>(
|
||||
self: &C,
|
||||
this: &C,
|
||||
a: Option<ty::Region>,
|
||||
b: Option<ty::Region>) -> cres<Option<ty::Region>> {
|
||||
|
||||
@ -170,7 +170,7 @@ pub fn eq_opt_regions<C:Combine>(
|
||||
Ok(None)
|
||||
}
|
||||
(Some(a), Some(b)) => {
|
||||
do eq_regions(self, a, b).then {
|
||||
do eq_regions(this, a, b).then {
|
||||
Ok(Some(a))
|
||||
}
|
||||
}
|
||||
@ -179,21 +179,21 @@ pub fn eq_opt_regions<C:Combine>(
|
||||
// they should be), then the type should either
|
||||
// consistently have a region parameter or not have a
|
||||
// region parameter.
|
||||
self.infcx().tcx.sess.bug(
|
||||
this.infcx().tcx.sess.bug(
|
||||
fmt!("substitution a had opt_region %s and \
|
||||
b had opt_region %s",
|
||||
a.inf_str(self.infcx()),
|
||||
b.inf_str(self.infcx())));
|
||||
a.inf_str(this.infcx()),
|
||||
b.inf_str(this.infcx())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn super_substs<C:Combine>(
|
||||
self: &C, generics: &ty::Generics,
|
||||
this: &C, generics: &ty::Generics,
|
||||
a: &ty::substs, b: &ty::substs) -> cres<ty::substs> {
|
||||
|
||||
fn relate_region_param<C:Combine>(
|
||||
self: &C,
|
||||
this: &C,
|
||||
generics: &ty::Generics,
|
||||
a: Option<ty::Region>,
|
||||
b: Option<ty::Region>)
|
||||
@ -204,17 +204,17 @@ pub fn super_substs<C:Combine>(
|
||||
Ok(None)
|
||||
}
|
||||
(&Some(ty::rv_invariant), &Some(a), &Some(b)) => {
|
||||
do eq_regions(self, a, b).then {
|
||||
do eq_regions(this, a, b).then {
|
||||
Ok(Some(a))
|
||||
}
|
||||
}
|
||||
(&Some(ty::rv_covariant), &Some(a), &Some(b)) => {
|
||||
do self.regions(a, b).chain |r| {
|
||||
do this.regions(a, b).chain |r| {
|
||||
Ok(Some(r))
|
||||
}
|
||||
}
|
||||
(&Some(ty::rv_contravariant), &Some(a), &Some(b)) => {
|
||||
do self.contraregions(a, b).chain |r| {
|
||||
do this.contraregions(a, b).chain |r| {
|
||||
Ok(Some(r))
|
||||
}
|
||||
}
|
||||
@ -224,19 +224,19 @@ pub fn super_substs<C:Combine>(
|
||||
// consistently have a region parameter or not have a
|
||||
// region parameter, and that should match with the
|
||||
// polytype.
|
||||
self.infcx().tcx.sess.bug(
|
||||
this.infcx().tcx.sess.bug(
|
||||
fmt!("substitution a had opt_region %s and \
|
||||
b had opt_region %s with variance %?",
|
||||
a.inf_str(self.infcx()),
|
||||
b.inf_str(self.infcx()),
|
||||
a.inf_str(this.infcx()),
|
||||
b.inf_str(this.infcx()),
|
||||
generics.region_param));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do self.tps(a.tps, b.tps).chain |tps| {
|
||||
do self.self_tys(a.self_ty, b.self_ty).chain |self_ty| {
|
||||
do relate_region_param(self, generics,
|
||||
do this.tps(a.tps, b.tps).chain |tps| {
|
||||
do this.self_tys(a.self_ty, b.self_ty).chain |self_ty| {
|
||||
do relate_region_param(this, generics,
|
||||
a.self_r, b.self_r).chain |self_r|
|
||||
{
|
||||
Ok(substs {
|
||||
@ -250,7 +250,7 @@ pub fn super_substs<C:Combine>(
|
||||
}
|
||||
|
||||
pub fn super_tps<C:Combine>(
|
||||
self: &C, as_: &[ty::t], bs: &[ty::t]) -> cres<~[ty::t]> {
|
||||
this: &C, as_: &[ty::t], bs: &[ty::t]) -> cres<~[ty::t]> {
|
||||
|
||||
// Note: type parameters are always treated as *invariant*
|
||||
// (otherwise the type system would be unsound). In the
|
||||
@ -259,16 +259,16 @@ pub fn super_tps<C:Combine>(
|
||||
|
||||
if vec::same_length(as_, bs) {
|
||||
iter_vec2(as_, bs, |a, b| {
|
||||
eq_tys(self, *a, *b)
|
||||
eq_tys(this, *a, *b)
|
||||
}).then(|| Ok(as_.to_vec()) )
|
||||
} else {
|
||||
Err(ty::terr_ty_param_size(
|
||||
expected_found(self, as_.len(), bs.len())))
|
||||
expected_found(this, as_.len(), bs.len())))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn super_self_tys<C:Combine>(
|
||||
self: &C, a: Option<ty::t>, b: Option<ty::t>) -> cres<Option<ty::t>> {
|
||||
this: &C, a: Option<ty::t>, b: Option<ty::t>) -> cres<Option<ty::t>> {
|
||||
|
||||
match (a, b) {
|
||||
(None, None) => {
|
||||
@ -276,8 +276,8 @@ pub fn super_self_tys<C:Combine>(
|
||||
}
|
||||
(Some(a), Some(b)) => {
|
||||
// FIXME(#5781) this should be eq_tys
|
||||
// eq_tys(self, a, b).then(|| Ok(Some(a)) )
|
||||
self.contratys(a, b).chain(|t| Ok(Some(t)))
|
||||
// eq_tys(this, a, b).then(|| Ok(Some(a)) )
|
||||
this.contratys(a, b).chain(|t| Ok(Some(t)))
|
||||
}
|
||||
(None, Some(_)) |
|
||||
(Some(_), None) => {
|
||||
@ -290,46 +290,46 @@ pub fn super_self_tys<C:Combine>(
|
||||
}
|
||||
|
||||
pub fn super_sigils<C:Combine>(
|
||||
self: &C, p1: ast::Sigil, p2: ast::Sigil) -> cres<ast::Sigil> {
|
||||
this: &C, p1: ast::Sigil, p2: ast::Sigil) -> cres<ast::Sigil> {
|
||||
if p1 == p2 {
|
||||
Ok(p1)
|
||||
} else {
|
||||
Err(ty::terr_sigil_mismatch(expected_found(self, p1, p2)))
|
||||
Err(ty::terr_sigil_mismatch(expected_found(this, p1, p2)))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn super_flds<C:Combine>(
|
||||
self: &C, a: ty::field, b: ty::field) -> cres<ty::field> {
|
||||
this: &C, a: ty::field, b: ty::field) -> cres<ty::field> {
|
||||
|
||||
if a.ident == b.ident {
|
||||
self.mts(&a.mt, &b.mt)
|
||||
this.mts(&a.mt, &b.mt)
|
||||
.chain(|mt| Ok(ty::field {ident: a.ident, mt: mt}) )
|
||||
.chain_err(|e| Err(ty::terr_in_field(@e, a.ident)) )
|
||||
} else {
|
||||
Err(ty::terr_record_fields(
|
||||
expected_found(self, a.ident, b.ident)))
|
||||
expected_found(this, a.ident, b.ident)))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn super_args<C:Combine>(self: &C, a: ty::arg, b: ty::arg)
|
||||
pub fn super_args<C:Combine>(this: &C, a: ty::arg, b: ty::arg)
|
||||
-> cres<ty::arg> {
|
||||
do self.contratys(a.ty, b.ty).chain |t| {
|
||||
do this.contratys(a.ty, b.ty).chain |t| {
|
||||
Ok(arg {
|
||||
ty: t
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn super_vstores<C:Combine>(self: &C,
|
||||
pub fn super_vstores<C:Combine>(this: &C,
|
||||
vk: ty::terr_vstore_kind,
|
||||
a: ty::vstore,
|
||||
b: ty::vstore)
|
||||
-> cres<ty::vstore> {
|
||||
debug!("%s.super_vstores(a=%?, b=%?)", self.tag(), a, b);
|
||||
debug!("%s.super_vstores(a=%?, b=%?)", this.tag(), a, b);
|
||||
|
||||
match (a, b) {
|
||||
(ty::vstore_slice(a_r), ty::vstore_slice(b_r)) => {
|
||||
do self.contraregions(a_r, b_r).chain |r| {
|
||||
do this.contraregions(a_r, b_r).chain |r| {
|
||||
Ok(ty::vstore_slice(r))
|
||||
}
|
||||
}
|
||||
@ -339,21 +339,21 @@ pub fn super_vstores<C:Combine>(self: &C,
|
||||
}
|
||||
|
||||
_ => {
|
||||
Err(ty::terr_vstores_differ(vk, expected_found(self, a, b)))
|
||||
Err(ty::terr_vstores_differ(vk, expected_found(this, a, b)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn super_trait_stores<C:Combine>(self: &C,
|
||||
pub fn super_trait_stores<C:Combine>(this: &C,
|
||||
vk: ty::terr_vstore_kind,
|
||||
a: ty::TraitStore,
|
||||
b: ty::TraitStore)
|
||||
-> cres<ty::TraitStore> {
|
||||
debug!("%s.super_vstores(a=%?, b=%?)", self.tag(), a, b);
|
||||
debug!("%s.super_vstores(a=%?, b=%?)", this.tag(), a, b);
|
||||
|
||||
match (a, b) {
|
||||
(ty::RegionTraitStore(a_r), ty::RegionTraitStore(b_r)) => {
|
||||
do self.contraregions(a_r, b_r).chain |r| {
|
||||
do this.contraregions(a_r, b_r).chain |r| {
|
||||
Ok(ty::RegionTraitStore(r))
|
||||
}
|
||||
}
|
||||
@ -363,19 +363,19 @@ pub fn super_trait_stores<C:Combine>(self: &C,
|
||||
}
|
||||
|
||||
_ => {
|
||||
Err(ty::terr_trait_stores_differ(vk, expected_found(self, a, b)))
|
||||
Err(ty::terr_trait_stores_differ(vk, expected_found(this, a, b)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn super_closure_tys<C:Combine>(
|
||||
self: &C, a_f: &ty::ClosureTy, b_f: &ty::ClosureTy) -> cres<ty::ClosureTy>
|
||||
this: &C, a_f: &ty::ClosureTy, b_f: &ty::ClosureTy) -> cres<ty::ClosureTy>
|
||||
{
|
||||
let p = if_ok!(self.sigils(a_f.sigil, b_f.sigil));
|
||||
let r = if_ok!(self.contraregions(a_f.region, b_f.region));
|
||||
let purity = if_ok!(self.purities(a_f.purity, b_f.purity));
|
||||
let onceness = if_ok!(self.oncenesses(a_f.onceness, b_f.onceness));
|
||||
let sig = if_ok!(self.fn_sigs(&a_f.sig, &b_f.sig));
|
||||
let p = if_ok!(this.sigils(a_f.sigil, b_f.sigil));
|
||||
let r = if_ok!(this.contraregions(a_f.region, b_f.region));
|
||||
let purity = if_ok!(this.purities(a_f.purity, b_f.purity));
|
||||
let onceness = if_ok!(this.oncenesses(a_f.onceness, b_f.onceness));
|
||||
let sig = if_ok!(this.fn_sigs(&a_f.sig, &b_f.sig));
|
||||
Ok(ty::ClosureTy {purity: purity,
|
||||
sigil: p,
|
||||
onceness: onceness,
|
||||
@ -384,43 +384,43 @@ pub fn super_closure_tys<C:Combine>(
|
||||
}
|
||||
|
||||
pub fn super_abis<C:Combine>(
|
||||
self: &C, a: AbiSet, b: AbiSet) -> cres<AbiSet>
|
||||
this: &C, a: AbiSet, b: AbiSet) -> cres<AbiSet>
|
||||
{
|
||||
if a == b {
|
||||
Ok(a)
|
||||
} else {
|
||||
Err(ty::terr_abi_mismatch(expected_found(self, a, b)))
|
||||
Err(ty::terr_abi_mismatch(expected_found(this, a, b)))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn super_bare_fn_tys<C:Combine>(
|
||||
self: &C, a_f: &ty::BareFnTy, b_f: &ty::BareFnTy) -> cres<ty::BareFnTy>
|
||||
this: &C, a_f: &ty::BareFnTy, b_f: &ty::BareFnTy) -> cres<ty::BareFnTy>
|
||||
{
|
||||
let purity = if_ok!(self.purities(a_f.purity, b_f.purity));
|
||||
let abi = if_ok!(self.abis(a_f.abis, b_f.abis));
|
||||
let sig = if_ok!(self.fn_sigs(&a_f.sig, &b_f.sig));
|
||||
let purity = if_ok!(this.purities(a_f.purity, b_f.purity));
|
||||
let abi = if_ok!(this.abis(a_f.abis, b_f.abis));
|
||||
let sig = if_ok!(this.fn_sigs(&a_f.sig, &b_f.sig));
|
||||
Ok(ty::BareFnTy {purity: purity,
|
||||
abis: abi,
|
||||
sig: sig})
|
||||
}
|
||||
|
||||
pub fn super_fn_sigs<C:Combine>(
|
||||
self: &C, a_f: &ty::FnSig, b_f: &ty::FnSig) -> cres<ty::FnSig>
|
||||
this: &C, a_f: &ty::FnSig, b_f: &ty::FnSig) -> cres<ty::FnSig>
|
||||
{
|
||||
fn argvecs<C:Combine>(self: &C,
|
||||
fn argvecs<C:Combine>(this: &C,
|
||||
a_args: &[ty::arg],
|
||||
b_args: &[ty::arg]) -> cres<~[ty::arg]>
|
||||
{
|
||||
if vec::same_length(a_args, b_args) {
|
||||
map_vec2(a_args, b_args, |a, b| self.args(*a, *b))
|
||||
map_vec2(a_args, b_args, |a, b| this.args(*a, *b))
|
||||
} else {
|
||||
Err(ty::terr_arg_count)
|
||||
}
|
||||
}
|
||||
|
||||
do argvecs(self, a_f.inputs, b_f.inputs)
|
||||
do argvecs(this, a_f.inputs, b_f.inputs)
|
||||
.chain |inputs| {
|
||||
do self.tys(a_f.output, b_f.output).chain |output| {
|
||||
do this.tys(a_f.output, b_f.output).chain |output| {
|
||||
Ok(FnSig {bound_lifetime_names: opt_vec::Empty, // FIXME(#4846)
|
||||
inputs: /*bad*/copy inputs,
|
||||
output: output})
|
||||
@ -429,8 +429,8 @@ pub fn super_fn_sigs<C:Combine>(
|
||||
}
|
||||
|
||||
pub fn super_tys<C:Combine>(
|
||||
self: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
|
||||
let tcx = self.infcx().tcx;
|
||||
this: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
|
||||
let tcx = this.infcx().tcx;
|
||||
return match (/*bad*/copy ty::get(a).sty, /*bad*/copy ty::get(b).sty) {
|
||||
// The "subtype" ought to be handling cases involving bot or var:
|
||||
(ty::ty_bot, _) |
|
||||
@ -439,45 +439,45 @@ pub fn super_tys<C:Combine>(
|
||||
(_, ty::ty_infer(TyVar(_))) => {
|
||||
tcx.sess.bug(
|
||||
fmt!("%s: bot and var types should have been handled (%s,%s)",
|
||||
self.tag(),
|
||||
a.inf_str(self.infcx()),
|
||||
b.inf_str(self.infcx())));
|
||||
this.tag(),
|
||||
a.inf_str(this.infcx()),
|
||||
b.inf_str(this.infcx())));
|
||||
}
|
||||
|
||||
// Relate integral variables to other types
|
||||
(ty::ty_infer(IntVar(a_id)), ty::ty_infer(IntVar(b_id))) => {
|
||||
if_ok!(self.infcx().simple_vars(self.a_is_expected(),
|
||||
if_ok!(this.infcx().simple_vars(this.a_is_expected(),
|
||||
a_id, b_id));
|
||||
Ok(a)
|
||||
}
|
||||
(ty::ty_infer(IntVar(v_id)), ty::ty_int(v)) => {
|
||||
unify_integral_variable(self, self.a_is_expected(),
|
||||
unify_integral_variable(this, this.a_is_expected(),
|
||||
v_id, IntType(v))
|
||||
}
|
||||
(ty::ty_int(v), ty::ty_infer(IntVar(v_id))) => {
|
||||
unify_integral_variable(self, !self.a_is_expected(),
|
||||
unify_integral_variable(this, !this.a_is_expected(),
|
||||
v_id, IntType(v))
|
||||
}
|
||||
(ty::ty_infer(IntVar(v_id)), ty::ty_uint(v)) => {
|
||||
unify_integral_variable(self, self.a_is_expected(),
|
||||
unify_integral_variable(this, this.a_is_expected(),
|
||||
v_id, UintType(v))
|
||||
}
|
||||
(ty::ty_uint(v), ty::ty_infer(IntVar(v_id))) => {
|
||||
unify_integral_variable(self, !self.a_is_expected(),
|
||||
unify_integral_variable(this, !this.a_is_expected(),
|
||||
v_id, UintType(v))
|
||||
}
|
||||
|
||||
// Relate floating-point variables to other types
|
||||
(ty::ty_infer(FloatVar(a_id)), ty::ty_infer(FloatVar(b_id))) => {
|
||||
if_ok!(self.infcx().simple_vars(self.a_is_expected(),
|
||||
if_ok!(this.infcx().simple_vars(this.a_is_expected(),
|
||||
a_id, b_id));
|
||||
Ok(a)
|
||||
}
|
||||
(ty::ty_infer(FloatVar(v_id)), ty::ty_float(v)) => {
|
||||
unify_float_variable(self, self.a_is_expected(), v_id, v)
|
||||
unify_float_variable(this, this.a_is_expected(), v_id, v)
|
||||
}
|
||||
(ty::ty_float(v), ty::ty_infer(FloatVar(v_id))) => {
|
||||
unify_float_variable(self, !self.a_is_expected(), v_id, v)
|
||||
unify_float_variable(this, !this.a_is_expected(), v_id, v)
|
||||
}
|
||||
|
||||
(ty::ty_nil, _) |
|
||||
@ -488,7 +488,7 @@ pub fn super_tys<C:Combine>(
|
||||
if ty::get(a).sty == ty::get(b).sty {
|
||||
Ok(a)
|
||||
} else {
|
||||
Err(ty::terr_sorts(expected_found(self, a, b)))
|
||||
Err(ty::terr_sorts(expected_found(this, a, b)))
|
||||
}
|
||||
}
|
||||
|
||||
@ -500,7 +500,7 @@ pub fn super_tys<C:Combine>(
|
||||
ty::ty_enum(b_id, ref b_substs))
|
||||
if a_id == b_id => {
|
||||
let type_def = ty::lookup_item_type(tcx, a_id);
|
||||
do self.substs(&type_def.generics, a_substs, b_substs).chain |substs| {
|
||||
do this.substs(&type_def.generics, a_substs, b_substs).chain |substs| {
|
||||
Ok(ty::mk_enum(tcx, a_id, substs))
|
||||
}
|
||||
}
|
||||
@ -509,8 +509,8 @@ pub fn super_tys<C:Combine>(
|
||||
ty::ty_trait(b_id, ref b_substs, b_store, b_mutbl))
|
||||
if a_id == b_id && a_mutbl == b_mutbl => {
|
||||
let trait_def = ty::lookup_trait_def(tcx, a_id);
|
||||
do self.substs(&trait_def.generics, a_substs, b_substs).chain |substs| {
|
||||
do self.trait_stores(ty::terr_trait, a_store, b_store).chain |s| {
|
||||
do this.substs(&trait_def.generics, a_substs, b_substs).chain |substs| {
|
||||
do this.trait_stores(ty::terr_trait, a_store, b_store).chain |s| {
|
||||
Ok(ty::mk_trait(tcx, a_id, /*bad*/copy substs, s, a_mutbl))
|
||||
}
|
||||
}
|
||||
@ -519,76 +519,76 @@ pub fn super_tys<C:Combine>(
|
||||
(ty::ty_struct(a_id, ref a_substs), ty::ty_struct(b_id, ref b_substs))
|
||||
if a_id == b_id => {
|
||||
let type_def = ty::lookup_item_type(tcx, a_id);
|
||||
do self.substs(&type_def.generics, a_substs, b_substs).chain |substs| {
|
||||
do this.substs(&type_def.generics, a_substs, b_substs).chain |substs| {
|
||||
Ok(ty::mk_struct(tcx, a_id, substs))
|
||||
}
|
||||
}
|
||||
|
||||
(ty::ty_box(ref a_mt), ty::ty_box(ref b_mt)) => {
|
||||
do self.mts(a_mt, b_mt).chain |mt| {
|
||||
do this.mts(a_mt, b_mt).chain |mt| {
|
||||
Ok(ty::mk_box(tcx, mt))
|
||||
}
|
||||
}
|
||||
|
||||
(ty::ty_uniq(ref a_mt), ty::ty_uniq(ref b_mt)) => {
|
||||
do self.mts(a_mt, b_mt).chain |mt| {
|
||||
do this.mts(a_mt, b_mt).chain |mt| {
|
||||
Ok(ty::mk_uniq(tcx, mt))
|
||||
}
|
||||
}
|
||||
|
||||
(ty::ty_ptr(ref a_mt), ty::ty_ptr(ref b_mt)) => {
|
||||
do self.mts(a_mt, b_mt).chain |mt| {
|
||||
do this.mts(a_mt, b_mt).chain |mt| {
|
||||
Ok(ty::mk_ptr(tcx, mt))
|
||||
}
|
||||
}
|
||||
|
||||
(ty::ty_rptr(a_r, ref a_mt), ty::ty_rptr(b_r, ref b_mt)) => {
|
||||
let r = if_ok!(self.contraregions(a_r, b_r));
|
||||
let mt = if_ok!(self.mts(a_mt, b_mt));
|
||||
let r = if_ok!(this.contraregions(a_r, b_r));
|
||||
let mt = if_ok!(this.mts(a_mt, b_mt));
|
||||
Ok(ty::mk_rptr(tcx, r, mt))
|
||||
}
|
||||
|
||||
(ty::ty_evec(ref a_mt, vs_a), ty::ty_evec(ref b_mt, vs_b)) => {
|
||||
do self.mts(a_mt, b_mt).chain |mt| {
|
||||
do self.vstores(ty::terr_vec, vs_a, vs_b).chain |vs| {
|
||||
do this.mts(a_mt, b_mt).chain |mt| {
|
||||
do this.vstores(ty::terr_vec, vs_a, vs_b).chain |vs| {
|
||||
Ok(ty::mk_evec(tcx, mt, vs))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(ty::ty_estr(vs_a), ty::ty_estr(vs_b)) => {
|
||||
do self.vstores(ty::terr_str, vs_a, vs_b).chain |vs| {
|
||||
do this.vstores(ty::terr_str, vs_a, vs_b).chain |vs| {
|
||||
Ok(ty::mk_estr(tcx,vs))
|
||||
}
|
||||
}
|
||||
|
||||
(ty::ty_tup(ref as_), ty::ty_tup(ref bs)) => {
|
||||
if as_.len() == bs.len() {
|
||||
map_vec2(*as_, *bs, |a, b| self.tys(*a, *b) )
|
||||
map_vec2(*as_, *bs, |a, b| this.tys(*a, *b) )
|
||||
.chain(|ts| Ok(ty::mk_tup(tcx, ts)) )
|
||||
} else {
|
||||
Err(ty::terr_tuple_size(
|
||||
expected_found(self, as_.len(), bs.len())))
|
||||
expected_found(this, as_.len(), bs.len())))
|
||||
}
|
||||
}
|
||||
|
||||
(ty::ty_bare_fn(ref a_fty), ty::ty_bare_fn(ref b_fty)) => {
|
||||
do self.bare_fn_tys(a_fty, b_fty).chain |fty| {
|
||||
do this.bare_fn_tys(a_fty, b_fty).chain |fty| {
|
||||
Ok(ty::mk_bare_fn(tcx, fty))
|
||||
}
|
||||
}
|
||||
|
||||
(ty::ty_closure(ref a_fty), ty::ty_closure(ref b_fty)) => {
|
||||
do self.closure_tys(a_fty, b_fty).chain |fty| {
|
||||
do this.closure_tys(a_fty, b_fty).chain |fty| {
|
||||
Ok(ty::mk_closure(tcx, fty))
|
||||
}
|
||||
}
|
||||
|
||||
_ => Err(ty::terr_sorts(expected_found(self, a, b)))
|
||||
_ => Err(ty::terr_sorts(expected_found(this, a, b)))
|
||||
};
|
||||
|
||||
fn unify_integral_variable<C:Combine>(
|
||||
self: &C,
|
||||
this: &C,
|
||||
vid_is_expected: bool,
|
||||
vid: ty::IntVid,
|
||||
val: ty::IntVarValue) -> cres<ty::t>
|
||||
@ -596,7 +596,7 @@ pub fn super_tys<C:Combine>(
|
||||
if val == IntType(ast::ty_char) {
|
||||
Err(ty::terr_integer_as_char)
|
||||
} else {
|
||||
if_ok!(self.infcx().simple_var_t(vid_is_expected, vid, val));
|
||||
if_ok!(this.infcx().simple_var_t(vid_is_expected, vid, val));
|
||||
match val {
|
||||
IntType(v) => Ok(ty::mk_mach_int(v)),
|
||||
UintType(v) => Ok(ty::mk_mach_uint(v))
|
||||
@ -605,18 +605,18 @@ pub fn super_tys<C:Combine>(
|
||||
}
|
||||
|
||||
fn unify_float_variable<C:Combine>(
|
||||
self: &C,
|
||||
this: &C,
|
||||
vid_is_expected: bool,
|
||||
vid: ty::FloatVid,
|
||||
val: ast::float_ty) -> cres<ty::t>
|
||||
{
|
||||
if_ok!(self.infcx().simple_var_t(vid_is_expected, vid, val));
|
||||
if_ok!(this.infcx().simple_var_t(vid_is_expected, vid, val));
|
||||
Ok(ty::mk_mach_float(val))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn super_trait_refs<C:Combine>(
|
||||
self: &C, a: &ty::TraitRef, b: &ty::TraitRef) -> cres<ty::TraitRef>
|
||||
this: &C, a: &ty::TraitRef, b: &ty::TraitRef) -> cres<ty::TraitRef>
|
||||
{
|
||||
// Different traits cannot be related
|
||||
|
||||
@ -624,11 +624,11 @@ pub fn super_trait_refs<C:Combine>(
|
||||
|
||||
if a.def_id != b.def_id {
|
||||
Err(ty::terr_traits(
|
||||
expected_found(self, a.def_id, b.def_id)))
|
||||
expected_found(this, a.def_id, b.def_id)))
|
||||
} else {
|
||||
let tcx = self.infcx().tcx;
|
||||
let tcx = this.infcx().tcx;
|
||||
let trait_def = ty::lookup_trait_def(tcx, a.def_id);
|
||||
let substs = if_ok!(self.substs(&trait_def.generics, &a.substs, &b.substs));
|
||||
let substs = if_ok!(this.substs(&trait_def.generics, &a.substs, &b.substs));
|
||||
Ok(ty::TraitRef {
|
||||
def_id: a.def_id,
|
||||
substs: substs
|
||||
|
@ -198,7 +198,7 @@ impl Combine for Glb {
|
||||
debug!("sig1 = %s", sig1.inf_str(self.infcx));
|
||||
return Ok(sig1);
|
||||
|
||||
fn generalize_region(self: &Glb,
|
||||
fn generalize_region(this: &Glb,
|
||||
snapshot: uint,
|
||||
new_vars: &[RegionVid],
|
||||
a_isr: isr_alist,
|
||||
@ -209,19 +209,19 @@ impl Combine for Glb {
|
||||
return r0;
|
||||
}
|
||||
|
||||
let tainted = self.infcx.region_vars.tainted(snapshot, r0);
|
||||
let tainted = this.infcx.region_vars.tainted(snapshot, r0);
|
||||
|
||||
let mut a_r = None, b_r = None, only_new_vars = true;
|
||||
for tainted.each |r| {
|
||||
if is_var_in_set(a_vars, *r) {
|
||||
if a_r.is_some() {
|
||||
return fresh_bound_variable(self);
|
||||
return fresh_bound_variable(this);
|
||||
} else {
|
||||
a_r = Some(*r);
|
||||
}
|
||||
} else if is_var_in_set(b_vars, *r) {
|
||||
if b_r.is_some() {
|
||||
return fresh_bound_variable(self);
|
||||
return fresh_bound_variable(this);
|
||||
} else {
|
||||
b_r = Some(*r);
|
||||
}
|
||||
@ -246,17 +246,17 @@ impl Combine for Glb {
|
||||
|
||||
if a_r.is_some() && b_r.is_some() && only_new_vars {
|
||||
// Related to exactly one bound variable from each fn:
|
||||
return rev_lookup(self, a_isr, a_r.get());
|
||||
return rev_lookup(this, a_isr, a_r.get());
|
||||
} else if a_r.is_none() && b_r.is_none() {
|
||||
// Not related to bound variables from either fn:
|
||||
return r0;
|
||||
} else {
|
||||
// Other:
|
||||
return fresh_bound_variable(self);
|
||||
return fresh_bound_variable(this);
|
||||
}
|
||||
}
|
||||
|
||||
fn rev_lookup(self: &Glb,
|
||||
fn rev_lookup(this: &Glb,
|
||||
a_isr: isr_alist,
|
||||
r: ty::Region) -> ty::Region
|
||||
{
|
||||
@ -267,13 +267,13 @@ impl Combine for Glb {
|
||||
}
|
||||
}
|
||||
|
||||
self.infcx.tcx.sess.span_bug(
|
||||
self.span,
|
||||
this.infcx.tcx.sess.span_bug(
|
||||
this.span,
|
||||
fmt!("could not find original bound region for %?", r));
|
||||
}
|
||||
|
||||
fn fresh_bound_variable(self: &Glb) -> ty::Region {
|
||||
self.infcx.region_vars.new_bound()
|
||||
fn fresh_bound_variable(this: &Glb) -> ty::Region {
|
||||
this.infcx.region_vars.new_bound()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -330,27 +330,27 @@ impl TyLatticeDir for Glb {
|
||||
}
|
||||
|
||||
pub fn super_lattice_tys<L:LatticeDir + TyLatticeDir + Combine>(
|
||||
self: &L,
|
||||
this: &L,
|
||||
a: ty::t,
|
||||
b: ty::t) -> cres<ty::t> {
|
||||
debug!("%s.lattice_tys(%s, %s)", self.tag(),
|
||||
a.inf_str(self.infcx()),
|
||||
b.inf_str(self.infcx()));
|
||||
debug!("%s.lattice_tys(%s, %s)", this.tag(),
|
||||
a.inf_str(this.infcx()),
|
||||
b.inf_str(this.infcx()));
|
||||
let _r = indenter();
|
||||
|
||||
if a == b {
|
||||
return Ok(a);
|
||||
}
|
||||
|
||||
let tcx = self.infcx().tcx;
|
||||
let tcx = this.infcx().tcx;
|
||||
|
||||
match (&ty::get(a).sty, &ty::get(b).sty) {
|
||||
(&ty::ty_bot, _) => { return self.ty_bot(b); }
|
||||
(_, &ty::ty_bot) => { return self.ty_bot(a); }
|
||||
(&ty::ty_bot, _) => { return this.ty_bot(b); }
|
||||
(_, &ty::ty_bot) => { return this.ty_bot(a); }
|
||||
|
||||
(&ty::ty_infer(TyVar(a_id)), &ty::ty_infer(TyVar(b_id))) => {
|
||||
let r = if_ok!(lattice_vars(self, a_id, b_id,
|
||||
|x, y| self.tys(*x, *y)));
|
||||
let r = if_ok!(lattice_vars(this, a_id, b_id,
|
||||
|x, y| this.tys(*x, *y)));
|
||||
return match r {
|
||||
VarResult(v) => Ok(ty::mk_var(tcx, v)),
|
||||
ValueResult(t) => Ok(t)
|
||||
@ -358,17 +358,17 @@ pub fn super_lattice_tys<L:LatticeDir + TyLatticeDir + Combine>(
|
||||
}
|
||||
|
||||
(&ty::ty_infer(TyVar(a_id)), _) => {
|
||||
return lattice_var_and_t(self, a_id, &b,
|
||||
|x, y| self.tys(*x, *y));
|
||||
return lattice_var_and_t(this, a_id, &b,
|
||||
|x, y| this.tys(*x, *y));
|
||||
}
|
||||
|
||||
(_, &ty::ty_infer(TyVar(b_id))) => {
|
||||
return lattice_var_and_t(self, b_id, &a,
|
||||
|x, y| self.tys(*x, *y));
|
||||
return lattice_var_and_t(this, b_id, &a,
|
||||
|x, y| this.tys(*x, *y));
|
||||
}
|
||||
|
||||
_ => {
|
||||
return super_tys(self, a, b);
|
||||
return super_tys(this, a, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -398,22 +398,22 @@ pub enum LatticeVarResult<V,T> {
|
||||
pub fn lattice_vars<L:LatticeDir + Combine,
|
||||
T:Copy + InferStr + LatticeValue,
|
||||
V:Copy + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
|
||||
self: &L, // defines whether we want LUB or GLB
|
||||
this: &L, // defines whether we want LUB or GLB
|
||||
a_vid: V, // first variable
|
||||
b_vid: V, // second variable
|
||||
lattice_dir_op: LatticeDirOp<T>) // LUB or GLB operation on types
|
||||
-> cres<LatticeVarResult<V,T>> {
|
||||
let nde_a = self.infcx().get(a_vid);
|
||||
let nde_b = self.infcx().get(b_vid);
|
||||
let nde_a = this.infcx().get(a_vid);
|
||||
let nde_b = this.infcx().get(b_vid);
|
||||
let a_vid = nde_a.root;
|
||||
let b_vid = nde_b.root;
|
||||
let a_bounds = &nde_a.possible_types;
|
||||
let b_bounds = &nde_b.possible_types;
|
||||
|
||||
debug!("%s.lattice_vars(%s=%s <: %s=%s)",
|
||||
self.tag(),
|
||||
a_vid.to_str(), a_bounds.inf_str(self.infcx()),
|
||||
b_vid.to_str(), b_bounds.inf_str(self.infcx()));
|
||||
this.tag(),
|
||||
a_vid.to_str(), a_bounds.inf_str(this.infcx()),
|
||||
b_vid.to_str(), b_bounds.inf_str(this.infcx()));
|
||||
|
||||
// Same variable: the easy case.
|
||||
if a_vid == b_vid {
|
||||
@ -422,10 +422,10 @@ pub fn lattice_vars<L:LatticeDir + Combine,
|
||||
|
||||
// If both A and B have an UB type, then we can just compute the
|
||||
// LUB of those types:
|
||||
let a_bnd = self.bnd(a_bounds), b_bnd = self.bnd(b_bounds);
|
||||
let a_bnd = this.bnd(a_bounds), b_bnd = this.bnd(b_bounds);
|
||||
match (a_bnd, b_bnd) {
|
||||
(Some(ref a_ty), Some(ref b_ty)) => {
|
||||
match self.infcx().try(|| lattice_dir_op(a_ty, b_ty) ) {
|
||||
match this.infcx().try(|| lattice_dir_op(a_ty, b_ty) ) {
|
||||
Ok(t) => return Ok(ValueResult(t)),
|
||||
Err(_) => { /*fallthrough */ }
|
||||
}
|
||||
@ -435,7 +435,7 @@ pub fn lattice_vars<L:LatticeDir + Combine,
|
||||
|
||||
// Otherwise, we need to merge A and B into one variable. We can
|
||||
// then use either variable as an upper bound:
|
||||
let cf = self.combine_fields();
|
||||
let cf = this.combine_fields();
|
||||
do cf.var_sub_var(a_vid, b_vid).then {
|
||||
Ok(VarResult(a_vid))
|
||||
}
|
||||
@ -444,12 +444,12 @@ pub fn lattice_vars<L:LatticeDir + Combine,
|
||||
pub fn lattice_var_and_t<L:LatticeDir + Combine,
|
||||
T:Copy + InferStr + LatticeValue,
|
||||
V:Copy + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
|
||||
self: &L,
|
||||
this: &L,
|
||||
a_id: V,
|
||||
b: &T,
|
||||
lattice_dir_op: LatticeDirOp<T>)
|
||||
-> cres<T> {
|
||||
let nde_a = self.infcx().get(a_id);
|
||||
let nde_a = this.infcx().get(a_id);
|
||||
let a_id = nde_a.root;
|
||||
let a_bounds = &nde_a.possible_types;
|
||||
|
||||
@ -457,24 +457,24 @@ pub fn lattice_var_and_t<L:LatticeDir + Combine,
|
||||
// apply equally well to GLB if you inverse upper/lower/sub/super/etc.
|
||||
|
||||
debug!("%s.lattice_var_and_t(%s=%s <: %s)",
|
||||
self.tag(),
|
||||
this.tag(),
|
||||
a_id.to_str(),
|
||||
a_bounds.inf_str(self.infcx()),
|
||||
b.inf_str(self.infcx()));
|
||||
a_bounds.inf_str(this.infcx()),
|
||||
b.inf_str(this.infcx()));
|
||||
|
||||
match self.bnd(a_bounds) {
|
||||
match this.bnd(a_bounds) {
|
||||
Some(ref a_bnd) => {
|
||||
// If a has an upper bound, return the LUB(a.ub, b)
|
||||
debug!("bnd=Some(%s)", a_bnd.inf_str(self.infcx()));
|
||||
debug!("bnd=Some(%s)", a_bnd.inf_str(this.infcx()));
|
||||
lattice_dir_op(a_bnd, b)
|
||||
}
|
||||
None => {
|
||||
// If a does not have an upper bound, make b the upper bound of a
|
||||
// and then return b.
|
||||
debug!("bnd=None");
|
||||
let a_bounds = self.with_bnd(a_bounds, *b);
|
||||
do self.combine_fields().bnds(&a_bounds.lb, &a_bounds.ub).then {
|
||||
self.infcx().set(a_id, Root(a_bounds, nde_a.rank));
|
||||
let a_bounds = this.with_bnd(a_bounds, *b);
|
||||
do this.combine_fields().bnds(&a_bounds.lb, &a_bounds.ub).then {
|
||||
this.infcx().set(a_id, Root(a_bounds, nde_a.rank));
|
||||
Ok(*b)
|
||||
}
|
||||
}
|
||||
@ -485,14 +485,14 @@ pub fn lattice_var_and_t<L:LatticeDir + Combine,
|
||||
// Random utility functions used by LUB/GLB when computing LUB/GLB of
|
||||
// fn types
|
||||
|
||||
pub fn var_ids<T:Combine>(self: &T, isr: isr_alist) -> ~[RegionVid] {
|
||||
pub fn var_ids<T:Combine>(this: &T, isr: isr_alist) -> ~[RegionVid] {
|
||||
let mut result = ~[];
|
||||
for list::each(isr) |pair| {
|
||||
match pair.second() {
|
||||
ty::re_infer(ty::ReVar(r)) => { result.push(r); }
|
||||
r => {
|
||||
self.infcx().tcx.sess.span_bug(
|
||||
self.span(),
|
||||
this.infcx().tcx.sess.span_bug(
|
||||
this.span(),
|
||||
fmt!("Found non-region-vid: %?", r));
|
||||
}
|
||||
}
|
||||
|
@ -149,7 +149,7 @@ impl Combine for Lub {
|
||||
a_isr, r));
|
||||
return Ok(sig1);
|
||||
|
||||
fn generalize_region(self: &Lub,
|
||||
fn generalize_region(this: &Lub,
|
||||
snapshot: uint,
|
||||
new_vars: &[RegionVid],
|
||||
a_isr: isr_alist,
|
||||
@ -160,7 +160,7 @@ impl Combine for Lub {
|
||||
return r0;
|
||||
}
|
||||
|
||||
let tainted = self.infcx.region_vars.tainted(snapshot, r0);
|
||||
let tainted = this.infcx.region_vars.tainted(snapshot, r0);
|
||||
|
||||
// Variables created during LUB computation which are
|
||||
// *related* to regions that pre-date the LUB computation
|
||||
@ -187,8 +187,8 @@ impl Combine for Lub {
|
||||
}
|
||||
}
|
||||
|
||||
self.infcx.tcx.sess.span_bug(
|
||||
self.span,
|
||||
this.infcx.tcx.sess.span_bug(
|
||||
this.span,
|
||||
fmt!("Region %? is not associated with \
|
||||
any bound region from A!", r0));
|
||||
}
|
||||
|
@ -876,7 +876,7 @@ pub impl RegionVarBindings {
|
||||
a: Region,
|
||||
b: Region,
|
||||
span: span,
|
||||
relate: &fn(self: &mut RegionVarBindings,
|
||||
relate: &fn(this: &mut RegionVarBindings,
|
||||
old_r: Region,
|
||||
new_r: Region) -> cres<()>)
|
||||
-> cres<Region> {
|
||||
@ -1103,11 +1103,11 @@ priv impl RegionVarBindings {
|
||||
Equal => ty::re_free(*a)
|
||||
};
|
||||
|
||||
fn helper(self: &RegionVarBindings,
|
||||
fn helper(this: &RegionVarBindings,
|
||||
a: &FreeRegion,
|
||||
b: &FreeRegion) -> ty::Region
|
||||
{
|
||||
let rm = self.tcx.region_maps;
|
||||
let rm = this.tcx.region_maps;
|
||||
if rm.sub_free_region(*a, *b) {
|
||||
ty::re_free(*b)
|
||||
} else if rm.sub_free_region(*b, *a) {
|
||||
@ -1198,17 +1198,17 @@ priv impl RegionVarBindings {
|
||||
Equal => Ok(ty::re_free(*a))
|
||||
};
|
||||
|
||||
fn helper(self: &RegionVarBindings,
|
||||
fn helper(this: &RegionVarBindings,
|
||||
a: &FreeRegion,
|
||||
b: &FreeRegion) -> cres<ty::Region>
|
||||
{
|
||||
let rm = self.tcx.region_maps;
|
||||
let rm = this.tcx.region_maps;
|
||||
if rm.sub_free_region(*a, *b) {
|
||||
Ok(ty::re_free(*a))
|
||||
} else if rm.sub_free_region(*b, *a) {
|
||||
Ok(ty::re_free(*b))
|
||||
} else {
|
||||
self.intersect_scopes(ty::re_free(*a), ty::re_free(*b),
|
||||
this.intersect_scopes(ty::re_free(*a), ty::re_free(*b),
|
||||
a.scope_id, b.scope_id)
|
||||
}
|
||||
}
|
||||
@ -1461,13 +1461,13 @@ pub impl RegionVarBindings {
|
||||
}
|
||||
};
|
||||
|
||||
fn check_node(self: &mut RegionVarBindings,
|
||||
fn check_node(this: &mut RegionVarBindings,
|
||||
a_vid: RegionVid,
|
||||
a_node: &mut GraphNode,
|
||||
a_region: Region,
|
||||
b_region: Region)
|
||||
-> bool {
|
||||
if !self.is_subregion_of(a_region, b_region) {
|
||||
if !this.is_subregion_of(a_region, b_region) {
|
||||
debug!("Setting %? to ErrorValue: %? not subregion of %?",
|
||||
a_vid, a_region, b_region);
|
||||
a_node.value = ErrorValue;
|
||||
@ -1475,13 +1475,13 @@ pub impl RegionVarBindings {
|
||||
false
|
||||
}
|
||||
|
||||
fn adjust_node(self: &mut RegionVarBindings,
|
||||
fn adjust_node(this: &mut RegionVarBindings,
|
||||
a_vid: RegionVid,
|
||||
a_node: &mut GraphNode,
|
||||
a_region: Region,
|
||||
b_region: Region)
|
||||
-> bool {
|
||||
match self.glb_concrete_regions(a_region, b_region) {
|
||||
match this.glb_concrete_regions(a_region, b_region) {
|
||||
Ok(glb) => {
|
||||
if glb == a_region {
|
||||
false
|
||||
@ -1744,14 +1744,14 @@ pub impl RegionVarBindings {
|
||||
let WalkState {result, dup_found, _} = state;
|
||||
return (result, dup_found);
|
||||
|
||||
fn process_edges(self: &mut RegionVarBindings,
|
||||
fn process_edges(this: &mut RegionVarBindings,
|
||||
state: &mut WalkState,
|
||||
graph: &Graph,
|
||||
source_vid: RegionVid,
|
||||
dir: Direction) {
|
||||
debug!("process_edges(source_vid=%?, dir=%?)", source_vid, dir);
|
||||
|
||||
for self.each_edge(graph, source_vid, dir) |edge| {
|
||||
for this.each_edge(graph, source_vid, dir) |edge| {
|
||||
match edge.constraint {
|
||||
ConstrainVarSubVar(from_vid, to_vid) => {
|
||||
let opp_vid =
|
||||
|
@ -267,10 +267,10 @@ pub struct binding_rscope {
|
||||
}
|
||||
|
||||
pub fn in_binding_rscope<RS:region_scope + Copy + 'static>(
|
||||
self: &RS,
|
||||
this: &RS,
|
||||
region_param_names: RegionParamNames)
|
||||
-> binding_rscope {
|
||||
let base = @copy *self;
|
||||
let base = @copy *this;
|
||||
let base = base as @region_scope;
|
||||
binding_rscope {
|
||||
base: base,
|
||||
|
@ -572,6 +572,9 @@ pub enum expr_ {
|
||||
expr_field(@expr, ident, ~[@Ty]),
|
||||
expr_index(@expr, @expr),
|
||||
expr_path(@Path),
|
||||
|
||||
/// The special identifier `self`.
|
||||
expr_self,
|
||||
expr_addr_of(mutability, @expr),
|
||||
expr_break(Option<ident>),
|
||||
expr_again(Option<ident>),
|
||||
|
@ -245,6 +245,7 @@ trait ExtCtxtMethods {
|
||||
fn expr_path(&self, span: span, strs: ~[ast::ident]) -> @ast::expr;
|
||||
fn expr_path_global(&self, span: span, strs: ~[ast::ident]) -> @ast::expr;
|
||||
fn expr_var(&self, span: span, var: &str) -> @ast::expr;
|
||||
fn expr_self(&self, span: span) -> @ast::expr;
|
||||
fn expr_field(&self, span: span, expr: @ast::expr, ident: ast::ident)
|
||||
-> @ast::expr;
|
||||
fn expr_call(&self, span: span, expr: @ast::expr, args: ~[@ast::expr])
|
||||
@ -450,6 +451,10 @@ impl ExtCtxtMethods for @ext_ctxt {
|
||||
self.expr_path(span, ~[self.ident_of(var)])
|
||||
}
|
||||
|
||||
fn expr_self(&self, span: span) -> @ast::expr {
|
||||
self.expr(span, ast::expr_self)
|
||||
}
|
||||
|
||||
fn expr_field(
|
||||
&self,
|
||||
span: span,
|
||||
@ -790,12 +795,8 @@ fn mk_struct_ser_impl(
|
||||
let expr_lambda = cx.lambda_expr_1(
|
||||
cx.expr_method_call(
|
||||
span,
|
||||
cx.expr_field(
|
||||
span,
|
||||
cx.expr_var(span, "self"),
|
||||
field.ident
|
||||
),
|
||||
cx.ident_of("encode"),
|
||||
cx.expr_field(span, cx.expr_self(span), field.ident),
|
||||
cx.ident_of(~"encode"),
|
||||
~[cx.expr_var(span, "__s")]
|
||||
),
|
||||
cx.ident_of("__s")
|
||||
@ -1062,13 +1063,10 @@ fn mk_enum_ser_body(
|
||||
// ast for `match *self { $(arms) }`
|
||||
let match_expr = cx.expr(
|
||||
span,
|
||||
ast::expr_match(
|
||||
cx.expr(
|
||||
span,
|
||||
ast::expr_unary(ast::deref, cx.expr_var(span, "self"))
|
||||
),
|
||||
arms
|
||||
)
|
||||
ast::expr_match(cx.expr(span,
|
||||
ast::expr_unary(ast::deref,
|
||||
cx.expr_self(span))),
|
||||
arms)
|
||||
);
|
||||
|
||||
// ast for `__s.emit_enum($(name), || $(match_expr))`
|
||||
|
@ -518,6 +518,10 @@ pub fn mk_unreachable_arm(cx: @ext_ctxt, span: span) -> ast::arm {
|
||||
mk_arm(cx, span, ~[mk_pat_wild(cx, span)], mk_unreachable(cx, span))
|
||||
}
|
||||
|
||||
pub fn make_self(cx: @ext_ctxt, span: span) -> @ast::expr {
|
||||
build::mk_expr(cx, span, ast::expr_self)
|
||||
}
|
||||
|
||||
//
|
||||
// Duplication functions
|
||||
//
|
||||
|
@ -204,8 +204,6 @@ fn expand_deriving_encodable_struct_method(
|
||||
type_ident: ident,
|
||||
struct_def: &struct_def
|
||||
) -> @method {
|
||||
let self_ident = cx.ident_of("self");
|
||||
|
||||
// Create the body of the method.
|
||||
let mut idx = 0;
|
||||
let mut statements = ~[];
|
||||
@ -213,12 +211,10 @@ fn expand_deriving_encodable_struct_method(
|
||||
match struct_field.node.kind {
|
||||
named_field(ident, _) => {
|
||||
// Create the accessor for this field.
|
||||
let self_field = build::mk_access(
|
||||
cx,
|
||||
span,
|
||||
~[self_ident],
|
||||
ident
|
||||
);
|
||||
let self_field = build::mk_access_(cx,
|
||||
span,
|
||||
build::make_self(cx, span),
|
||||
ident);
|
||||
|
||||
// Call the substructure method.
|
||||
let encode_expr = call_substructure_encode_method(
|
||||
|
@ -371,8 +371,7 @@ pub fn expand_enum_or_struct_match(cx: @ext_ctxt,
|
||||
span: span,
|
||||
arms: ~[ ast::arm ])
|
||||
-> @expr {
|
||||
let self_ident = cx.ident_of("self");
|
||||
let self_expr = build::mk_path(cx, span, ~[ self_ident ]);
|
||||
let self_expr = build::make_self(cx, span);
|
||||
let self_expr = build::mk_unary(cx, span, ast::deref, self_expr);
|
||||
let self_match_expr = ast::expr_match(self_expr, arms);
|
||||
build::mk_expr(cx, span, self_match_expr)
|
||||
|
@ -191,7 +191,7 @@ fn mk_generics(lifetimes: ~[ast::Lifetime], ty_params: ~[ast::TyParam]) -> Gene
|
||||
}
|
||||
}
|
||||
|
||||
/// Lifetimes and bounds on type paramers
|
||||
/// Lifetimes and bounds on type parameters
|
||||
pub struct LifetimeBounds {
|
||||
lifetimes: ~[~str],
|
||||
bounds: ~[(~str, ~[Path])]
|
||||
@ -218,7 +218,7 @@ pub impl LifetimeBounds {
|
||||
|
||||
pub fn get_explicit_self(cx: @ext_ctxt, span: span, self_ptr: Option<PtrTy>)
|
||||
-> (@expr, ast::self_ty) {
|
||||
let self_path = build::mk_path(cx, span, ~[cx.ident_of("self")]);
|
||||
let self_path = build::make_self(cx, span);
|
||||
match self_ptr {
|
||||
None => {
|
||||
(self_path, respan(span, ast::sty_value))
|
||||
|
@ -32,7 +32,7 @@ impl proto_parser for parser::Parser {
|
||||
sep: None,
|
||||
trailing_sep_allowed: false,
|
||||
},
|
||||
|self| self.parse_state(proto)
|
||||
|this| this.parse_state(proto)
|
||||
);
|
||||
|
||||
return proto;
|
||||
@ -70,7 +70,7 @@ impl proto_parser for parser::Parser {
|
||||
sep: Some(token::COMMA),
|
||||
trailing_sep_allowed: true,
|
||||
},
|
||||
|self| self.parse_message(state)
|
||||
|this| this.parse_message(state)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -524,6 +524,7 @@ pub fn noop_fold_expr(e: &expr_, fld: @ast_fold) -> expr_ {
|
||||
expr_index(fld.fold_expr(el), fld.fold_expr(er))
|
||||
}
|
||||
expr_path(pth) => expr_path(fld.fold_path(pth)),
|
||||
expr_self => expr_self,
|
||||
expr_break(ref opt_ident) => {
|
||||
expr_break(opt_ident.map(|x| fld.fold_ident(*x)))
|
||||
}
|
||||
|
@ -222,7 +222,8 @@ pub impl Parser {
|
||||
// signal an error if the given string is a strict keyword
|
||||
fn check_strict_keywords_(&self, w: &~str) {
|
||||
if self.is_strict_keyword(w) {
|
||||
self.fatal(fmt!("found `%s` in ident position", *w));
|
||||
self.span_err(*self.last_span,
|
||||
fmt!("found `%s` in ident position", *w));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -475,10 +475,12 @@ mod test {
|
||||
span:sp(0,6)})
|
||||
}
|
||||
|
||||
#[should_fail]
|
||||
// FIXME (#6416): For some reason, this fails and causes a test failure, even though it's
|
||||
// marked as `#[should_fail]`.
|
||||
/*#[should_fail]
|
||||
#[test] fn bad_path_expr_1() {
|
||||
string_to_expr(@~"::abc::def::return");
|
||||
}
|
||||
}*/
|
||||
|
||||
#[test] fn string_to_tts_1 () {
|
||||
let (tts,ps) = string_to_tts_t(@~"fn a (b : int) { b; }");
|
||||
|
@ -26,7 +26,7 @@ use ast::{expr_break, expr_call, expr_cast, expr_copy, expr_do_body};
|
||||
use ast::{expr_field, expr_fn_block, expr_if, expr_index};
|
||||
use ast::{expr_lit, expr_log, expr_loop, expr_loop_body, expr_mac};
|
||||
use ast::{expr_method_call, expr_paren, expr_path, expr_repeat};
|
||||
use ast::{expr_ret, expr_struct, expr_tup, expr_unary};
|
||||
use ast::{expr_ret, expr_self, expr_struct, expr_tup, expr_unary};
|
||||
use ast::{expr_vec, expr_vstore, expr_vstore_mut_box};
|
||||
use ast::{expr_vstore_slice, expr_vstore_box};
|
||||
use ast::{expr_vstore_mut_slice, expr_while, extern_fn, field, fn_decl};
|
||||
@ -430,8 +430,12 @@ pub impl Parser {
|
||||
lifetimes: lifetimes,
|
||||
});
|
||||
|
||||
fn parse_onceness(self: &Parser) -> Onceness {
|
||||
if self.eat_keyword(&~"once") { Once } else { Many }
|
||||
fn parse_onceness(this: &Parser) -> Onceness {
|
||||
if this.eat_keyword(&~"once") {
|
||||
Once
|
||||
} else {
|
||||
Many
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1224,6 +1228,9 @@ pub impl Parser {
|
||||
expr_block(blk));
|
||||
} else if token::is_bar(&*self.token) {
|
||||
return self.parse_lambda_expr();
|
||||
} else if self.eat_keyword(&~"self") {
|
||||
ex = expr_self;
|
||||
hi = self.span.hi;
|
||||
} else if self.eat_keyword(&~"if") {
|
||||
return self.parse_if_expr();
|
||||
} else if self.eat_keyword(&~"for") {
|
||||
@ -2984,9 +2991,7 @@ pub impl Parser {
|
||||
}
|
||||
}
|
||||
|
||||
fn maybe_parse_borrowed_self_ty(
|
||||
self: &Parser
|
||||
) -> ast::self_ty_ {
|
||||
fn maybe_parse_borrowed_self_ty(this: &Parser) -> ast::self_ty_ {
|
||||
// The following things are possible to see here:
|
||||
//
|
||||
// fn(&self)
|
||||
@ -2996,37 +3001,29 @@ pub impl Parser {
|
||||
//
|
||||
// We already know that the current token is `&`.
|
||||
|
||||
if (
|
||||
self.token_is_keyword(&~"self", &self.look_ahead(1)))
|
||||
{
|
||||
self.bump();
|
||||
self.expect_self_ident();
|
||||
if (this.token_is_keyword(&~"self", &this.look_ahead(1))) {
|
||||
this.bump();
|
||||
this.expect_self_ident();
|
||||
sty_region(None, m_imm)
|
||||
} else if (
|
||||
self.token_is_mutability(&self.look_ahead(1)) &&
|
||||
self.token_is_keyword(&~"self", &self.look_ahead(2)))
|
||||
{
|
||||
self.bump();
|
||||
let mutability = self.parse_mutability();
|
||||
self.expect_self_ident();
|
||||
} else if (this.token_is_mutability(&this.look_ahead(1)) &&
|
||||
this.token_is_keyword(&~"self", &this.look_ahead(2))) {
|
||||
this.bump();
|
||||
let mutability = this.parse_mutability();
|
||||
this.expect_self_ident();
|
||||
sty_region(None, mutability)
|
||||
} else if (
|
||||
self.token_is_lifetime(&self.look_ahead(1)) &&
|
||||
self.token_is_keyword(&~"self", &self.look_ahead(2)))
|
||||
{
|
||||
self.bump();
|
||||
let lifetime = @self.parse_lifetime();
|
||||
self.expect_self_ident();
|
||||
} else if (this.token_is_lifetime(&this.look_ahead(1)) &&
|
||||
this.token_is_keyword(&~"self", &this.look_ahead(2))) {
|
||||
this.bump();
|
||||
let lifetime = @this.parse_lifetime();
|
||||
this.expect_self_ident();
|
||||
sty_region(Some(lifetime), m_imm)
|
||||
} else if (
|
||||
self.token_is_lifetime(&self.look_ahead(1)) &&
|
||||
self.token_is_mutability(&self.look_ahead(2)) &&
|
||||
self.token_is_keyword(&~"self", &self.look_ahead(3)))
|
||||
{
|
||||
self.bump();
|
||||
let lifetime = @self.parse_lifetime();
|
||||
let mutability = self.parse_mutability();
|
||||
self.expect_self_ident();
|
||||
} else if (this.token_is_lifetime(&this.look_ahead(1)) &&
|
||||
this.token_is_mutability(&this.look_ahead(2)) &&
|
||||
this.token_is_keyword(&~"self", &this.look_ahead(3))) {
|
||||
this.bump();
|
||||
let lifetime = @this.parse_lifetime();
|
||||
let mutability = this.parse_mutability();
|
||||
this.expect_self_ident();
|
||||
sty_region(Some(lifetime), mutability)
|
||||
} else {
|
||||
sty_static
|
||||
|
@ -340,7 +340,7 @@ pub mod special_idents {
|
||||
pub static main : ident = ident { repr: 26, ctxt: 0};
|
||||
pub static opaque : ident = ident { repr: 27, ctxt: 0};
|
||||
pub static blk : ident = ident { repr: 28, ctxt: 0};
|
||||
pub static static : ident = ident { repr: 29, ctxt: 0};
|
||||
pub static statik : ident = ident { repr: 29, ctxt: 0};
|
||||
pub static intrinsic : ident = ident { repr: 30, ctxt: 0};
|
||||
pub static clownshoes_foreign_mod: ident = ident { repr: 31, ctxt: 0};
|
||||
pub static unnamed_field: ident = ident { repr: 32, ctxt: 0};
|
||||
@ -504,26 +504,17 @@ pub fn mk_fake_ident_interner() -> @ident_interner {
|
||||
*/
|
||||
pub fn keyword_table() -> HashSet<~str> {
|
||||
let mut keywords = HashSet::new();
|
||||
let mut tmp = temporary_keyword_table();
|
||||
let mut strict = strict_keyword_table();
|
||||
let mut reserved = reserved_keyword_table();
|
||||
|
||||
do tmp.consume |word| { keywords.insert(word); }
|
||||
do strict.consume |word| { keywords.insert(word); }
|
||||
do reserved.consume |word| { keywords.insert(word); }
|
||||
return keywords;
|
||||
}
|
||||
|
||||
/// Keywords that may be used as identifiers
|
||||
pub fn temporary_keyword_table() -> HashSet<~str> {
|
||||
let mut words = HashSet::new();
|
||||
let keys = ~[
|
||||
~"self", ~"static",
|
||||
];
|
||||
do vec::consume(keys) |_, s| {
|
||||
words.insert(s);
|
||||
do strict.consume |word| {
|
||||
keywords.insert(word);
|
||||
}
|
||||
return words;
|
||||
do reserved.consume |word| {
|
||||
keywords.insert(word);
|
||||
}
|
||||
|
||||
keywords
|
||||
}
|
||||
|
||||
/// Full keywords. May not appear anywhere else.
|
||||
@ -542,7 +533,7 @@ pub fn strict_keyword_table() -> HashSet<~str> {
|
||||
~"once",
|
||||
~"priv", ~"pub", ~"pure",
|
||||
~"ref", ~"return",
|
||||
~"struct", ~"super",
|
||||
~"static", ~"self", ~"struct", ~"super",
|
||||
~"true", ~"trait", ~"type",
|
||||
~"unsafe", ~"use",
|
||||
~"while"
|
||||
|
@ -1352,6 +1352,7 @@ pub fn print_expr(s: @ps, expr: @ast::expr) {
|
||||
word(s.s, ~"]");
|
||||
}
|
||||
ast::expr_path(path) => print_path(s, path, true),
|
||||
ast::expr_self => word(s.s, ~"self"),
|
||||
ast::expr_break(opt_ident) => {
|
||||
word(s.s, ~"break");
|
||||
space(s.s);
|
||||
|
@ -529,6 +529,7 @@ pub fn visit_expr<E: Copy>(ex: @expr, e: E, v: vt<E>) {
|
||||
(v.visit_expr)(b, e, v);
|
||||
}
|
||||
expr_path(p) => visit_path(p, e, v),
|
||||
expr_self => (),
|
||||
expr_break(_) => (),
|
||||
expr_again(_) => (),
|
||||
expr_ret(eo) => visit_expr_opt(eo, e, v),
|
||||
|
@ -9,6 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
trait B < A > { fn a() -> A { self.a} } //~ ERROR unresolved name
|
||||
trait B < A > { fn a() -> A { this.a } } //~ ERROR unresolved name
|
||||
|
||||
fn main() {}
|
||||
|
@ -9,7 +9,7 @@ impl Drop for S {
|
||||
pub impl S {
|
||||
fn foo(self) -> int {
|
||||
self.bar();
|
||||
return self.x; //~ ERROR use of moved value
|
||||
return self.x; //~ ERROR use of partially moved value
|
||||
}
|
||||
|
||||
fn bar(self) {}
|
||||
|
@ -5,7 +5,7 @@ struct S {
|
||||
pub impl S {
|
||||
fn foo(self) -> int {
|
||||
self.bar();
|
||||
return *self.x; //~ ERROR use of moved value
|
||||
return *self.x; //~ ERROR use of partially moved value
|
||||
}
|
||||
|
||||
fn bar(self) {}
|
||||
|
Loading…
Reference in New Issue
Block a user