Auto merge of #52405 - matthewjasper:mutability-errors, r=pnkfelix

[NLL] Mutability errors

cc #51028
cc #51170
cc #46559
Closes #46629

* Better explain why the place is immutable ("immutable item" is gone)
* Distinguish &T and *const T
* Use better spans when a mutable borrow is for a closure capture

r? @pnkfelix
This commit is contained in:
bors 2018-07-21 14:37:45 +00:00
commit 942b384d61
60 changed files with 1823 additions and 352 deletions

View File

@ -531,6 +531,8 @@ pub enum BindingForm<'tcx> {
Var(VarBindingForm<'tcx>),
/// Binding for a `self`/`&self`/`&mut self` binding where the type is implicit.
ImplicitSelf,
/// Reference used in a guard expression to ensure immutability.
RefForGuard,
}
CloneTypeFoldableAndLiftImpls! { BindingForm<'tcx>, }
@ -555,6 +557,7 @@ mod binding_form_impl {
match self {
Var(binding) => binding.hash_stable(hcx, hasher),
ImplicitSelf => (),
RefForGuard => (),
}
}
}

View File

@ -202,7 +202,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
/// the local assigned at `location`.
/// This is done by searching in statements succeeding `location`
/// and originating from `maybe_closure_span`.
fn find_closure_span(
pub(super) fn find_closure_span(
&self,
maybe_closure_span: Span,
location: Location,
@ -742,6 +742,24 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
autoderef,
&including_downcast,
)?;
} else if let Place::Local(local) = proj.base {
if let Some(ClearCrossCrate::Set(BindingForm::RefForGuard))
= self.mir.local_decls[local].is_user_variable {
self.append_place_to_string(
&proj.base,
buf,
autoderef,
&including_downcast,
)?;
} else {
buf.push_str(&"*");
self.append_place_to_string(
&proj.base,
buf,
autoderef,
&including_downcast,
)?;
}
} else {
buf.push_str(&"*");
self.append_place_to_string(

View File

@ -16,7 +16,7 @@ use rustc::hir::def_id::DefId;
use rustc::hir::map::definitions::DefPathData;
use rustc::infer::InferCtxt;
use rustc::lint::builtin::UNUSED_MUT;
use rustc::mir::{self, AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
use rustc::mir::{ClearCrossCrate, Local, Location, Mir, Mutability, Operand, Place};
use rustc::mir::{Field, Projection, ProjectionElem, Rvalue, Statement, StatementKind};
use rustc::mir::{Terminator, TerminatorKind};
@ -43,14 +43,13 @@ use dataflow::{do_dataflow, DebugFormatted};
use dataflow::{EverInitializedPlaces, MovingOutStatements};
use dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
use util::borrowck_errors::{BorrowckErrors, Origin};
use util::collect_writes::FindAssignments;
use util::suggest_ref_mut;
use self::borrow_set::{BorrowData, BorrowSet};
use self::flows::Flows;
use self::location::LocationTable;
use self::prefixes::PrefixSet;
use self::MutateMode::{JustWrite, WriteAndRead};
use self::mutability_errors::AccessKind;
use self::path_utils::*;
@ -58,12 +57,13 @@ crate mod borrow_set;
mod error_reporting;
mod flows;
mod location;
mod move_errors;
mod mutability_errors;
mod path_utils;
crate mod place_ext;
mod places_conflict;
mod prefixes;
mod used_muts;
mod move_errors;
pub(crate) mod nll;
@ -922,7 +922,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
}
let mutability_error =
self.check_access_permissions(place_span, rw, is_local_mutation_allowed, flow_state);
self.check_access_permissions(
place_span,
rw,
is_local_mutation_allowed,
flow_state,
context.loc,
);
let conflict_error =
self.check_access_for_conflict(context, place_span, sd, rw, flow_state);
@ -1668,6 +1674,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
}
}
/// Check the permissions for the given place and read or write kind
///
/// Returns true if an error is reported, false otherwise.
@ -1677,17 +1684,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
kind: ReadOrWrite,
is_local_mutation_allowed: LocalMutationIsAllowed,
flow_state: &Flows<'cx, 'gcx, 'tcx>,
location: Location,
) -> bool {
debug!(
"check_access_permissions({:?}, {:?}, {:?})",
place, kind, is_local_mutation_allowed
);
#[derive(Copy, Clone, Debug)]
enum AccessKind {
MutableBorrow,
Mutate,
}
let error_access;
let the_place_err;
@ -1756,206 +1759,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
}
// at this point, we have set up the error reporting state.
let mut err;
let item_msg = match self.describe_place(place) {
Some(name) => format!("immutable item `{}`", name),
None => "immutable item".to_owned(),
};
// `act` and `acted_on` are strings that let us abstract over
// the verbs used in some diagnostic messages.
let act;
let acted_on;
match error_access {
AccessKind::Mutate => {
let item_msg = match the_place_err {
Place::Projection(box Projection {
base: _,
elem: ProjectionElem::Deref,
}) => match self.describe_place(place) {
Some(description) => {
format!("`{}` which is behind a `&` reference", description)
}
None => format!("data in a `&` reference"),
},
_ => item_msg,
};
err = self.tcx.cannot_assign(span, &item_msg, Origin::Mir);
act = "assign";
acted_on = "written";
}
AccessKind::MutableBorrow => {
err = self
.tcx
.cannot_borrow_path_as_mutable(span, &item_msg, Origin::Mir);
act = "borrow as mutable";
acted_on = "borrowed as mutable";
}
}
match the_place_err {
// We want to suggest users use `let mut` for local (user
// variable) mutations...
Place::Local(local) if self.mir.local_decls[*local].can_be_made_mutable() => {
// ... but it doesn't make sense to suggest it on
// variables that are `ref x`, `ref mut x`, `&self`,
// or `&mut self` (such variables are simply not
// mutable)..
let local_decl = &self.mir.local_decls[*local];
assert_eq!(local_decl.mutability, Mutability::Not);
err.span_label(span, format!("cannot {ACT}", ACT = act));
err.span_suggestion(
local_decl.source_info.span,
"consider changing this to be mutable",
format!("mut {}", local_decl.name.unwrap()),
);
}
// complete hack to approximate old AST-borrowck
// diagnostic: if the span starts with a mutable borrow of
// a local variable, then just suggest the user remove it.
Place::Local(_)
if {
if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(span) {
snippet.starts_with("&mut ")
} else {
false
}
} =>
{
err.span_label(span, format!("cannot {ACT}", ACT = act));
err.span_label(span, "try removing `&mut` here");
}
// We want to point out when a `&` can be readily replaced
// with an `&mut`.
//
// FIXME: can this case be generalized to work for an
// arbitrary base for the projection?
Place::Projection(box Projection {
base: Place::Local(local),
elem: ProjectionElem::Deref,
}) if self.mir.local_decls[*local].is_user_variable.is_some() => {
let local_decl = &self.mir.local_decls[*local];
let suggestion = match local_decl.is_user_variable.as_ref().unwrap() {
ClearCrossCrate::Set(mir::BindingForm::ImplicitSelf) => {
Some(suggest_ampmut_self(local_decl))
},
ClearCrossCrate::Set(mir::BindingForm::Var(mir::VarBindingForm {
binding_mode: ty::BindingMode::BindByValue(_),
opt_ty_info,
..
})) => Some(suggest_ampmut(
self.tcx,
self.mir,
*local,
local_decl,
*opt_ty_info,
)),
ClearCrossCrate::Set(mir::BindingForm::Var(mir::VarBindingForm {
binding_mode: ty::BindingMode::BindByReference(_),
..
})) => suggest_ref_mut(self.tcx, local_decl.source_info.span),
ClearCrossCrate::Clear => bug!("saw cleared local state"),
};
if let Some((err_help_span, suggested_code)) = suggestion {
err.span_suggestion(
err_help_span,
"consider changing this to be a mutable reference",
suggested_code,
);
}
if let Some(name) = local_decl.name {
err.span_label(
span,
format!(
"`{NAME}` is a `&` reference, \
so the data it refers to cannot be {ACTED_ON}",
NAME = name,
ACTED_ON = acted_on
),
);
} else {
err.span_label(
span,
format!("cannot {ACT} through `&`-reference", ACT = act),
);
}
}
_ => {
err.span_label(span, format!("cannot {ACT}", ACT = act));
}
}
err.emit();
self.report_mutability_error(
place,
span,
the_place_err,
error_access,
location,
);
return true;
fn suggest_ampmut_self<'cx, 'gcx, 'tcx>(
local_decl: &mir::LocalDecl<'tcx>,
) -> (Span, String) {
(local_decl.source_info.span, "&mut self".to_string())
}
// When we want to suggest a user change a local variable to be a `&mut`, there
// are three potential "obvious" things to highlight:
//
// let ident [: Type] [= RightHandSideExpression];
// ^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^
// (1.) (2.) (3.)
//
// We can always fallback on highlighting the first. But chances are good that
// the user experience will be better if we highlight one of the others if possible;
// for example, if the RHS is present and the Type is not, then the type is going to
// be inferred *from* the RHS, which means we should highlight that (and suggest
// that they borrow the RHS mutably).
//
// This implementation attempts to emulate AST-borrowck prioritization
// by trying (3.), then (2.) and finally falling back on (1.).
fn suggest_ampmut<'cx, 'gcx, 'tcx>(
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
mir: &Mir<'tcx>,
local: Local,
local_decl: &mir::LocalDecl<'tcx>,
opt_ty_info: Option<Span>,
) -> (Span, String) {
let locations = mir.find_assignments(local);
if locations.len() > 0 {
let assignment_rhs_span = mir.source_info(locations[0]).span;
let snippet = tcx.sess.codemap().span_to_snippet(assignment_rhs_span);
if let Ok(src) = snippet {
if src.starts_with('&') {
let borrowed_expr = src[1..].to_string();
return (
assignment_rhs_span,
format!("&mut {}", borrowed_expr),
);
}
}
}
let highlight_span = match opt_ty_info {
// if this is a variable binding with an explicit type,
// try to highlight that for the suggestion.
Some(ty_span) => ty_span,
// otherwise, just highlight the span associated with
// the (MIR) LocalDecl.
None => local_decl.source_info.span,
};
let ty_mut = local_decl.ty.builtin_deref(true).unwrap();
assert_eq!(ty_mut.mutbl, hir::MutImmutable);
(highlight_span, format!("&mut {}", ty_mut.ty))
}
}
/// Adds the place into the used mutable variables set

View File

@ -0,0 +1,469 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use rustc::hir;
use rustc::mir::{self, BindingForm, ClearCrossCrate, Local, Location, Mir};
use rustc::mir::{Mutability, Place, Projection, ProjectionElem, Static};
use rustc::ty::{self, TyCtxt};
use rustc_data_structures::indexed_vec::Idx;
use syntax_pos::Span;
use borrow_check::MirBorrowckCtxt;
use util::borrowck_errors::{BorrowckErrors, Origin};
use util::collect_writes::FindAssignments;
use util::suggest_ref_mut;
#[derive(Copy, Clone, Debug)]
pub(super) enum AccessKind {
MutableBorrow,
Mutate,
}
impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
pub(super) fn report_mutability_error(
&mut self,
access_place: &Place<'tcx>,
span: Span,
the_place_err: &Place<'tcx>,
error_access: AccessKind,
location: Location,
) {
let mut err;
let item_msg;
let reason;
let access_place_desc = self.describe_place(access_place);
match the_place_err {
Place::Local(local) => {
item_msg = format!("`{}`", access_place_desc.unwrap());
if let Place::Local(_) = access_place {
reason = ", as it is not declared as mutable".to_string();
} else {
let name = self.mir.local_decls[*local]
.name
.expect("immutable unnamed local");
reason = format!(", as `{}` is not declared as mutable", name);
}
}
Place::Projection(box Projection {
base,
elem: ProjectionElem::Field(upvar_index, _),
}) => {
debug_assert!(is_closure_or_generator(
base.ty(self.mir, self.tcx).to_ty(self.tcx)
));
item_msg = format!("`{}`", access_place_desc.unwrap());
if self.is_upvar(access_place) {
reason = ", as it is not declared as mutable".to_string();
} else {
let name = self.mir.upvar_decls[upvar_index.index()].debug_name;
reason = format!(", as `{}` is not declared as mutable", name);
}
}
Place::Projection(box Projection {
base,
elem: ProjectionElem::Deref,
}) => {
if *base == Place::Local(Local::new(1)) && !self.mir.upvar_decls.is_empty() {
item_msg = format!("`{}`", access_place_desc.unwrap());
debug_assert!(self.mir.local_decls[Local::new(1)].ty.is_region_ptr());
debug_assert!(is_closure_or_generator(
the_place_err.ty(self.mir, self.tcx).to_ty(self.tcx)
));
reason = if self.is_upvar(access_place) {
", as it is a captured variable in a `Fn` closure".to_string()
} else {
format!(", as `Fn` closures cannot mutate their captured variables")
}
} else if {
if let Place::Local(local) = *base {
if let Some(ClearCrossCrate::Set(BindingForm::RefForGuard))
= self.mir.local_decls[local].is_user_variable {
true
} else {
false
}
} else {
false
}
} {
item_msg = format!("`{}`", access_place_desc.unwrap());
reason = format!(", as it is immutable for the pattern guard");
} else {
let pointer_type =
if base.ty(self.mir, self.tcx).to_ty(self.tcx).is_region_ptr() {
"`&` reference"
} else {
"`*const` pointer"
};
if let Some(desc) = access_place_desc {
item_msg = format!("`{}`", desc);
reason = match error_access {
AccessKind::Mutate => format!(" which is behind a {}", pointer_type),
AccessKind::MutableBorrow => {
format!(", as it is behind a {}", pointer_type)
}
}
} else {
item_msg = format!("data in a {}", pointer_type);
reason = "".to_string();
}
}
}
Place::Static(box Static { def_id, ty: _ }) => {
if let Place::Static(_) = access_place {
item_msg = format!("immutable static item `{}`", access_place_desc.unwrap());
reason = "".to_string();
} else {
item_msg = format!("`{}`", access_place_desc.unwrap());
let static_name = &self.tcx.item_name(*def_id);
reason = format!(", as `{}` is an immutable static item", static_name);
}
}
Place::Projection(box Projection {
base: _,
elem: ProjectionElem::Index(_),
})
| Place::Projection(box Projection {
base: _,
elem: ProjectionElem::ConstantIndex { .. },
})
| Place::Projection(box Projection {
base: _,
elem: ProjectionElem::Subslice { .. },
})
| Place::Projection(box Projection {
base: _,
elem: ProjectionElem::Downcast(..),
}) => bug!("Unexpected immutable place."),
}
// `act` and `acted_on` are strings that let us abstract over
// the verbs used in some diagnostic messages.
let act;
let acted_on;
let span = match error_access {
AccessKind::Mutate => {
err = self.tcx
.cannot_assign(span, &(item_msg + &reason), Origin::Mir);
act = "assign";
acted_on = "written";
span
}
AccessKind::MutableBorrow => {
act = "borrow as mutable";
acted_on = "borrowed as mutable";
let closure_span = self.find_closure_span(span, location);
if let Some((args, var)) = closure_span {
err = self.tcx.cannot_borrow_path_as_mutable_because(
args,
&item_msg,
&reason,
Origin::Mir,
);
err.span_label(
var,
format!(
"mutable borrow occurs due to use of `{}` in closure",
self.describe_place(access_place).unwrap(),
),
);
args
} else {
err = self.tcx.cannot_borrow_path_as_mutable_because(
span,
&item_msg,
&reason,
Origin::Mir,
);
span
}
}
};
match the_place_err {
// We want to suggest users use `let mut` for local (user
// variable) mutations...
Place::Local(local) if self.mir.local_decls[*local].can_be_made_mutable() => {
// ... but it doesn't make sense to suggest it on
// variables that are `ref x`, `ref mut x`, `&self`,
// or `&mut self` (such variables are simply not
// mutable).
let local_decl = &self.mir.local_decls[*local];
assert_eq!(local_decl.mutability, Mutability::Not);
err.span_label(span, format!("cannot {ACT}", ACT = act));
err.span_suggestion(
local_decl.source_info.span,
"consider changing this to be mutable",
format!("mut {}", local_decl.name.unwrap()),
);
}
// Also suggest adding mut for upvars
Place::Projection(box Projection {
base,
elem: ProjectionElem::Field(upvar_index, _),
}) => {
debug_assert!(is_closure_or_generator(
base.ty(self.mir, self.tcx).to_ty(self.tcx)
));
err.span_label(span, format!("cannot {ACT}", ACT = act));
let upvar_hir_id = self.mir.upvar_decls[upvar_index.index()]
.var_hir_id
.assert_crate_local();
let upvar_node_id = self.tcx.hir.hir_to_node_id(upvar_hir_id);
if let Some(hir::map::NodeBinding(pat)) = self.tcx.hir.find(upvar_node_id) {
if let hir::PatKind::Binding(
hir::BindingAnnotation::Unannotated,
_,
upvar_ident,
_,
) = pat.node
{
err.span_suggestion(
upvar_ident.span,
"consider changing this to be mutable",
format!("mut {}", upvar_ident.name),
);
}
}
}
// complete hack to approximate old AST-borrowck
// diagnostic: if the span starts with a mutable borrow of
// a local variable, then just suggest the user remove it.
Place::Local(_)
if {
if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(span) {
snippet.starts_with("&mut ")
} else {
false
}
} =>
{
err.span_label(span, format!("cannot {ACT}", ACT = act));
err.span_label(span, "try removing `&mut` here");
}
Place::Projection(box Projection {
base: Place::Local(local),
elem: ProjectionElem::Deref,
}) if {
if let Some(ClearCrossCrate::Set(BindingForm::RefForGuard)) =
self.mir.local_decls[*local].is_user_variable
{
true
} else {
false
}
} =>
{
err.span_label(span, format!("cannot {ACT}", ACT = act));
err.note(
"variables bound in patterns are immutable until the end of the pattern guard",
);
}
// We want to point out when a `&` can be readily replaced
// with an `&mut`.
//
// FIXME: can this case be generalized to work for an
// arbitrary base for the projection?
Place::Projection(box Projection {
base: Place::Local(local),
elem: ProjectionElem::Deref,
}) if self.mir.local_decls[*local].is_user_variable.is_some() =>
{
let local_decl = &self.mir.local_decls[*local];
let suggestion = match local_decl.is_user_variable.as_ref().unwrap() {
ClearCrossCrate::Set(mir::BindingForm::ImplicitSelf) => {
Some(suggest_ampmut_self(local_decl))
}
ClearCrossCrate::Set(mir::BindingForm::Var(mir::VarBindingForm {
binding_mode: ty::BindingMode::BindByValue(_),
opt_ty_info,
..
})) => Some(suggest_ampmut(
self.tcx,
self.mir,
*local,
local_decl,
*opt_ty_info,
)),
ClearCrossCrate::Set(mir::BindingForm::Var(mir::VarBindingForm {
binding_mode: ty::BindingMode::BindByReference(_),
..
})) => suggest_ref_mut(self.tcx, local_decl.source_info.span),
//
ClearCrossCrate::Set(mir::BindingForm::RefForGuard) => unreachable!(),
ClearCrossCrate::Clear => bug!("saw cleared local state"),
};
let (pointer_sigil, pointer_desc) = if local_decl.ty.is_region_ptr() {
("&", "reference")
} else {
("*const", "pointer")
};
if let Some((err_help_span, suggested_code)) = suggestion {
err.span_suggestion(
err_help_span,
&format!("consider changing this to be a mutable {}", pointer_desc),
suggested_code,
);
}
if let Some(name) = local_decl.name {
err.span_label(
span,
format!(
"`{NAME}` is a `{SIGIL}` {DESC}, \
so the data it refers to cannot be {ACTED_ON}",
NAME = name,
SIGIL = pointer_sigil,
DESC = pointer_desc,
ACTED_ON = acted_on
),
);
} else {
err.span_label(
span,
format!(
"cannot {ACT} through `{SIGIL}` {DESC}",
ACT = act,
SIGIL = pointer_sigil,
DESC = pointer_desc
),
);
}
}
Place::Projection(box Projection {
base,
elem: ProjectionElem::Deref,
}) if *base == Place::Local(Local::new(1)) && !self.mir.upvar_decls.is_empty() =>
{
err.span_label(span, format!("cannot {ACT}", ACT = act));
err.span_help(
self.mir.span,
"consider changing this to accept closures that implement `FnMut`"
);
}
_ => {
err.span_label(span, format!("cannot {ACT}", ACT = act));
}
}
err.emit();
}
// Does this place refer to what the user sees as an upvar
fn is_upvar(&self, place: &Place<'tcx>) -> bool {
match *place {
Place::Projection(box Projection {
ref base,
elem: ProjectionElem::Field(_, _),
}) => {
let base_ty = base.ty(self.mir, self.tcx).to_ty(self.tcx);
is_closure_or_generator(base_ty)
}
Place::Projection(box Projection {
base:
Place::Projection(box Projection {
ref base,
elem: ProjectionElem::Field(upvar_index, _),
}),
elem: ProjectionElem::Deref,
}) => {
let base_ty = base.ty(self.mir, self.tcx).to_ty(self.tcx);
is_closure_or_generator(base_ty) && self.mir.upvar_decls[upvar_index.index()].by_ref
}
_ => false,
}
}
}
fn suggest_ampmut_self<'cx, 'gcx, 'tcx>(local_decl: &mir::LocalDecl<'tcx>) -> (Span, String) {
(local_decl.source_info.span, "&mut self".to_string())
}
// When we want to suggest a user change a local variable to be a `&mut`, there
// are three potential "obvious" things to highlight:
//
// let ident [: Type] [= RightHandSideExpression];
// ^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^
// (1.) (2.) (3.)
//
// We can always fallback on highlighting the first. But chances are good that
// the user experience will be better if we highlight one of the others if possible;
// for example, if the RHS is present and the Type is not, then the type is going to
// be inferred *from* the RHS, which means we should highlight that (and suggest
// that they borrow the RHS mutably).
//
// This implementation attempts to emulate AST-borrowck prioritization
// by trying (3.), then (2.) and finally falling back on (1.).
fn suggest_ampmut<'cx, 'gcx, 'tcx>(
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
mir: &Mir<'tcx>,
local: Local,
local_decl: &mir::LocalDecl<'tcx>,
opt_ty_info: Option<Span>,
) -> (Span, String) {
let locations = mir.find_assignments(local);
if locations.len() > 0 {
let assignment_rhs_span = mir.source_info(locations[0]).span;
let snippet = tcx.sess.codemap().span_to_snippet(assignment_rhs_span);
if let Ok(src) = snippet {
if src.starts_with('&') {
let borrowed_expr = src[1..].to_string();
return (assignment_rhs_span, format!("&mut {}", borrowed_expr));
}
}
}
let highlight_span = match opt_ty_info {
// if this is a variable binding with an explicit type,
// try to highlight that for the suggestion.
Some(ty_span) => ty_span,
// otherwise, just highlight the span associated with
// the (MIR) LocalDecl.
None => local_decl.source_info.span,
};
let ty_mut = local_decl.ty.builtin_deref(true).unwrap();
assert_eq!(ty_mut.mutbl, hir::MutImmutable);
if local_decl.ty.is_region_ptr() {
(highlight_span, format!("&mut {}", ty_mut.ty))
} else {
(highlight_span, format!("*mut {}", ty_mut.ty))
}
}
fn is_closure_or_generator(ty: ty::Ty) -> bool {
ty.is_closure() || ty.is_generator()
}

View File

@ -206,7 +206,27 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
this.consume_by_copy_or_move(place)
}
_ => {
unpack!(block = this.as_operand(block, scope, upvar))
// Turn mutable borrow captures into unique
// borrow captures when capturing an immutable
// variable. This is sound because the mutation
// that caused the capture will cause an error.
match upvar.kind {
ExprKind::Borrow {
borrow_kind: BorrowKind::Mut {
allow_two_phase_borrow: false
},
region,
arg,
} => unpack!(block = this.limit_capture_mutability(
upvar.span,
upvar.ty,
scope,
block,
arg,
region,
)),
_ => unpack!(block = this.as_operand(block, scope, upvar)),
}
}
}
})
@ -393,6 +413,101 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
}
}
fn limit_capture_mutability(
&mut self,
upvar_span: Span,
upvar_ty: Ty<'tcx>,
temp_lifetime: Option<region::Scope>,
mut block: BasicBlock,
arg: ExprRef<'tcx>,
region: &'tcx ty::RegionKind,
) -> BlockAnd<Operand<'tcx>> {
let this = self;
let source_info = this.source_info(upvar_span);
let temp = this.local_decls.push(LocalDecl::new_temp(upvar_ty, upvar_span));
this.cfg.push(block, Statement {
source_info,
kind: StatementKind::StorageLive(temp)
});
let arg_place = unpack!(block = this.as_place(block, arg));
let mutability = match arg_place {
Place::Local(local) => this.local_decls[local].mutability,
Place::Projection(box Projection {
base: Place::Local(local),
elem: ProjectionElem::Deref,
}) => {
debug_assert!(
if let Some(ClearCrossCrate::Set(BindingForm::RefForGuard))
= this.local_decls[local].is_user_variable {
true
} else {
false
},
"Unexpected capture place",
);
this.local_decls[local].mutability
}
Place::Projection(box Projection {
ref base,
elem: ProjectionElem::Field(upvar_index, _),
})
| Place::Projection(box Projection {
base: Place::Projection(box Projection {
ref base,
elem: ProjectionElem::Field(upvar_index, _),
}),
elem: ProjectionElem::Deref,
}) => {
// Not projected from the implicit `self` in a closure.
debug_assert!(
match *base {
Place::Local(local) => local == Local::new(1),
Place::Projection(box Projection {
ref base,
elem: ProjectionElem::Deref,
}) => *base == Place::Local(Local::new(1)),
_ => false,
},
"Unexpected capture place"
);
// Not in a closure
debug_assert!(
this.upvar_decls.len() > upvar_index.index(),
"Unexpected capture place"
);
this.upvar_decls[upvar_index.index()].mutability
}
_ => bug!("Unexpected capture place"),
};
let borrow_kind = match mutability {
Mutability::Not => BorrowKind::Unique,
Mutability::Mut => BorrowKind::Mut { allow_two_phase_borrow: false },
};
this.cfg.push_assign(
block,
source_info,
&Place::Local(temp),
Rvalue::Ref(region, borrow_kind, arg_place),
);
// In constants, temp_lifetime is None. We should not need to drop
// anything because no values with a destructor can be created in
// a constant at this time, even if the type may need dropping.
if let Some(temp_lifetime) = temp_lifetime {
this.schedule_drop_storage_and_value(
upvar_span, temp_lifetime, &Place::Local(temp), upvar_ty,
);
}
block.and(Operand::Move(Place::Local(temp)))
}
// Helper to get a `-1` value of the appropriate type
fn neg_1_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> {
let param_ty = ty::ParamEnv::empty().and(self.hir.tcx().lift_to_global(&ty).unwrap());

View File

@ -1198,7 +1198,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
visibility_scope,
// FIXME: should these secretly injected ref_for_guard's be marked as `internal`?
internal: false,
is_user_variable: None,
is_user_variable: Some(ClearCrossCrate::Set(BindingForm::RefForGuard)),
});
LocalsForNode::Three { val_for_guard, ref_for_guard, for_arm_body }
} else {

View File

@ -286,6 +286,7 @@ struct Builder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
/// (A match binding can have two locals; the 2nd is for the arm's guard.)
var_indices: NodeMap<LocalsForNode>,
local_decls: IndexVec<Local, LocalDecl<'tcx>>,
upvar_decls: Vec<UpvarDecl>,
unit_temp: Option<Place<'tcx>>,
/// cached block with the RESUME terminator; this is created
@ -472,11 +473,52 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
let tcx = hir.tcx();
let span = tcx.hir.span(fn_id);
// Gather the upvars of a closure, if any.
let upvar_decls: Vec<_> = tcx.with_freevars(fn_id, |freevars| {
freevars.iter().map(|fv| {
let var_id = fv.var_id();
let var_hir_id = tcx.hir.node_to_hir_id(var_id);
let closure_expr_id = tcx.hir.local_def_id(fn_id);
let capture = hir.tables().upvar_capture(ty::UpvarId {
var_id: var_hir_id,
closure_expr_id: LocalDefId::from_def_id(closure_expr_id),
});
let by_ref = match capture {
ty::UpvarCapture::ByValue => false,
ty::UpvarCapture::ByRef(..) => true
};
let mut decl = UpvarDecl {
debug_name: keywords::Invalid.name(),
var_hir_id: ClearCrossCrate::Set(var_hir_id),
by_ref,
mutability: Mutability::Not,
};
if let Some(hir::map::NodeBinding(pat)) = tcx.hir.find(var_id) {
if let hir::PatKind::Binding(_, _, ident, _) = pat.node {
decl.debug_name = ident.name;
if let Some(&bm) = hir.tables.pat_binding_modes().get(pat.hir_id) {
if bm == ty::BindByValue(hir::MutMutable) {
decl.mutability = Mutability::Mut;
} else {
decl.mutability = Mutability::Not;
}
} else {
tcx.sess.delay_span_bug(pat.span, "missing binding mode");
}
}
}
decl
}).collect()
});
let mut builder = Builder::new(hir.clone(),
span,
arguments.len(),
safety,
return_ty);
return_ty,
upvar_decls);
let fn_def_id = tcx.hir.local_def_id(fn_id);
let call_site_scope = region::Scope::CallSite(body.value.hir_id.local_id);
@ -519,46 +561,7 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
info!("fn_id {:?} has attrs {:?}", closure_expr_id,
tcx.get_attrs(closure_expr_id));
// Gather the upvars of a closure, if any.
let upvar_decls: Vec<_> = tcx.with_freevars(fn_id, |freevars| {
freevars.iter().map(|fv| {
let var_id = fv.var_id();
let var_hir_id = tcx.hir.node_to_hir_id(var_id);
let closure_expr_id = tcx.hir.local_def_id(fn_id);
let capture = hir.tables().upvar_capture(ty::UpvarId {
var_id: var_hir_id,
closure_expr_id: LocalDefId::from_def_id(closure_expr_id),
});
let by_ref = match capture {
ty::UpvarCapture::ByValue => false,
ty::UpvarCapture::ByRef(..) => true
};
let mut decl = UpvarDecl {
debug_name: keywords::Invalid.name(),
var_hir_id: ClearCrossCrate::Set(var_hir_id),
by_ref,
mutability: Mutability::Not,
};
if let Some(hir::map::NodeBinding(pat)) = tcx.hir.find(var_id) {
if let hir::PatKind::Binding(_, _, ident, _) = pat.node {
decl.debug_name = ident.name;
if let Some(&bm) = hir.tables.pat_binding_modes().get(pat.hir_id) {
if bm == ty::BindByValue(hir::MutMutable) {
decl.mutability = Mutability::Mut;
} else {
decl.mutability = Mutability::Not;
}
} else {
tcx.sess.delay_span_bug(pat.span, "missing binding mode");
}
}
}
decl
}).collect()
});
let mut mir = builder.finish(upvar_decls, yield_ty);
let mut mir = builder.finish(yield_ty);
mir.spread_arg = spread_arg;
mir
}
@ -571,7 +574,7 @@ fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
let ty = hir.tables().expr_ty_adjusted(ast_expr);
let owner_id = tcx.hir.body_owner(body_id);
let span = tcx.hir.span(owner_id);
let mut builder = Builder::new(hir.clone(), span, 0, Safety::Safe, ty);
let mut builder = Builder::new(hir.clone(), span, 0, Safety::Safe, ty, vec![]);
let mut block = START_BLOCK;
let expr = builder.hir.mirror(ast_expr);
@ -590,7 +593,7 @@ fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
TerminatorKind::Unreachable);
}
builder.finish(vec![], None)
builder.finish(None)
}
fn construct_error<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
@ -599,10 +602,10 @@ fn construct_error<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
let owner_id = hir.tcx().hir.body_owner(body_id);
let span = hir.tcx().hir.span(owner_id);
let ty = hir.tcx().types.err;
let mut builder = Builder::new(hir, span, 0, Safety::Safe, ty);
let mut builder = Builder::new(hir, span, 0, Safety::Safe, ty, vec![]);
let source_info = builder.source_info(span);
builder.cfg.terminate(START_BLOCK, source_info, TerminatorKind::Unreachable);
builder.finish(vec![], None)
builder.finish(None)
}
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
@ -610,7 +613,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
span: Span,
arg_count: usize,
safety: Safety,
return_ty: Ty<'tcx>)
return_ty: Ty<'tcx>,
upvar_decls: Vec<UpvarDecl>)
-> Builder<'a, 'gcx, 'tcx> {
let lint_level = LintLevel::Explicit(hir.root_lint_level);
let mut builder = Builder {
@ -628,6 +632,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
breakable_scopes: vec![],
local_decls: IndexVec::from_elem_n(LocalDecl::new_return_place(return_ty,
span), 1),
upvar_decls,
var_indices: NodeMap(),
unit_temp: None,
cached_resume_block: None,
@ -645,7 +650,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
}
fn finish(self,
upvar_decls: Vec<UpvarDecl>,
yield_ty: Option<Ty<'tcx>>)
-> Mir<'tcx> {
for (index, block) in self.cfg.basic_blocks.iter().enumerate() {
@ -661,7 +665,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
yield_ty,
self.local_decls,
self.arg_count,
upvar_decls,
self.upvar_decls,
self.fn_span
)
}

View File

@ -519,24 +519,35 @@ pub trait BorrowckErrors<'cx>: Sized + Copy {
self.cancel_if_wrong_origin(err, o)
}
fn cannot_borrow_path_as_mutable(
fn cannot_borrow_path_as_mutable_because(
self,
span: Span,
path: &str,
reason: &str,
o: Origin,
) -> DiagnosticBuilder<'cx> {
let err = struct_span_err!(
self,
span,
E0596,
"cannot borrow {} as mutable{OGN}",
"cannot borrow {} as mutable{}{OGN}",
path,
OGN = o
reason,
OGN = o,
);
self.cancel_if_wrong_origin(err, o)
}
fn cannot_borrow_path_as_mutable(
self,
span: Span,
path: &str,
o: Origin,
) -> DiagnosticBuilder<'cx> {
self.cannot_borrow_path_as_mutable_because(span, path, "", o)
}
fn cannot_borrow_across_generator_yield(
self,
span: Span,

View File

@ -15,5 +15,5 @@ static NUM: i32 = 18;
fn main() {
NUM = 20; //[ast]~ ERROR E0594
//[mir]~^ ERROR cannot assign to immutable item `NUM`
//[mir]~^ ERROR cannot assign to immutable static item `NUM`
}

View File

@ -16,5 +16,5 @@ static foo: isize = 5;
fn main() {
// assigning to various global constants
foo = 6; //[ast]~ ERROR cannot assign to immutable static item
//[mir]~^ ERROR cannot assign to immutable item `foo`
//[mir]~^ ERROR cannot assign to immutable static item `foo`
}

View File

@ -22,10 +22,10 @@ fn main() {
let x = 1;
to_fn_once(move|| { x = 2; });
//[ast]~^ ERROR: cannot assign to immutable captured outer variable
//[mir]~^^ ERROR: cannot assign to immutable item `x`
//[mir]~^^ ERROR: cannot assign to `x`, as it is not declared as mutable
let s = std::io::stdin();
to_fn_once(move|| { s.read_to_end(&mut Vec::new()); });
//[ast]~^ ERROR: cannot borrow immutable captured outer variable
//[mir]~^^ ERROR: cannot borrow immutable item `s` as mutable
//[mir]~^^ ERROR: cannot borrow `s` as mutable, as it is not declared as mutable
}

View File

@ -17,5 +17,5 @@
static FOO: isize = 5;
fn main() {
FOO = 6; //~ ERROR cannot assign to immutable item `FOO` [E0594]
FOO = 6; //~ ERROR cannot assign to immutable static item `FOO` [E0594]
}

View File

@ -14,7 +14,7 @@ LL | | x; //~ value moved here
| |_____move out of `x` occurs here
| borrow later used here
error[E0596]: cannot borrow immutable item `y` as mutable
error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable
--> $DIR/augmented-assignments.rs:30:5
|
LL | let y = Int(2);

View File

@ -14,21 +14,14 @@ LL | give_any(|y| x = Some(y));
| |
| lifetime `'1` appears in this argument
error[E0594]: cannot assign to immutable item `x`
error[E0594]: cannot assign to `x`, as it is not declared as mutable
--> $DIR/issue-45983.rs:17:18
|
LL | give_any(|y| x = Some(y));
| ^^^^^^^^^^^ cannot assign
error[E0596]: cannot borrow immutable item `x` as mutable
--> $DIR/issue-45983.rs:17:14
|
LL | let x = None;
| - help: consider changing this to be mutable: `mut x`
LL | give_any(|y| x = Some(y));
| ^^^^^^^^^^^^^^^ cannot borrow as mutable
| ^^^^^^^^^^^ cannot assign
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
Some errors occurred: E0594, E0596.
For more information about an error, try `rustc --explain E0594`.
For more information about this error, try `rustc --explain E0594`.

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item `b` as mutable
error[E0596]: cannot borrow `b` as mutable, as it is not declared as mutable
--> $DIR/mut-borrow-of-mut-ref.rs:18:7
|
LL | fn f(b: &mut i32) {

View File

@ -0,0 +1,379 @@
error[E0594]: cannot assign to `*x` which is behind a `&` reference
--> $DIR/mutability-errors.rs:19:5
|
LL | fn named_ref(x: &(i32,)) {
| ------- help: consider changing this to be a mutable reference: `&mut (i32,)`
LL | *x = (1,); //~ ERROR
| ^^^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written
error[E0594]: cannot assign to `x.0` which is behind a `&` reference
--> $DIR/mutability-errors.rs:20:5
|
LL | fn named_ref(x: &(i32,)) {
| ------- help: consider changing this to be a mutable reference: `&mut (i32,)`
LL | *x = (1,); //~ ERROR
LL | x.0 = 1; //~ ERROR
| ^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
--> $DIR/mutability-errors.rs:21:5
|
LL | fn named_ref(x: &(i32,)) {
| ------- help: consider changing this to be a mutable reference: `&mut (i32,)`
...
LL | &mut *x; //~ ERROR
| ^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow `x.0` as mutable, as it is behind a `&` reference
--> $DIR/mutability-errors.rs:22:5
|
LL | fn named_ref(x: &(i32,)) {
| ------- help: consider changing this to be a mutable reference: `&mut (i32,)`
...
LL | &mut x.0; //~ ERROR
| ^^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0594]: cannot assign to data in a `&` reference
--> $DIR/mutability-errors.rs:26:5
|
LL | *f() = (1,); //~ ERROR
| ^^^^^^^^^^^ cannot assign
error[E0594]: cannot assign to data in a `&` reference
--> $DIR/mutability-errors.rs:27:5
|
LL | f().0 = 1; //~ ERROR
| ^^^^^^^^^ cannot assign
error[E0596]: cannot borrow data in a `&` reference as mutable
--> $DIR/mutability-errors.rs:28:5
|
LL | &mut *f(); //~ ERROR
| ^^^^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow data in a `&` reference as mutable
--> $DIR/mutability-errors.rs:29:5
|
LL | &mut f().0; //~ ERROR
| ^^^^^^^^^^ cannot borrow as mutable
error[E0594]: cannot assign to `*x` which is behind a `*const` pointer
--> $DIR/mutability-errors.rs:33:5
|
LL | unsafe fn named_ptr(x: *const (i32,)) {
| ------------- help: consider changing this to be a mutable pointer: `*mut (i32,)`
LL | *x = (1,); //~ ERROR
| ^^^^^^^^^ `x` is a `*const` pointer, so the data it refers to cannot be written
error[E0594]: cannot assign to `x.0` which is behind a `*const` pointer
--> $DIR/mutability-errors.rs:34:5
|
LL | unsafe fn named_ptr(x: *const (i32,)) {
| ------------- help: consider changing this to be a mutable pointer: `*mut (i32,)`
LL | *x = (1,); //~ ERROR
LL | (*x).0 = 1; //~ ERROR
| ^^^^^^^^^^ `x` is a `*const` pointer, so the data it refers to cannot be written
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `*const` pointer
--> $DIR/mutability-errors.rs:35:5
|
LL | unsafe fn named_ptr(x: *const (i32,)) {
| ------------- help: consider changing this to be a mutable pointer: `*mut (i32,)`
...
LL | &mut *x; //~ ERROR
| ^^^^^^^ `x` is a `*const` pointer, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow `x.0` as mutable, as it is behind a `*const` pointer
--> $DIR/mutability-errors.rs:36:5
|
LL | unsafe fn named_ptr(x: *const (i32,)) {
| ------------- help: consider changing this to be a mutable pointer: `*mut (i32,)`
...
LL | &mut (*x).0; //~ ERROR
| ^^^^^^^^^^^ `x` is a `*const` pointer, so the data it refers to cannot be borrowed as mutable
error[E0594]: cannot assign to data in a `*const` pointer
--> $DIR/mutability-errors.rs:40:5
|
LL | *f() = (1,); //~ ERROR
| ^^^^^^^^^^^ cannot assign
error[E0594]: cannot assign to data in a `*const` pointer
--> $DIR/mutability-errors.rs:41:5
|
LL | (*f()).0 = 1; //~ ERROR
| ^^^^^^^^^^^^ cannot assign
error[E0596]: cannot borrow data in a `*const` pointer as mutable
--> $DIR/mutability-errors.rs:42:5
|
LL | &mut *f(); //~ ERROR
| ^^^^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow data in a `*const` pointer as mutable
--> $DIR/mutability-errors.rs:43:5
|
LL | &mut (*f()).0; //~ ERROR
| ^^^^^^^^^^^^^ cannot borrow as mutable
error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure
--> $DIR/mutability-errors.rs:50:9
|
LL | x = (1,); //~ ERROR
| ^^^^^^^^ cannot assign
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/mutability-errors.rs:49:12
|
LL | fn_ref(|| {
| ____________^
LL | | x = (1,); //~ ERROR
LL | | x.0 = 1; //~ ERROR
LL | | &mut x; //~ ERROR
LL | | &mut x.0; //~ ERROR
LL | | });
| |_____^
error[E0594]: cannot assign to `x.0`, as `Fn` closures cannot mutate their captured variables
--> $DIR/mutability-errors.rs:51:9
|
LL | x.0 = 1; //~ ERROR
| ^^^^^^^ cannot assign
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/mutability-errors.rs:49:12
|
LL | fn_ref(|| {
| ____________^
LL | | x = (1,); //~ ERROR
LL | | x.0 = 1; //~ ERROR
LL | | &mut x; //~ ERROR
LL | | &mut x.0; //~ ERROR
LL | | });
| |_____^
error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
--> $DIR/mutability-errors.rs:52:9
|
LL | &mut x; //~ ERROR
| ^^^^^^ cannot borrow as mutable
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/mutability-errors.rs:49:12
|
LL | fn_ref(|| {
| ____________^
LL | | x = (1,); //~ ERROR
LL | | x.0 = 1; //~ ERROR
LL | | &mut x; //~ ERROR
LL | | &mut x.0; //~ ERROR
LL | | });
| |_____^
error[E0596]: cannot borrow `x.0` as mutable, as `Fn` closures cannot mutate their captured variables
--> $DIR/mutability-errors.rs:53:9
|
LL | &mut x.0; //~ ERROR
| ^^^^^^^^ cannot borrow as mutable
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/mutability-errors.rs:49:12
|
LL | fn_ref(|| {
| ____________^
LL | | x = (1,); //~ ERROR
LL | | x.0 = 1; //~ ERROR
LL | | &mut x; //~ ERROR
LL | | &mut x.0; //~ ERROR
LL | | });
| |_____^
error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure
--> $DIR/mutability-errors.rs:56:9
|
LL | x = (1,); //~ ERROR
| ^^^^^^^^ cannot assign
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/mutability-errors.rs:55:12
|
LL | fn_ref(move || {
| ____________^
LL | | x = (1,); //~ ERROR
LL | | x.0 = 1; //~ ERROR
LL | | &mut x; //~ ERROR
LL | | &mut x.0; //~ ERROR
LL | | });
| |_____^
error[E0594]: cannot assign to `x.0`, as `Fn` closures cannot mutate their captured variables
--> $DIR/mutability-errors.rs:57:9
|
LL | x.0 = 1; //~ ERROR
| ^^^^^^^ cannot assign
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/mutability-errors.rs:55:12
|
LL | fn_ref(move || {
| ____________^
LL | | x = (1,); //~ ERROR
LL | | x.0 = 1; //~ ERROR
LL | | &mut x; //~ ERROR
LL | | &mut x.0; //~ ERROR
LL | | });
| |_____^
error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
--> $DIR/mutability-errors.rs:58:9
|
LL | &mut x; //~ ERROR
| ^^^^^^ cannot borrow as mutable
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/mutability-errors.rs:55:12
|
LL | fn_ref(move || {
| ____________^
LL | | x = (1,); //~ ERROR
LL | | x.0 = 1; //~ ERROR
LL | | &mut x; //~ ERROR
LL | | &mut x.0; //~ ERROR
LL | | });
| |_____^
error[E0596]: cannot borrow `x.0` as mutable, as `Fn` closures cannot mutate their captured variables
--> $DIR/mutability-errors.rs:59:9
|
LL | &mut x.0; //~ ERROR
| ^^^^^^^^ cannot borrow as mutable
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/mutability-errors.rs:55:12
|
LL | fn_ref(move || {
| ____________^
LL | | x = (1,); //~ ERROR
LL | | x.0 = 1; //~ ERROR
LL | | &mut x; //~ ERROR
LL | | &mut x.0; //~ ERROR
LL | | });
| |_____^
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/mutability-errors.rs:64:5
|
LL | fn imm_local(x: (i32,)) {
| - help: consider changing this to be mutable: `mut x`
LL | &mut x; //~ ERROR
| ^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow `x.0` as mutable, as `x` is not declared as mutable
--> $DIR/mutability-errors.rs:65:5
|
LL | fn imm_local(x: (i32,)) {
| - help: consider changing this to be mutable: `mut x`
LL | &mut x; //~ ERROR
LL | &mut x.0; //~ ERROR
| ^^^^^^^^ cannot borrow as mutable
error[E0594]: cannot assign to `x`, as it is not declared as mutable
--> $DIR/mutability-errors.rs:70:9
|
LL | fn imm_capture(x: (i32,)) {
| - help: consider changing this to be mutable: `mut x`
LL | || { //~ ERROR
LL | x = (1,);
| ^^^^^^^^ cannot assign
error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable
--> $DIR/mutability-errors.rs:71:9
|
LL | fn imm_capture(x: (i32,)) {
| - help: consider changing this to be mutable: `mut x`
...
LL | x.0 = 1;
| ^^^^^^^ cannot assign
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/mutability-errors.rs:72:9
|
LL | fn imm_capture(x: (i32,)) {
| - help: consider changing this to be mutable: `mut x`
...
LL | &mut x;
| ^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow `x.0` as mutable, as `x` is not declared as mutable
--> $DIR/mutability-errors.rs:73:9
|
LL | fn imm_capture(x: (i32,)) {
| - help: consider changing this to be mutable: `mut x`
...
LL | &mut x.0;
| ^^^^^^^^ cannot borrow as mutable
error[E0594]: cannot assign to `x`, as it is not declared as mutable
--> $DIR/mutability-errors.rs:76:9
|
LL | fn imm_capture(x: (i32,)) {
| - help: consider changing this to be mutable: `mut x`
...
LL | x = (1,); //~ ERROR
| ^^^^^^^^ cannot assign
error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable
--> $DIR/mutability-errors.rs:77:9
|
LL | fn imm_capture(x: (i32,)) {
| - help: consider changing this to be mutable: `mut x`
...
LL | x.0 = 1; //~ ERROR
| ^^^^^^^ cannot assign
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/mutability-errors.rs:78:9
|
LL | fn imm_capture(x: (i32,)) {
| - help: consider changing this to be mutable: `mut x`
...
LL | &mut x; //~ ERROR
| ^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow `x.0` as mutable, as `x` is not declared as mutable
--> $DIR/mutability-errors.rs:79:9
|
LL | fn imm_capture(x: (i32,)) {
| - help: consider changing this to be mutable: `mut x`
...
LL | &mut x.0; //~ ERROR
| ^^^^^^^^ cannot borrow as mutable
error[E0594]: cannot assign to immutable static item `X`
--> $DIR/mutability-errors.rs:86:5
|
LL | X = (1,); //~ ERROR
| ^^^^^^^^ cannot assign
error[E0594]: cannot assign to `X.0`, as `X` is an immutable static item
--> $DIR/mutability-errors.rs:87:5
|
LL | X.0 = 1; //~ ERROR
| ^^^^^^^ cannot assign
error[E0596]: cannot borrow immutable static item `X` as mutable
--> $DIR/mutability-errors.rs:88:5
|
LL | &mut X; //~ ERROR
| ^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow `X.0` as mutable, as `X` is an immutable static item
--> $DIR/mutability-errors.rs:89:5
|
LL | &mut X.0; //~ ERROR
| ^^^^^^^^ cannot borrow as mutable
error: aborting due to 38 previous errors
Some errors occurred: E0594, E0596.
For more information about an error, try `rustc --explain E0594`.

View File

@ -0,0 +1,92 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// All the possible mutability error cases.
#![allow(unused)]
type MakeRef = fn() -> &'static (i32,);
type MakePtr = fn() -> *const (i32,);
fn named_ref(x: &(i32,)) {
*x = (1,); //~ ERROR
x.0 = 1; //~ ERROR
&mut *x; //~ ERROR
&mut x.0; //~ ERROR
}
fn unnamed_ref(f: MakeRef) {
*f() = (1,); //~ ERROR
f().0 = 1; //~ ERROR
&mut *f(); //~ ERROR
&mut f().0; //~ ERROR
}
unsafe fn named_ptr(x: *const (i32,)) {
*x = (1,); //~ ERROR
(*x).0 = 1; //~ ERROR
&mut *x; //~ ERROR
&mut (*x).0; //~ ERROR
}
unsafe fn unnamed_ptr(f: MakePtr) {
*f() = (1,); //~ ERROR
(*f()).0 = 1; //~ ERROR
&mut *f(); //~ ERROR
&mut (*f()).0; //~ ERROR
}
fn fn_ref<F: Fn()>(f: F) -> F { f }
fn ref_closure(mut x: (i32,)) {
fn_ref(|| {
x = (1,); //~ ERROR
x.0 = 1; //~ ERROR
&mut x; //~ ERROR
&mut x.0; //~ ERROR
});
fn_ref(move || {
x = (1,); //~ ERROR
x.0 = 1; //~ ERROR
&mut x; //~ ERROR
&mut x.0; //~ ERROR
});
}
fn imm_local(x: (i32,)) {
&mut x; //~ ERROR
&mut x.0; //~ ERROR
}
fn imm_capture(x: (i32,)) {
|| { //~ ERROR
x = (1,);
x.0 = 1;
&mut x;
&mut x.0;
};
move || {
x = (1,); //~ ERROR
x.0 = 1; //~ ERROR
&mut x; //~ ERROR
&mut x.0; //~ ERROR
};
}
static X: (i32,) = (0,);
fn imm_static() {
X = (1,); //~ ERROR
X.0 = 1; //~ ERROR
&mut X; //~ ERROR
&mut X.0; //~ ERROR
}
fn main() {}

View File

@ -0,0 +1,308 @@
error[E0594]: cannot assign to immutable borrowed content `*x`
--> $DIR/mutability-errors.rs:19:5
|
LL | fn named_ref(x: &(i32,)) {
| ------- use `&mut (i32,)` here to make mutable
LL | *x = (1,); //~ ERROR
| ^^^^^^^^^ cannot borrow as mutable
error[E0594]: cannot assign to field `x.0` of immutable binding
--> $DIR/mutability-errors.rs:20:5
|
LL | fn named_ref(x: &(i32,)) {
| ------- use `&mut (i32,)` here to make mutable
LL | *x = (1,); //~ ERROR
LL | x.0 = 1; //~ ERROR
| ^^^^^^^ cannot mutably borrow field of immutable binding
error[E0596]: cannot borrow immutable borrowed content `*x` as mutable
--> $DIR/mutability-errors.rs:21:10
|
LL | fn named_ref(x: &(i32,)) {
| ------- use `&mut (i32,)` here to make mutable
...
LL | &mut *x; //~ ERROR
| ^^ cannot borrow as mutable
error[E0596]: cannot borrow field `x.0` of immutable binding as mutable
--> $DIR/mutability-errors.rs:22:10
|
LL | fn named_ref(x: &(i32,)) {
| ------- use `&mut (i32,)` here to make mutable
...
LL | &mut x.0; //~ ERROR
| ^^^ cannot mutably borrow field of immutable binding
error[E0594]: cannot assign to immutable borrowed content
--> $DIR/mutability-errors.rs:26:5
|
LL | *f() = (1,); //~ ERROR
| ^^^^^^^^^^^ cannot borrow as mutable
error[E0594]: cannot assign to field of immutable binding
--> $DIR/mutability-errors.rs:27:5
|
LL | f().0 = 1; //~ ERROR
| ^^^^^^^^^ cannot mutably borrow field of immutable binding
error[E0596]: cannot borrow immutable borrowed content as mutable
--> $DIR/mutability-errors.rs:28:10
|
LL | &mut *f(); //~ ERROR
| ^^^^ cannot borrow as mutable
error[E0596]: cannot borrow field of immutable binding as mutable
--> $DIR/mutability-errors.rs:29:10
|
LL | &mut f().0; //~ ERROR
| ^^^^^ cannot mutably borrow field of immutable binding
error[E0594]: cannot assign to immutable dereference of raw pointer `*x`
--> $DIR/mutability-errors.rs:33:5
|
LL | *x = (1,); //~ ERROR
| ^^^^^^^^^ cannot borrow as mutable
error[E0594]: cannot assign to field `x.0` of immutable binding
--> $DIR/mutability-errors.rs:34:5
|
LL | (*x).0 = 1; //~ ERROR
| ^^^^^^^^^^ cannot mutably borrow field of immutable binding
error[E0596]: cannot borrow immutable dereference of raw pointer `*x` as mutable
--> $DIR/mutability-errors.rs:35:10
|
LL | &mut *x; //~ ERROR
| ^^ cannot borrow as mutable
error[E0596]: cannot borrow field `x.0` of immutable binding as mutable
--> $DIR/mutability-errors.rs:36:10
|
LL | &mut (*x).0; //~ ERROR
| ^^^^^^ cannot mutably borrow field of immutable binding
error[E0594]: cannot assign to immutable dereference of raw pointer
--> $DIR/mutability-errors.rs:40:5
|
LL | *f() = (1,); //~ ERROR
| ^^^^^^^^^^^ cannot borrow as mutable
error[E0594]: cannot assign to field of immutable binding
--> $DIR/mutability-errors.rs:41:5
|
LL | (*f()).0 = 1; //~ ERROR
| ^^^^^^^^^^^^ cannot mutably borrow field of immutable binding
error[E0596]: cannot borrow immutable dereference of raw pointer as mutable
--> $DIR/mutability-errors.rs:42:10
|
LL | &mut *f(); //~ ERROR
| ^^^^ cannot borrow as mutable
error[E0596]: cannot borrow field of immutable binding as mutable
--> $DIR/mutability-errors.rs:43:10
|
LL | &mut (*f()).0; //~ ERROR
| ^^^^^^^^ cannot mutably borrow field of immutable binding
error[E0387]: cannot assign to data in a captured outer variable in an `Fn` closure
--> $DIR/mutability-errors.rs:50:9
|
LL | x = (1,); //~ ERROR
| ^^^^^^^^
|
help: consider changing this closure to take self by mutable reference
--> $DIR/mutability-errors.rs:49:12
|
LL | fn_ref(|| {
| ____________^
LL | | x = (1,); //~ ERROR
LL | | x.0 = 1; //~ ERROR
LL | | &mut x; //~ ERROR
LL | | &mut x.0; //~ ERROR
LL | | });
| |_____^
error[E0387]: cannot assign to data in a captured outer variable in an `Fn` closure
--> $DIR/mutability-errors.rs:51:9
|
LL | x.0 = 1; //~ ERROR
| ^^^^^^^
|
help: consider changing this closure to take self by mutable reference
--> $DIR/mutability-errors.rs:49:12
|
LL | fn_ref(|| {
| ____________^
LL | | x = (1,); //~ ERROR
LL | | x.0 = 1; //~ ERROR
LL | | &mut x; //~ ERROR
LL | | &mut x.0; //~ ERROR
LL | | });
| |_____^
error[E0387]: cannot borrow data mutably in a captured outer variable in an `Fn` closure
--> $DIR/mutability-errors.rs:52:14
|
LL | &mut x; //~ ERROR
| ^
|
help: consider changing this closure to take self by mutable reference
--> $DIR/mutability-errors.rs:49:12
|
LL | fn_ref(|| {
| ____________^
LL | | x = (1,); //~ ERROR
LL | | x.0 = 1; //~ ERROR
LL | | &mut x; //~ ERROR
LL | | &mut x.0; //~ ERROR
LL | | });
| |_____^
error[E0387]: cannot borrow data mutably in a captured outer variable in an `Fn` closure
--> $DIR/mutability-errors.rs:53:14
|
LL | &mut x.0; //~ ERROR
| ^^^
|
help: consider changing this closure to take self by mutable reference
--> $DIR/mutability-errors.rs:49:12
|
LL | fn_ref(|| {
| ____________^
LL | | x = (1,); //~ ERROR
LL | | x.0 = 1; //~ ERROR
LL | | &mut x; //~ ERROR
LL | | &mut x.0; //~ ERROR
LL | | });
| |_____^
error[E0594]: cannot assign to captured outer variable in an `Fn` closure
--> $DIR/mutability-errors.rs:56:9
|
LL | x = (1,); //~ ERROR
| ^^^^^^^^
|
= note: `Fn` closures cannot capture their enclosing environment for modifications
help: consider changing this closure to take self by mutable reference
--> $DIR/mutability-errors.rs:55:12
|
LL | fn_ref(move || {
| ____________^
LL | | x = (1,); //~ ERROR
LL | | x.0 = 1; //~ ERROR
LL | | &mut x; //~ ERROR
LL | | &mut x.0; //~ ERROR
LL | | });
| |_____^
error[E0594]: cannot assign to field `x.0` of immutable binding
--> $DIR/mutability-errors.rs:57:9
|
LL | x.0 = 1; //~ ERROR
| ^^^^^^^ cannot mutably borrow field of immutable binding
error[E0596]: cannot borrow captured outer variable in an `Fn` closure as mutable
--> $DIR/mutability-errors.rs:58:14
|
LL | &mut x; //~ ERROR
| ^
|
help: consider changing this closure to take self by mutable reference
--> $DIR/mutability-errors.rs:55:12
|
LL | fn_ref(move || {
| ____________^
LL | | x = (1,); //~ ERROR
LL | | x.0 = 1; //~ ERROR
LL | | &mut x; //~ ERROR
LL | | &mut x.0; //~ ERROR
LL | | });
| |_____^
error[E0596]: cannot borrow field `x.0` of immutable binding as mutable
--> $DIR/mutability-errors.rs:59:14
|
LL | &mut x.0; //~ ERROR
| ^^^ cannot mutably borrow field of immutable binding
error[E0596]: cannot borrow immutable argument `x` as mutable
--> $DIR/mutability-errors.rs:64:10
|
LL | fn imm_local(x: (i32,)) {
| - consider changing this to `mut x`
LL | &mut x; //~ ERROR
| ^ cannot borrow mutably
error[E0596]: cannot borrow field `x.0` of immutable binding as mutable
--> $DIR/mutability-errors.rs:65:10
|
LL | fn imm_local(x: (i32,)) {
| - consider changing this to `mut x`
LL | &mut x; //~ ERROR
LL | &mut x.0; //~ ERROR
| ^^^ cannot mutably borrow field of immutable binding
error[E0595]: closure cannot assign to immutable argument `x`
--> $DIR/mutability-errors.rs:69:5
|
LL | fn imm_capture(x: (i32,)) {
| - consider changing this to `mut x`
LL | || { //~ ERROR
| ^^ cannot borrow mutably
error[E0594]: cannot assign to captured outer variable in an `FnMut` closure
--> $DIR/mutability-errors.rs:76:9
|
LL | fn imm_capture(x: (i32,)) {
| - help: consider making `x` mutable: `mut x`
...
LL | x = (1,); //~ ERROR
| ^^^^^^^^
error[E0594]: cannot assign to field `x.0` of immutable binding
--> $DIR/mutability-errors.rs:77:9
|
LL | x.0 = 1; //~ ERROR
| ^^^^^^^ cannot mutably borrow field of immutable binding
error[E0596]: cannot borrow captured outer variable in an `FnMut` closure as mutable
--> $DIR/mutability-errors.rs:78:14
|
LL | &mut x; //~ ERROR
| ^
error[E0596]: cannot borrow field `x.0` of immutable binding as mutable
--> $DIR/mutability-errors.rs:79:14
|
LL | &mut x.0; //~ ERROR
| ^^^ cannot mutably borrow field of immutable binding
error[E0594]: cannot assign to immutable static item
--> $DIR/mutability-errors.rs:86:5
|
LL | X = (1,); //~ ERROR
| ^^^^^^^^
error[E0594]: cannot assign to field of immutable binding
--> $DIR/mutability-errors.rs:87:5
|
LL | X.0 = 1; //~ ERROR
| ^^^^^^^ cannot mutably borrow field of immutable binding
error[E0596]: cannot borrow immutable static item as mutable
--> $DIR/mutability-errors.rs:88:10
|
LL | &mut X; //~ ERROR
| ^
error[E0596]: cannot borrow field of immutable binding as mutable
--> $DIR/mutability-errors.rs:89:10
|
LL | &mut X.0; //~ ERROR
| ^^^ cannot mutably borrow field of immutable binding
error: aborting due to 35 previous errors
Some errors occurred: E0387, E0594, E0595, E0596.
For more information about an error, try `rustc --explain E0387`.

View File

@ -1,6 +1,8 @@
error[E0594]: cannot assign to immutable item `y`
error[E0594]: cannot assign to `y`, as it is not declared as mutable
--> $DIR/closure-immutable-outer-variable.rs:21:26
|
LL | let y = true;
| - help: consider changing this to be mutable: `mut y`
LL | foo(Box::new(move || y = false) as Box<_>); //~ ERROR cannot assign to captured outer variable
| ^^^^^^^^^ cannot assign

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item `x` as mutable
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/huge_multispan_highlight.rs:100:13
|
LL | let x = "foo";

View File

@ -1,10 +1,10 @@
error[E0596]: cannot borrow immutable item `self` as mutable
error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
--> $DIR/issue-31424.rs:17:9
|
LL | (&mut self).bar(); //~ ERROR cannot borrow
| ^^^^^^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow immutable item `self` as mutable
error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
--> $DIR/issue-31424.rs:23:9
|
LL | fn bar(self: &mut Self) {

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item `self` as mutable
error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
--> $DIR/issue-34126.rs:16:18
|
LL | self.run(&mut self); //~ ERROR cannot borrow

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item `key` as mutable
error[E0596]: cannot borrow `key` as mutable, as it is not declared as mutable
--> $DIR/issue-34337.rs:16:9
|
LL | get(&mut key); //~ ERROR cannot borrow

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item `f.v` as mutable
error[E0596]: cannot borrow `f.v` as mutable, as `f` is not declared as mutable
--> $DIR/issue-35937.rs:17:5
|
LL | let f = Foo { v: Vec::new() };

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item `x` as mutable
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/issue-37139.rs:22:18
|
LL | test(&mut x); //~ ERROR cannot borrow immutable

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item `*self.s` as mutable
error[E0596]: cannot borrow `*self.s` as mutable, as it is behind a `&` reference
--> $DIR/issue-38147-1.rs:27:9
|
LL | fn f(&self) {

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item `*self.s` as mutable
error[E0596]: cannot borrow `*self.s` as mutable, as it is behind a `&` reference
--> $DIR/issue-38147-2.rs:17:9
|
LL | self.s.push('x');

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item `*self.s` as mutable
error[E0596]: cannot borrow `*self.s` as mutable, as it is behind a `&` reference
--> $DIR/issue-38147-3.rs:17:9
|
LL | self.s.push('x');

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item `*f.s` as mutable
error[E0596]: cannot borrow `*f.s` as mutable, as it is behind a `&` reference
--> $DIR/issue-38147-4.rs:16:5
|
LL | fn f(x: usize, f: &Foo) {

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item `z.x` as mutable
error[E0596]: cannot borrow `z.x` as mutable, as `z` is not declared as mutable
--> $DIR/issue-39544.rs:21:13
|
LL | let z = Z { x: X::Y };
@ -6,7 +6,7 @@ LL | let z = Z { x: X::Y };
LL | let _ = &mut z.x; //~ ERROR cannot borrow
| ^^^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow immutable item `self.x` as mutable
error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference
--> $DIR/issue-39544.rs:26:17
|
LL | fn foo<'z>(&'z self) {
@ -14,7 +14,7 @@ LL | fn foo<'z>(&'z self) {
LL | let _ = &mut self.x; //~ ERROR cannot borrow
| ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow immutable item `self.x` as mutable
error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference
--> $DIR/issue-39544.rs:30:17
|
LL | fn foo1(&self, other: &Z) {
@ -22,7 +22,7 @@ LL | fn foo1(&self, other: &Z) {
LL | let _ = &mut self.x; //~ ERROR cannot borrow
| ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow immutable item `other.x` as mutable
error[E0596]: cannot borrow `other.x` as mutable, as it is behind a `&` reference
--> $DIR/issue-39544.rs:31:17
|
LL | fn foo1(&self, other: &Z) {
@ -31,7 +31,7 @@ LL | let _ = &mut self.x; //~ ERROR cannot borrow
LL | let _ = &mut other.x; //~ ERROR cannot borrow
| ^^^^^^^^^^^^ `other` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow immutable item `self.x` as mutable
error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference
--> $DIR/issue-39544.rs:35:17
|
LL | fn foo2<'a>(&'a self, other: &Z) {
@ -39,7 +39,7 @@ LL | fn foo2<'a>(&'a self, other: &Z) {
LL | let _ = &mut self.x; //~ ERROR cannot borrow
| ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow immutable item `other.x` as mutable
error[E0596]: cannot borrow `other.x` as mutable, as it is behind a `&` reference
--> $DIR/issue-39544.rs:36:17
|
LL | fn foo2<'a>(&'a self, other: &Z) {
@ -48,7 +48,7 @@ LL | let _ = &mut self.x; //~ ERROR cannot borrow
LL | let _ = &mut other.x; //~ ERROR cannot borrow
| ^^^^^^^^^^^^ `other` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow immutable item `self.x` as mutable
error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference
--> $DIR/issue-39544.rs:40:17
|
LL | fn foo3<'a>(self: &'a Self, other: &Z) {
@ -56,7 +56,7 @@ LL | fn foo3<'a>(self: &'a Self, other: &Z) {
LL | let _ = &mut self.x; //~ ERROR cannot borrow
| ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow immutable item `other.x` as mutable
error[E0596]: cannot borrow `other.x` as mutable, as it is behind a `&` reference
--> $DIR/issue-39544.rs:41:17
|
LL | fn foo3<'a>(self: &'a Self, other: &Z) {
@ -65,7 +65,7 @@ LL | let _ = &mut self.x; //~ ERROR cannot borrow
LL | let _ = &mut other.x; //~ ERROR cannot borrow
| ^^^^^^^^^^^^ `other` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow immutable item `other.x` as mutable
error[E0596]: cannot borrow `other.x` as mutable, as it is behind a `&` reference
--> $DIR/issue-39544.rs:45:17
|
LL | fn foo4(other: &Z) {
@ -73,7 +73,7 @@ LL | fn foo4(other: &Z) {
LL | let _ = &mut other.x; //~ ERROR cannot borrow
| ^^^^^^^^^^^^ `other` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow immutable item `z.x` as mutable
error[E0596]: cannot borrow `z.x` as mutable, as `z` is not declared as mutable
--> $DIR/issue-39544.rs:51:13
|
LL | pub fn with_arg(z: Z, w: &Z) {
@ -81,7 +81,7 @@ LL | pub fn with_arg(z: Z, w: &Z) {
LL | let _ = &mut z.x; //~ ERROR cannot borrow
| ^^^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow immutable item `w.x` as mutable
error[E0596]: cannot borrow `w.x` as mutable, as it is behind a `&` reference
--> $DIR/issue-39544.rs:52:13
|
LL | pub fn with_arg(z: Z, w: &Z) {

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item `*buf` as mutable
error[E0596]: cannot borrow `*buf` as mutable, as it is behind a `&` reference
--> $DIR/issue-40823.rs:13:5
|
LL | let mut buf = &[1, 2, 3, 4];

View File

@ -10,7 +10,7 @@ error[E0017]: references in statics may only refer to immutable values
LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
| ^^^^^^ statics require immutable values
error[E0596]: cannot borrow immutable item `X` as mutable
error[E0596]: cannot borrow immutable static item `X` as mutable
--> $DIR/E0017.rs:15:39
|
LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017

View File

@ -10,7 +10,7 @@ error[E0017]: references in statics may only refer to immutable values
LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
| ^^^^^^ statics require immutable values
error[E0596]: cannot borrow immutable item `X` as mutable
error[E0596]: cannot borrow immutable static item `X` as mutable
--> $DIR/E0388.rs:15:39
|
LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017

View File

@ -1,8 +1,14 @@
error[E0594]: cannot assign to `x` which is behind a `&` reference
error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure
--> $DIR/fn-closure-mutable-capture.rs:15:17
|
LL | bar(move || x = 1);
| ^^^^^ cannot assign
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/fn-closure-mutable-capture.rs:15:9
|
LL | bar(move || x = 1);
| ^^^^^^^^^^^^^
error: aborting due to previous error

View File

@ -1,14 +1,33 @@
error[E0596]: cannot borrow immutable item `x` as mutable
error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
--> $DIR/issue-21600.rs:24:20
|
LL | call_it(|| x.gen_mut()); //~ ERROR cannot borrow data mutably in a captured outer
| ^ cannot borrow as mutable
error[E0596]: cannot borrow immutable item `x` as mutable
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/issue-21600.rs:24:17
|
LL | call_it(|| x.gen_mut()); //~ ERROR cannot borrow data mutably in a captured outer
| ^^^^^^^^^^^^^^ cannot borrow as mutable
| ^^^^^^^^^^^^^^
error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
--> $DIR/issue-21600.rs:24:17
|
LL | call_it(|| x.gen_mut()); //~ ERROR cannot borrow data mutably in a captured outer
| ^^ - mutable borrow occurs due to use of `x` in closure
| |
| cannot borrow as mutable
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/issue-21600.rs:22:13
|
LL | call_it(|| {
| _____________^
LL | | call_it(|| x.gen());
LL | | call_it(|| x.gen_mut()); //~ ERROR cannot borrow data mutably in a captured outer
LL | | //~^ ERROR cannot borrow data mutably in a captured outer
LL | | });
| |_____^
error: aborting due to 2 previous errors

View File

@ -24,7 +24,7 @@ fn main() {
match b {
&mut false => {},
ref mut r if { (|| { let bar = &mut *r; **bar = false; })();
//~^ ERROR cannot borrow immutable item `*r` as mutable
//~^ ERROR cannot borrow `r` as mutable, as it is immutable for the pattern guard
false } => { &mut *r; },
&mut true => { println!("You might think we should get here"); },
_ => panic!("surely we could never get here, since rustc warns it is unreachable."),

View File

@ -1,8 +1,12 @@
error[E0596]: cannot borrow immutable item `*r` as mutable
--> $DIR/issue-27282-reborrow-ref-mut-in-guard.rs:26:24
error[E0596]: cannot borrow `r` as mutable, as it is immutable for the pattern guard
--> $DIR/issue-27282-reborrow-ref-mut-in-guard.rs:26:25
|
LL | ref mut r if { (|| { let bar = &mut *r; **bar = false; })();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
| ^^ - mutable borrow occurs due to use of `r` in closure
| |
| cannot borrow as mutable
|
= note: variables bound in patterns are immutable until the end of the pattern guard
error: aborting due to previous error

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item `v` as mutable
error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
--> $DIR/issue-33819.rs:13:34
|
LL | Some(ref v) => { let a = &mut v; },

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item `*x` as mutable
error[E0596]: cannot borrow `*x` as mutable, as `x` is not declared as mutable
--> $DIR/issue-36400.rs:15:7
|
LL | let x = Box::new(3);

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item as mutable
error[E0596]: cannot borrow data in a `&` reference as mutable
--> $DIR/issue-41726.rs:15:9
|
LL | things[src.as_str()].sort(); //~ ERROR cannot borrow immutable

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item `*TAB[..]` as mutable
error[E0596]: cannot borrow `*TAB[..]` as mutable, as `TAB` is an immutable static item
--> $DIR/issue-42344.rs:14:5
|
LL | TAB[0].iter_mut(); //~ ERROR cannot borrow data mutably in a `&` reference [E0389]

View File

@ -1,6 +1,9 @@
error[E0594]: cannot assign to immutable item `x`
error[E0594]: cannot assign to `x`, as it is not declared as mutable
--> $DIR/issue-46023.rs:18:9
|
LL | let x = 0;
| - help: consider changing this to be mutable: `mut x`
...
LL | x = 1;
| ^^^^^ cannot assign

View File

@ -1,6 +1,9 @@
error[E0594]: cannot assign to immutable item `x`
error[E0594]: cannot assign to `x`, as it is not declared as mutable
--> $DIR/issue-46023.rs:18:9
|
LL | let x = 0;
| - help: consider changing this to be mutable: `mut x`
...
LL | x = 1;
| ^^^^^ cannot assign

View File

@ -16,7 +16,7 @@ fn main() {
(move || {
x = 1;
//[mir]~^ ERROR cannot assign to immutable item `x` [E0594]
//[mir]~^ ERROR cannot assign to `x`, as it is not declared as mutable [E0594]
//[ast]~^^ ERROR cannot assign to captured outer variable in an `FnMut` closure [E0594]
})()
}

View File

@ -4,7 +4,7 @@ error[E0017]: references in statics may only refer to immutable values
LL | static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; //[ast]~ ERROR E0017
| ^^^^^^^^^^^^^^^^^^^^ statics require immutable values
error[E0594]: cannot assign to immutable item `buf[..]`
error[E0594]: cannot assign to `buf[..]`, as `buf` is an immutable static item
--> $DIR/issue-46604.rs:20:5
|
LL | buf[0]=2; //[ast]~ ERROR E0389

View File

@ -4,7 +4,7 @@ error[E0017]: references in statics may only refer to immutable values
LL | static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; //[ast]~ ERROR E0017
| ^^^^^^^^^^^^^^^^^^^^ statics require immutable values
error[E0594]: cannot assign to immutable item `buf[..]`
error[E0594]: cannot assign to `buf[..]`, as `buf` is an immutable static item
--> $DIR/issue-46604.rs:20:5
|
LL | buf[0]=2; //[ast]~ ERROR E0389

View File

@ -12,7 +12,7 @@ LL | fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) {
LL | y.push(z); //~ ERROR lifetime mismatch
| ^ ...but data from `z` flows into `y` here
error[E0596]: cannot borrow immutable item `y` as mutable
error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable
--> $DIR/ex3-both-anon-regions-using-fn-items.rs:11:3
|
LL | fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) {

View File

@ -12,7 +12,7 @@ LL | fn foo(x:Box<Fn(&u8, &u8)> , y: Vec<&u8>, z: &u8) {
LL | y.push(z); //~ ERROR lifetime mismatch
| ^ ...but data from `z` flows into `y` here
error[E0596]: cannot borrow immutable item `y` as mutable
error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable
--> $DIR/ex3-both-anon-regions-using-trait-objects.rs:11:3
|
LL | fn foo(x:Box<Fn(&u8, &u8)> , y: Vec<&u8>, z: &u8) {

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item `foo` as mutable
error[E0596]: cannot borrow `foo` as mutable, as it is not declared as mutable
--> $DIR/span-covering-argument-1.rs:15:14
|
LL | let $s = 0;

View File

@ -0,0 +1,68 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Some cases with closures that might be problems
#![allow(unused)]
#![feature(nll)]
// Should have one error per assigment
fn one_closure(x: i32) {
||
x = 1; //~ ERROR
move ||
x = 1; //~ ERROR
}
fn two_closures(x: i32) {
|| {
||
x = 1; //~ ERROR
};
move || {
||
x = 1; //~ ERROR
};
}
fn fn_ref<F: Fn()>(f: F) -> F { f }
fn two_closures_ref_mut(mut x: i32) {
fn_ref(|| {
|| //~ ERROR
x = 1;}
);
fn_ref(move || {
|| //~ ERROR
x = 1;});
}
// This still gives two messages, but it requires two things to be fixed.
fn two_closures_ref(x: i32) {
fn_ref(|| {
|| //~ ERROR
x = 1;} //~ ERROR
);
fn_ref(move || {
|| //~ ERROR
x = 1;}); //~ ERROR
}
fn two_closures_two_refs(x: &mut i32) {
fn_ref(|| {
|| //~ ERROR
*x = 1;});
fn_ref(move || {
|| //~ ERROR
*x = 1;});
}
fn main() {}

View File

@ -0,0 +1,160 @@
error[E0594]: cannot assign to `x`, as it is not declared as mutable
--> $DIR/closure-captures.rs:20:5
|
LL | fn one_closure(x: i32) {
| - help: consider changing this to be mutable: `mut x`
LL | ||
LL | x = 1; //~ ERROR
| ^^^^^ cannot assign
error[E0594]: cannot assign to `x`, as it is not declared as mutable
--> $DIR/closure-captures.rs:22:5
|
LL | fn one_closure(x: i32) {
| - help: consider changing this to be mutable: `mut x`
...
LL | x = 1; //~ ERROR
| ^^^^^ cannot assign
error[E0594]: cannot assign to `x`, as it is not declared as mutable
--> $DIR/closure-captures.rs:28:9
|
LL | fn two_closures(x: i32) {
| - help: consider changing this to be mutable: `mut x`
...
LL | x = 1; //~ ERROR
| ^^^^^ cannot assign
error[E0594]: cannot assign to `x`, as it is not declared as mutable
--> $DIR/closure-captures.rs:32:9
|
LL | fn two_closures(x: i32) {
| - help: consider changing this to be mutable: `mut x`
...
LL | x = 1; //~ ERROR
| ^^^^^ cannot assign
error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
--> $DIR/closure-captures.rs:40:9
|
LL | || //~ ERROR
| ^^ cannot borrow as mutable
LL | x = 1;}
| - mutable borrow occurs due to use of `x` in closure
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/closure-captures.rs:39:12
|
LL | fn_ref(|| {
| ____________^
LL | | || //~ ERROR
LL | | x = 1;}
| |________________^
error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
--> $DIR/closure-captures.rs:44:9
|
LL | || //~ ERROR
| ^^ cannot borrow as mutable
LL | x = 1;});
| - mutable borrow occurs due to use of `x` in closure
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/closure-captures.rs:43:12
|
LL | fn_ref(move || {
| ____________^
LL | | || //~ ERROR
LL | | x = 1;});
| |___________^
error[E0594]: cannot assign to `x`, as it is not declared as mutable
--> $DIR/closure-captures.rs:52:10
|
LL | fn two_closures_ref(x: i32) {
| - help: consider changing this to be mutable: `mut x`
...
LL | x = 1;} //~ ERROR
| ^^^^^ cannot assign
error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
--> $DIR/closure-captures.rs:51:9
|
LL | || //~ ERROR
| ^^ cannot borrow as mutable
LL | x = 1;} //~ ERROR
| - mutable borrow occurs due to use of `x` in closure
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/closure-captures.rs:50:12
|
LL | fn_ref(|| {
| ____________^
LL | | || //~ ERROR
LL | | x = 1;} //~ ERROR
| |________________^
error[E0594]: cannot assign to `x`, as it is not declared as mutable
--> $DIR/closure-captures.rs:56:5
|
LL | fn two_closures_ref(x: i32) {
| - help: consider changing this to be mutable: `mut x`
...
LL | x = 1;}); //~ ERROR
| ^^^^^ cannot assign
error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
--> $DIR/closure-captures.rs:55:9
|
LL | || //~ ERROR
| ^^ cannot borrow as mutable
LL | x = 1;}); //~ ERROR
| - mutable borrow occurs due to use of `x` in closure
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/closure-captures.rs:54:12
|
LL | fn_ref(move || {
| ____________^
LL | | || //~ ERROR
LL | | x = 1;}); //~ ERROR
| |___________^
error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
--> $DIR/closure-captures.rs:61:9
|
LL | || //~ ERROR
| ^^ cannot borrow as mutable
LL | *x = 1;});
| - mutable borrow occurs due to use of `x` in closure
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/closure-captures.rs:60:12
|
LL | fn_ref(|| {
| ____________^
LL | | || //~ ERROR
LL | | *x = 1;});
| |________________^
error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
--> $DIR/closure-captures.rs:64:9
|
LL | || //~ ERROR
| ^^ cannot borrow as mutable
LL | *x = 1;});
| - mutable borrow occurs due to use of `x` in closure
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/closure-captures.rs:63:12
|
LL | fn_ref(move || {
| ____________^
LL | | || //~ ERROR
LL | | *x = 1;});
| |________________^
error: aborting due to 12 previous errors
Some errors occurred: E0594, E0596.
For more information about an error, try `rustc --explain E0594`.

View File

@ -1,6 +1,9 @@
error[E0594]: cannot assign to immutable item `x`
error[E0594]: cannot assign to `x`, as it is not declared as mutable
--> $DIR/generator-upvar-mutability.rs:18:9
|
LL | let x = 0;
| - help: consider changing this to be mutable: `mut x`
LL | move || {
LL | x = 1;
| ^^^^^ cannot assign

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item `x` as mutable
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:63:24
|
LL | fn deref_mut_field1(x: Own<Point>) {
@ -6,7 +6,7 @@ LL | fn deref_mut_field1(x: Own<Point>) {
LL | let __isize = &mut x.y; //~ ERROR cannot borrow
| ^ cannot borrow as mutable
error[E0596]: cannot borrow immutable item `*x` as mutable
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:75:10
|
LL | fn deref_extend_mut_field1(x: &Own<Point>) -> &mut isize {
@ -14,7 +14,7 @@ LL | fn deref_extend_mut_field1(x: &Own<Point>) -> &mut isize {
LL | &mut x.y //~ ERROR cannot borrow
| ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow immutable item `x` as mutable
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:98:5
|
LL | fn assign_field1<'a>(x: Own<Point>) {
@ -22,7 +22,7 @@ LL | fn assign_field1<'a>(x: Own<Point>) {
LL | x.y = 3; //~ ERROR cannot borrow
| ^ cannot borrow as mutable
error[E0596]: cannot borrow immutable item `*x` as mutable
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:102:5
|
LL | fn assign_field2<'a>(x: &'a Own<Point>) {
@ -30,7 +30,7 @@ LL | fn assign_field2<'a>(x: &'a Own<Point>) {
LL | x.y = 3; //~ ERROR cannot borrow
| ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow immutable item `x` as mutable
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:119:5
|
LL | fn deref_mut_method1(x: Own<Point>) {
@ -38,7 +38,7 @@ LL | fn deref_mut_method1(x: Own<Point>) {
LL | x.set(0, 0); //~ ERROR cannot borrow
| ^ cannot borrow as mutable
error[E0596]: cannot borrow immutable item `*x` as mutable
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:131:5
|
LL | fn deref_extend_mut_method1(x: &Own<Point>) -> &mut isize {
@ -46,7 +46,7 @@ LL | fn deref_extend_mut_method1(x: &Own<Point>) -> &mut isize {
LL | x.y_mut() //~ ERROR cannot borrow
| ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow immutable item `x` as mutable
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:139:6
|
LL | fn assign_method1<'a>(x: Own<Point>) {
@ -54,7 +54,7 @@ LL | fn assign_method1<'a>(x: Own<Point>) {
LL | *x.y_mut() = 3; //~ ERROR cannot borrow
| ^ cannot borrow as mutable
error[E0596]: cannot borrow immutable item `*x` as mutable
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:143:6
|
LL | fn assign_method2<'a>(x: &'a Own<Point>) {

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item `x` as mutable
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/borrowck-borrow-overloaded-deref-mut.rs:39:25
|
LL | fn deref_mut1(x: Own<isize>) {
@ -6,7 +6,7 @@ LL | fn deref_mut1(x: Own<isize>) {
LL | let __isize = &mut *x; //~ ERROR cannot borrow
| ^ cannot borrow as mutable
error[E0596]: cannot borrow immutable item `*x` as mutable
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-borrow-overloaded-deref-mut.rs:51:11
|
LL | fn deref_extend_mut1<'a>(x: &'a Own<isize>) -> &'a mut isize {
@ -14,7 +14,7 @@ LL | fn deref_extend_mut1<'a>(x: &'a Own<isize>) -> &'a mut isize {
LL | &mut **x //~ ERROR cannot borrow
| ^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow immutable item `x` as mutable
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/borrowck-borrow-overloaded-deref-mut.rs:59:6
|
LL | fn assign1<'a>(x: Own<isize>) {
@ -22,7 +22,7 @@ LL | fn assign1<'a>(x: Own<isize>) {
LL | *x = 3; //~ ERROR cannot borrow
| ^ cannot borrow as mutable
error[E0596]: cannot borrow immutable item `*x` as mutable
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-borrow-overloaded-deref-mut.rs:63:6
|
LL | fn assign2<'a>(x: &'a Own<isize>) {

View File

@ -12,7 +12,7 @@ LL | | f((Box::new(|| {})))
LL | | }));
| |_______- borrow later used here
error[E0596]: cannot borrow immutable item `*f` as mutable
error[E0596]: cannot borrow `*f` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-call-is-borrow-issue-12224.rs:35:5
|
LL | fn test2<F>(f: &F) where F: FnMut() {
@ -20,7 +20,7 @@ LL | fn test2<F>(f: &F) where F: FnMut() {
LL | (*f)();
| ^^^^ `f` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow immutable item `*f.f` as mutable
error[E0596]: cannot borrow `*f.f` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-call-is-borrow-issue-12224.rs:44:5
|
LL | fn test4(f: &Test) {

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item `*x` as mutable
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-call-method-from-mut-aliasable.rs:27:5
|
LL | fn b(x: &Foo) {

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item `*x` as mutable
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-fn-in-const-b.rs:17:9
|
LL | fn broken(x: &Vec<String>) {

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item `*x` as mutable
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-object-mutability.rs:19:5
|
LL | fn borrowed_receiver(x: &Foo) {
@ -7,7 +7,7 @@ LL | x.borrowed();
LL | x.borrowed_mut(); //~ ERROR cannot borrow
| ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow immutable item `*x` as mutable
error[E0596]: cannot borrow `*x` as mutable, as `x` is not declared as mutable
--> $DIR/borrowck-object-mutability.rs:29:5
|
LL | fn owned_receiver(x: Box<Foo>) {

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item `*a` as mutable
error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference
--> $DIR/mut-arg-hint.rs:13:9
|
LL | fn foo(mut a: &String) {
@ -6,7 +6,7 @@ LL | fn foo(mut a: &String) {
LL | a.push_str("bar"); //~ ERROR cannot borrow immutable borrowed content
| ^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow immutable item `*a` as mutable
error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference
--> $DIR/mut-arg-hint.rs:18:5
|
LL | pub fn foo<'a>(mut a: &'a String) {
@ -14,7 +14,7 @@ LL | pub fn foo<'a>(mut a: &'a String) {
LL | a.push_str("foo"); //~ ERROR cannot borrow immutable borrowed content
| ^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow immutable item `*a` as mutable
error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference
--> $DIR/mut-arg-hint.rs:25:9
|
LL | pub fn foo(mut a: &String) {

View File

@ -1,4 +1,4 @@
error[E0596]: cannot borrow immutable item `**t` as mutable
error[E0596]: cannot borrow `**t` as mutable, as it is behind a `&` reference
--> $DIR/trivial-bounds-inconsistent-copy-reborrow.rs:16:5
|
LL | fn reborrow_mut<'a>(t: &'a &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
@ -6,7 +6,7 @@ LL | fn reborrow_mut<'a>(t: &'a &'a mut i32) -> &'a mut i32 where &'a mut i32: C
LL | *t //~ ERROR
| ^^ `t` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow immutable item `**t` as mutable
error[E0596]: cannot borrow `**t` as mutable, as it is behind a `&` reference
--> $DIR/trivial-bounds-inconsistent-copy-reborrow.rs:20:6
|
LL | fn copy_reborrow_mut<'a>(t: &'a &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {