Skip to content

Mut on ident patterns. #10026

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

Merged
merged 5 commits into from
Oct 27, 2013
Merged
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
2 changes: 1 addition & 1 deletion src/librustc/middle/borrowck/gather_loans/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ impl<'self> GatherLoanCtxt<'self> {
loan_mutability,
scope_r);
}
ast::BindInfer => {
ast::BindByValue(_) => {
// No borrows here, but there may be moves
if self.bccx.is_move(pat.id) {
gather_moves::gather_move_from_pat(
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -884,7 +884,7 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
BindByRef(_) => {
by_ref_span = Some(span);
}
BindInfer => {
BindByValue(_) => {
if cx.moves_map.contains(&id) {
any_by_move = true;
}
Expand Down
12 changes: 5 additions & 7 deletions src/librustc/middle/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,14 +432,12 @@ fn is_nullary_variant(cx: &Context, ex: @Expr) -> bool {

fn check_imm_free_var(cx: &Context, def: Def, sp: Span) {
match def {
DefLocal(_, is_mutbl) => {
if is_mutbl {
cx.tcx.sess.span_err(
sp,
"mutable variables cannot be implicitly captured");
}
DefLocal(_, BindByValue(MutMutable)) => {
cx.tcx.sess.span_err(
sp,
"mutable variables cannot be implicitly captured");
}
DefArg(*) => { /* ok */ }
DefLocal(*) | DefArg(*) => { /* ok */ }
DefUpvar(_, def1, _, _) => { check_imm_free_var(cx, *def1, sp); }
DefBinding(*) | DefSelf(*) => { /*ok*/ }
_ => {
Expand Down
60 changes: 19 additions & 41 deletions src/librustc/middle/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -813,27 +813,24 @@ fn check_unused_unsafe(cx: &Context, e: &ast::Expr) {
}

fn check_unused_mut_pat(cx: &Context, p: @ast::Pat) {
let mut used = false;
let mut bindings = 0;
do pat_util::pat_bindings(cx.tcx.def_map, p) |_, id, _, _| {
used = used || cx.tcx.used_mut_nodes.contains(&id);
bindings += 1;
}
if !used {
let msg = if bindings == 1 {
"variable does not need to be mutable"
} else {
"variables do not need to be mutable"
};
cx.span_lint(unused_mut, p.span, msg);
}
}

fn check_unused_mut_fn_decl(cx: &Context, fd: &ast::fn_decl) {
for arg in fd.inputs.iter() {
if arg.is_mutbl {
check_unused_mut_pat(cx, arg.pat);
match p.node {
ast::PatIdent(ast::BindByValue(ast::MutMutable), _, _) => {
let mut used = false;
let mut bindings = 0;
do pat_util::pat_bindings(cx.tcx.def_map, p) |_, id, _, _| {
used = used || cx.tcx.used_mut_nodes.contains(&id);
bindings += 1;
}
if !used {
let msg = if bindings == 1 {
"variable does not need to be mutable"
} else {
"variables do not need to be mutable"
};
cx.span_lint(unused_mut, p.span, msg);
}
}
_ => ()
}
}

Expand Down Expand Up @@ -1075,6 +1072,8 @@ impl Visitor<()> for Context {

fn visit_pat(&mut self, p: @ast::Pat, _: ()) {
check_pat_non_uppercase_statics(self, p);
check_unused_mut_pat(self, p);

visit::walk_pat(self, p, ());
}

Expand All @@ -1095,30 +1094,9 @@ impl Visitor<()> for Context {
visit::walk_stmt(self, s, ());
}

fn visit_ty_method(&mut self, tm: &ast::TypeMethod, _: ()) {
check_unused_mut_fn_decl(self, &tm.decl);
visit::walk_ty_method(self, tm, ());
}

fn visit_trait_method(&mut self, tm: &ast::trait_method, _: ()) {
match *tm {
ast::required(ref m) => check_unused_mut_fn_decl(self, &m.decl),
ast::provided(ref m) => check_unused_mut_fn_decl(self, &m.decl)
}
visit::walk_trait_method(self, tm, ());
}

fn visit_local(&mut self, l: @ast::Local, _: ()) {
if l.is_mutbl {
check_unused_mut_pat(self, l.pat);
}
visit::walk_local(self, l, ());
}

fn visit_fn(&mut self, fk: &visit::fn_kind, decl: &ast::fn_decl,
body: &ast::Block, span: Span, id: ast::NodeId, _: ()) {
let recurse = |this: &mut Context| {
check_unused_mut_fn_decl(this, decl);
visit::walk_fn(this, fk, decl, body, span, id, ());
};

Expand Down
14 changes: 11 additions & 3 deletions src/librustc/middle/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,18 +429,22 @@ fn visit_fn(v: &mut LivenessVisitor,

fn visit_local(v: &mut LivenessVisitor, local: @Local, this: @mut IrMaps) {
let def_map = this.tcx.def_map;
do pat_util::pat_bindings(def_map, local.pat) |_bm, p_id, sp, path| {
do pat_util::pat_bindings(def_map, local.pat) |bm, p_id, sp, path| {
debug!("adding local variable {}", p_id);
let name = ast_util::path_to_ident(path);
this.add_live_node_for_node(p_id, VarDefNode(sp));
let kind = match local.init {
Some(_) => FromLetWithInitializer,
None => FromLetNoInitializer
};
let mutbl = match bm {
BindByValue(MutMutable) => true,
_ => false
};
this.add_variable(Local(LocalInfo {
id: p_id,
ident: name,
is_mutbl: local.is_mutbl,
is_mutbl: mutbl,
kind: kind
}));
}
Expand All @@ -454,11 +458,15 @@ fn visit_arm(v: &mut LivenessVisitor, arm: &Arm, this: @mut IrMaps) {
debug!("adding local variable {} from match with bm {:?}",
p_id, bm);
let name = ast_util::path_to_ident(path);
let mutbl = match bm {
BindByValue(MutMutable) => true,
_ => false
};
this.add_live_node_for_node(p_id, VarDefNode(sp));
this.add_variable(Local(LocalInfo {
id: p_id,
ident: name,
is_mutbl: false,
is_mutbl: mutbl,
kind: FromMatch(bm)
}));
}
Expand Down
36 changes: 17 additions & 19 deletions src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -473,12 +473,15 @@ impl mem_categorization_ctxt {
}
}

ast::DefArg(vid, mutbl) => {
ast::DefArg(vid, binding_mode) => {
// Idea: make this could be rewritten to model by-ref
// stuff as `&const` and `&mut`?

// m: mutability of the argument
let m = if mutbl {McDeclared} else {McImmutable};
let m = match binding_mode {
ast::BindByValue(ast::MutMutable) => McDeclared,
_ => McImmutable
};
@cmt_ {
id: id,
span: span,
Expand Down Expand Up @@ -548,25 +551,20 @@ impl mem_categorization_ctxt {
}
}

ast::DefLocal(vid, mutbl) => {
let m = if mutbl {McDeclared} else {McImmutable};
@cmt_ {
id:id,
span:span,
cat:cat_local(vid),
mutbl:m,
ty:expr_ty
}
}

ast::DefBinding(vid, _) => {
ast::DefLocal(vid, binding_mode) |
ast::DefBinding(vid, binding_mode) => {
// by-value/by-ref bindings are local variables
let m = match binding_mode {
ast::BindByValue(ast::MutMutable) => McDeclared,
_ => McImmutable
};

@cmt_ {
id:id,
span:span,
cat:cat_local(vid),
mutbl:McImmutable,
ty:expr_ty
id: id,
span: span,
cat: cat_local(vid),
mutbl: m,
ty: expr_ty
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/moves.rs
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,7 @@ impl VisitContext {
do pat_bindings(self.tcx.def_map, pat) |bm, id, _span, path| {
let binding_moves = match bm {
BindByRef(_) => false,
BindInfer => {
BindByValue(_) => {
let pat_ty = ty::node_id_to_type(self.tcx, id);
debug!("pattern {:?} {} type is {}",
id,
Expand Down
19 changes: 5 additions & 14 deletions src/librustc/middle/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3817,11 +3817,8 @@ impl Resolver {
Some(declaration) => {
for argument in declaration.inputs.iter() {
let binding_mode = ArgumentIrrefutableMode;
let mutability =
if argument.is_mutbl {Mutable} else {Immutable};
this.resolve_pattern(argument.pat,
binding_mode,
mutability,
None);

this.resolve_type(&argument.ty);
Expand Down Expand Up @@ -4036,8 +4033,6 @@ impl Resolver {
}

fn resolve_local(&mut self, local: @Local) {
let mutability = if local.is_mutbl {Mutable} else {Immutable};

// Resolve the type.
self.resolve_type(&local.ty);

Expand All @@ -4052,7 +4047,7 @@ impl Resolver {
}

// Resolve the pattern.
self.resolve_pattern(local.pat, LocalIrrefutableMode, mutability, None);
self.resolve_pattern(local.pat, LocalIrrefutableMode, None);
}

// build a map from pattern identifiers to binding-info's.
Expand Down Expand Up @@ -4116,8 +4111,7 @@ impl Resolver {

let bindings_list = @mut HashMap::new();
for pattern in arm.pats.iter() {
self.resolve_pattern(*pattern, RefutableMode, Immutable,
Some(bindings_list));
self.resolve_pattern(*pattern, RefutableMode, Some(bindings_list));
}

// This has to happen *after* we determine which
Expand Down Expand Up @@ -4261,7 +4255,6 @@ impl Resolver {
fn resolve_pattern(&mut self,
pattern: @Pat,
mode: PatternBindingMode,
mutability: Mutability,
// Maps idents to the node ID for the (outermost)
// pattern that binds them
bindings_list: Option<@mut HashMap<Name,NodeId>>) {
Expand Down Expand Up @@ -4324,8 +4317,6 @@ impl Resolver {
debug!("(resolving pattern) binding `{}`",
interner_get(renamed));

let is_mutable = mutability == Mutable;

let def = match mode {
RefutableMode => {
// For pattern arms, we must use
Expand All @@ -4335,11 +4326,11 @@ impl Resolver {
}
LocalIrrefutableMode => {
// But for locals, we use `def_local`.
DefLocal(pattern.id, is_mutable)
DefLocal(pattern.id, binding_mode)
}
ArgumentIrrefutableMode => {
// And for function arguments, `def_arg`.
DefArg(pattern.id, is_mutable)
DefArg(pattern.id, binding_mode)
}
};

Expand Down Expand Up @@ -5361,7 +5352,7 @@ impl Resolver {
pat_binding_mode: BindingMode,
descr: &str) {
match pat_binding_mode {
BindInfer => {}
BindByValue(_) => {}
BindByRef(*) => {
self.resolve_error(
pat.span,
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/middle/trans/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1842,7 +1842,7 @@ fn create_bindings_map(bcx: @mut Block, pat: @ast::Pat) -> BindingsMap {
let llmatch;
let trmode;
match bm {
ast::BindInfer => {
ast::BindByValue(_) => {
// in this case, the final type of the variable will be T,
// but during matching we need to store a *T as explained
// above
Expand Down Expand Up @@ -2130,7 +2130,7 @@ fn bind_irrefutable_pat(bcx: @mut Block,
bcx, pat.id, path, binding_mode,
|bcx, variable_ty, llvariable_val| {
match pat_binding_mode {
ast::BindInfer => {
ast::BindByValue(_) => {
// By value binding: move the value that `val`
// points at into the binding's stack slot.
let datum = Datum {val: val,
Expand Down Expand Up @@ -2241,7 +2241,7 @@ fn bind_irrefutable_pat(bcx: @mut Block,

fn simple_identifier<'a>(pat: &'a ast::Pat) -> Option<&'a ast::Path> {
match pat.node {
ast::PatIdent(ast::BindInfer, ref path, None) => {
ast::PatIdent(ast::BindByValue(_), ref path, None) => {
Some(path)
}
_ => {
Expand Down
1 change: 0 additions & 1 deletion src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2100,7 +2100,6 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
// Translate variant arguments to function arguments.
let fn_args = do args.map |varg| {
ast::arg {
is_mutbl: false,
ty: (*varg.ty()).clone(),
pat: ast_util::ident_to_pat(
ccx.tcx.sess.next_node_id(),
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/typeck/check/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::Pat, expected: ty::t) {
demand::eqtype(fcx, pat.span, region_ty, typ);
}
// otherwise the type of x is the expected type T
ast::BindInfer => {
ast::BindByValue(_) => {
demand::eqtype(fcx, pat.span, expected, typ);
}
}
Expand Down
8 changes: 3 additions & 5 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,8 @@ pub enum Def {
DefMod(DefId),
DefForeignMod(DefId),
DefStatic(DefId, bool /* is_mutbl */),
DefArg(NodeId, bool /* is_mutbl */),
DefLocal(NodeId, bool /* is_mutbl */),
DefArg(NodeId, BindingMode),
DefLocal(NodeId, BindingMode),
DefVariant(DefId /* enum */, DefId /* variant */, bool /* is_structure */),
DefTy(DefId),
DefTrait(DefId),
Expand Down Expand Up @@ -324,7 +324,7 @@ pub struct FieldPat {
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
pub enum BindingMode {
BindByRef(Mutability),
BindInfer
BindByValue(Mutability),
}

#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
Expand Down Expand Up @@ -445,7 +445,6 @@ pub enum Stmt_ {
// a refinement on pat.
#[deriving(Eq, Encodable, Decodable,IterBytes)]
pub struct Local {
is_mutbl: bool,
ty: Ty,
pat: @Pat,
init: Option<@Expr>,
Expand Down Expand Up @@ -880,7 +879,6 @@ pub struct inline_asm {

#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
pub struct arg {
is_mutbl: bool,
ty: Ty,
pat: @Pat,
id: NodeId,
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/ast_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ pub fn ident_to_path(s: Span, identifier: Ident) -> Path {

pub fn ident_to_pat(id: NodeId, s: Span, i: Ident) -> @Pat {
@ast::Pat { id: id,
node: PatIdent(BindInfer, ident_to_path(s, i), None),
node: PatIdent(BindByValue(MutImmutable), ident_to_path(s, i), None),
span: s }
}

Expand Down
Loading