Skip to content

librustc: Allow moves out of self #4147

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,8 @@ impl ast::def: tr {
did2_opt.map(|did2| did2.tr(xcx)),
p)
}
ast::def_self(nid) => { ast::def_self(xcx.tr_id(nid)) }
ast::def_self_ty(nid) => { ast::def_self_ty(xcx.tr_id(nid)) }
ast::def_self(nid, i) => { ast::def_self(xcx.tr_id(nid), i) }
ast::def_mod(did) => { ast::def_mod(did.tr(xcx)) }
ast::def_foreign_mod(did) => { ast::def_foreign_mod(did.tr(xcx)) }
ast::def_const(did) => { ast::def_const(did.tr(xcx)) }
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/middle/borrowck/check_loans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,9 @@ impl check_loan_ctxt {
// rvalues, I guess.
cat_special(sk_static_item) => {}

// We allow moving out of explicit self only.
cat_special(sk_self) => {}

cat_deref(_, _, unsafe_ptr) => {}

// Nothing else.
Expand Down
4 changes: 3 additions & 1 deletion src/librustc/middle/borrowck/preserve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ priv impl &preserve_ctxt {
let _i = indenter();

match cmt.cat {
cat_special(sk_self) | cat_special(sk_heap_upvar) => {
cat_special(sk_self) |
cat_special(sk_implicit_self) |
cat_special(sk_heap_upvar) => {
self.compare_scope(cmt, ty::re_scope(self.item_ub))
}
cat_special(sk_static_item) | cat_special(sk_method) => {
Expand Down
46 changes: 32 additions & 14 deletions src/librustc/middle/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,10 @@ use core::io::WriterUtil;
use std::map::HashMap;
use syntax::ast::*;
use syntax::codemap::span;
use syntax::parse::token::special_idents;
use syntax::print::pprust::{expr_to_str, block_to_str};
use syntax::visit::vt;
use syntax::visit::{fk_anon, fk_dtor, fk_fn_block, fk_item_fn, fk_method};
use syntax::visit::{vt};
use syntax::{visit, ast_util};

export check_crate;
Expand Down Expand Up @@ -265,15 +267,15 @@ struct LocalInfo {
enum VarKind {
Arg(node_id, ident, rmode),
Local(LocalInfo),
Self,
ImplicitRet
}

fn relevant_def(def: def) -> Option<node_id> {
match def {
def_binding(nid, _) |
def_arg(nid, _) |
def_local(nid, _) => Some(nid),
def_local(nid, _) |
def_self(nid, _) => Some(nid),

_ => None
}
Expand Down Expand Up @@ -338,8 +340,7 @@ impl IrMaps {
Arg(node_id, _, _) => {
self.variable_map.insert(node_id, v);
}
Self | ImplicitRet => {
}
ImplicitRet => {}
}

debug!("%s is %?", v.to_str(), vk);
Expand All @@ -361,7 +362,6 @@ impl IrMaps {
match copy self.var_kinds[*var] {
Local(LocalInfo {ident: nm, _}) |
Arg(_, nm, _) => self.tcx.sess.str_of(nm),
Self => ~"self",
ImplicitRet => ~"<implicit-ret>"
}
}
Expand Down Expand Up @@ -404,7 +404,7 @@ impl IrMaps {
(*v).push(id);
}
Arg(_, _, by_ref) |
Arg(_, _, by_val) | Self | ImplicitRet => {
Arg(_, _, by_val) | ImplicitRet => {
debug!("--but it is not owned");
}
}
Expand Down Expand Up @@ -432,6 +432,31 @@ fn visit_fn(fk: visit::fn_kind, decl: fn_decl, body: blk,
}
};

// Add `self`, whether explicit or implicit.
match fk {
fk_method(_, _, method) => {
match method.self_ty.node {
sty_by_ref => {
fn_maps.add_variable(Arg(method.self_id,
special_idents::self_,
by_ref));
}
sty_value | sty_region(_) | sty_box(_) | sty_uniq(_) => {
fn_maps.add_variable(Arg(method.self_id,
special_idents::self_,
by_copy));
}
sty_static => {}
}
}
fk_dtor(_, _, self_id, _) => {
fn_maps.add_variable(Arg(self_id,
special_idents::self_,
by_copy));
}
fk_item_fn(*) | fk_anon(*) | fk_fn_block(*) => {}
}

// gather up the various local variables, significant expressions,
// and so forth:
visit::visit_fn(fk, decl, body, sp, id, fn_maps, v);
Expand Down Expand Up @@ -1790,13 +1815,6 @@ impl @Liveness {
copy or move mode", self.tcx.sess.str_of(name)));
return;
}
Self => {
self.tcx.sess.span_err(
move_span,
~"illegal move from self (cannot move out of a field of \
self)");
return;
}
Local(*) | ImplicitRet => {
self.tcx.sess.span_bug(
move_span,
Expand Down
17 changes: 13 additions & 4 deletions src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ enum special_kind {
sk_method,
sk_static_item,
sk_self,
sk_implicit_self, // old by-reference `self`
sk_heap_upvar
}

Expand Down Expand Up @@ -566,7 +567,7 @@ impl &mem_categorization_ctxt {
ast::def_ty(_) | ast::def_prim_ty(_) |
ast::def_ty_param(*) | ast::def_struct(*) |
ast::def_typaram_binder(*) | ast::def_region(_) |
ast::def_label(_) => {
ast::def_label(_) | ast::def_self_ty(*) => {
@{id:id, span:span,
cat:cat_special(sk_static_item), lp:None,
mutbl:m_imm, ty:expr_ty}
Expand Down Expand Up @@ -599,9 +600,15 @@ impl &mem_categorization_ctxt {
mutbl:m, ty:expr_ty}
}

ast::def_self(_) => {
ast::def_self(_, is_implicit) => {
let special_kind = if is_implicit {
sk_implicit_self
} else {
sk_self
};

@{id:id, span:span,
cat:cat_special(sk_self), lp:None,
cat:cat_special(special_kind), lp:None,
mutbl:m_imm, ty:expr_ty}
}

Expand Down Expand Up @@ -975,6 +982,7 @@ impl &mem_categorization_ctxt {
match cat {
cat_special(sk_method) => ~"method",
cat_special(sk_static_item) => ~"static_item",
cat_special(sk_implicit_self) => ~"implicit-self",
cat_special(sk_self) => ~"self",
cat_special(sk_heap_upvar) => ~"heap-upvar",
cat_stack_upvar(_) => ~"stack-upvar",
Expand Down Expand Up @@ -1053,7 +1061,8 @@ impl &mem_categorization_ctxt {
match cmt.cat {
cat_special(sk_method) => ~"method",
cat_special(sk_static_item) => ~"static item",
cat_special(sk_self) => ~"self reference",
cat_special(sk_implicit_self) => ~"self reference",
cat_special(sk_self) => ~"self value",
cat_special(sk_heap_upvar) => {
~"captured outer variable in a heap closure"
}
Expand Down
46 changes: 24 additions & 22 deletions src/librustc/middle/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,13 @@ use metadata::decoder::{def_like, dl_def, dl_field, dl_impl};
use middle::lang_items::LanguageItems;
use middle::lint::{deny, allow, forbid, level, unused_imports, warn};
use middle::pat_util::{pat_bindings};
use syntax::ast::{_mod, add, arm};
use syntax::ast::{bitand, bitor, bitxor};
use syntax::ast::{binding_mode, blk, capture_clause, struct_dtor};
use syntax::ast::{crate, crate_num, decl_item};
use syntax::ast::{def, def_arg, def_binding, def_struct, def_const, def_fn};
use syntax::ast::{def_foreign_mod, def_id, def_label, def_local, def_mod};
use syntax::ast::{def_prim_ty, def_region, def_self, def_ty, def_ty_param};
use syntax::ast::{def_typaram_binder, def_static_method};
use syntax::ast::{_mod, add, arm, binding_mode, bitand, bitor, bitxor, blk};
use syntax::ast::{capture_clause};
use syntax::ast::{crate, crate_num, decl_item, def, def_arg, def_binding};
use syntax::ast::{def_const, def_foreign_mod, def_fn, def_id, def_label};
use syntax::ast::{def_local, def_mod, def_prim_ty, def_region, def_self};
use syntax::ast::{def_self_ty, def_static_method, def_struct, def_ty};
use syntax::ast::{def_ty_param, def_typaram_binder};
use syntax::ast::{def_upvar, def_use, def_variant, expr, expr_assign_op};
use syntax::ast::{expr_binary, expr_break, expr_cast, expr_field, expr_fn};
use syntax::ast::{expr_fn_block, expr_index, expr_method_call, expr_path};
Expand All @@ -40,13 +39,13 @@ use syntax::ast::{local, local_crate, lt, method, mode, module_ns, mul, ne};
use syntax::ast::{neg, node_id, pat, pat_enum, pat_ident, path, prim_ty};
use syntax::ast::{pat_box, pat_lit, pat_range, pat_rec, pat_struct};
use syntax::ast::{pat_tup, pat_uniq, pat_wild, private, provided, public};
use syntax::ast::{required, rem, self_ty_, shl, shr, stmt_decl};
use syntax::ast::{struct_field, struct_variant_kind, sty_static, subtract};
use syntax::ast::{trait_ref, tuple_variant_kind, Ty, ty_bool, ty_char};
use syntax::ast::{ty_f, ty_f32, ty_f64, ty_float, ty_i, ty_i16, ty_i32};
use syntax::ast::{ty_i64, ty_i8, ty_int, ty_param, ty_path, ty_str, ty_u};
use syntax::ast::{ty_u16, ty_u32, ty_u64, ty_u8, ty_uint, type_value_ns};
use syntax::ast::{ty_param_bound, unnamed_field};
use syntax::ast::{required, rem, self_ty_, shl, shr, stmt_decl, struct_dtor};
use syntax::ast::{struct_field, struct_variant_kind, sty_by_ref, sty_static};
use syntax::ast::{subtract, trait_ref, tuple_variant_kind, Ty, ty_bool};
use syntax::ast::{ty_char, ty_f, ty_f32, ty_f64, ty_float, ty_i, ty_i16};
use syntax::ast::{ty_i32, ty_i64, ty_i8, ty_int, ty_param, ty_path, ty_str};
use syntax::ast::{ty_u, ty_u16, ty_u32, ty_u64, ty_u8, ty_uint};
use syntax::ast::{type_value_ns, ty_param_bound, unnamed_field};
use syntax::ast::{variant, view_item, view_item_export, view_item_import};
use syntax::ast::{view_item_use, view_path_glob, view_path_list};
use syntax::ast::{view_path_simple, visibility, anonymous, named};
Expand Down Expand Up @@ -197,7 +196,7 @@ impl Mutability : cmp::Eq {

enum SelfBinding {
NoSelfBinding,
HasSelfBinding(node_id)
HasSelfBinding(node_id, bool /* is implicit */)
}

enum CaptureClause {
Expand Down Expand Up @@ -1753,7 +1752,7 @@ impl Resolver {
def_self(*) | def_arg(*) | def_local(*) |
def_prim_ty(*) | def_ty_param(*) | def_binding(*) |
def_use(*) | def_upvar(*) | def_region(*) |
def_typaram_binder(*) | def_label(*) => {
def_typaram_binder(*) | def_label(*) | def_self_ty(*) => {
fail fmt!("didn't expect `%?`", def);
}
}
Expand Down Expand Up @@ -3724,7 +3723,7 @@ impl Resolver {
let self_type_rib = @Rib(NormalRibKind);
(*self.type_ribs).push(self_type_rib);
self_type_rib.bindings.insert(self.self_ident,
dl_def(def_self(item.id)));
dl_def(def_self_ty(item.id)));

// Create a new rib for the trait-wide type parameters.
do self.with_type_parameter_rib
Expand Down Expand Up @@ -3985,8 +3984,9 @@ impl Resolver {
NoSelfBinding => {
// Nothing to do.
}
HasSelfBinding(self_node_id) => {
let def_like = dl_def(def_self(self_node_id));
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);
}
Expand Down Expand Up @@ -4065,7 +4065,8 @@ impl Resolver {
NoTypeParameters,
(*destructor).node.body,
HasSelfBinding
((*destructor).node.self_id),
((*destructor).node.self_id,
true),
NoCaptureClause,
visitor);
}
Expand All @@ -4088,7 +4089,8 @@ impl Resolver {
// we only have self ty if it is a non static method
let self_binding = match method.self_ty.node {
sty_static => { NoSelfBinding }
_ => { HasSelfBinding(method.self_id) }
sty_by_ref => { HasSelfBinding(method.self_id, true) }
_ => { HasSelfBinding(method.self_id, false) }
};

self.resolve_function(rib_kind,
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/middle/trans/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ fn trans(bcx: block, expr: @ast::expr) -> Callee {
ast::def_mod(*) | ast::def_foreign_mod(*) |
ast::def_const(*) | ast::def_ty(*) | ast::def_prim_ty(*) |
ast::def_use(*) | ast::def_typaram_binder(*) |
ast::def_region(*) | ast::def_label(*) | ast::def_ty_param(*) => {
ast::def_region(*) | ast::def_label(*) | ast::def_ty_param(*) |
ast::def_self_ty(*) => {
bcx.tcx().sess.span_bug(
ref_expr.span,
fmt!("Cannot translate def %? \
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,7 @@ fn trans_local_var(bcx: block,
ast::def_local(nid, _) | ast::def_binding(nid, _) => {
take_local(bcx, bcx.fcx.lllocals, nid, expr_id_opt)
}
ast::def_self(nid) => {
ast::def_self(nid, _) => {
let self_info: ValSelfData = match bcx.fcx.llself {
Some(ref self_info) => *self_info,
None => {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/typeck/astconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ fn ast_ty_to_ty<AC: ast_conv, RS: region_scope Copy Owned>(
check_path_args(tcx, path, NO_TPS | NO_REGIONS);
ty::mk_param(tcx, n, id)
}
ast::def_self(_) => {
ast::def_self_ty(_) => {
// n.b.: resolve guarantees that the self type only appears in a
// trait, which we rely upon in various places when creating
// substs
Expand Down
5 changes: 4 additions & 1 deletion src/librustc/middle/typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2721,7 +2721,7 @@ fn ty_param_bounds_and_ty_for_def(fcx: @fn_ctxt, sp: span, defn: ast::def) ->

match defn {
ast::def_arg(nid, _) | ast::def_local(nid, _) |
ast::def_self(nid) | ast::def_binding(nid, _) => {
ast::def_self(nid, _) | ast::def_binding(nid, _) => {
assert (fcx.inh.locals.contains_key(nid));
let typ = ty::mk_var(fcx.ccx.tcx, lookup_local(fcx, sp, nid));
return no_params(typ);
Expand Down Expand Up @@ -2774,6 +2774,9 @@ fn ty_param_bounds_and_ty_for_def(fcx: @fn_ctxt, sp: span, defn: ast::def) ->
ast::def_label(*) => {
fcx.ccx.tcx.sess.span_bug(sp, ~"expected value but found label");
}
ast::def_self_ty(*) => {
fcx.ccx.tcx.sess.span_bug(sp, ~"expected value but found self ty");
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/typeck/check/regionck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ type rvt = visit::vt<@rcx>;
fn encl_region_of_def(fcx: @fn_ctxt, def: ast::def) -> ty::Region {
let tcx = fcx.tcx();
match def {
def_local(node_id, _) | def_arg(node_id, _) | def_self(node_id) |
def_local(node_id, _) | def_arg(node_id, _) | def_self(node_id, _) |
def_binding(node_id, _) =>
return encl_region(tcx, node_id),
def_upvar(_, subdef, closure_id, body_id) => {
Expand Down
13 changes: 10 additions & 3 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ enum def {
def_static_method(/* method */ def_id,
/* trait */ Option<def_id>,
purity),
def_self(node_id),
def_self(node_id, bool /* is_implicit */),
def_self_ty(node_id),
def_mod(def_id),
def_foreign_mod(def_id),
def_const(def_id),
Expand Down Expand Up @@ -156,9 +157,15 @@ impl def : cmp::Eq {
_ => false
}
}
def_self(e0a) => {
def_self(e0a, e1a) => {
match (*other) {
def_self(e0b) => e0a == e0b,
def_self(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
def_self_ty(e0a) => {
match (*other) {
def_self_ty(e0b) => e0a == e0b,
_ => false
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/libsyntax/ast_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ pure fn def_id_of_def(d: def) -> def_id {
def_use(id) | def_struct(id) => {
id
}
def_arg(id, _) | def_local(id, _) | def_self(id) |
def_upvar(id, _, _, _) | def_binding(id, _) | def_region(id)
def_arg(id, _) | def_local(id, _) | def_self(id, _) | def_self_ty(id)
| def_upvar(id, _, _, _) | def_binding(id, _) | def_region(id)
| def_typaram_binder(id) | def_label(id) => {
local_def(id)
}
Expand Down Expand Up @@ -384,7 +384,7 @@ impl inlined_item: inlined_item_utils {
referring to a def_self */
fn is_self(d: ast::def) -> bool {
match d {
def_self(_) => true,
def_self(*) => true,
def_upvar(_, d, _, _) => is_self(*d),
_ => false
}
Expand Down
Loading