1
Fork 0

Auto merge of #59114 - matthewjasper:enable-migate-2015, r=pnkfelix

Enable NLL migrate mode on the 2015 edition

## What is in this PR?

* Remove the `-Zborrowck=ast` flag option from rustc.
* The default in the 2015 edition is now `-Zborrowck=migrate`.
* The 2018 edition default is unchanged: it's still `-Zborrowck=migrate`.
* Enable two-phase borrows (currently toggled via the `-Ztwo-phase-borrows` flag) on all editions.
* Remove most dead code that handled these options.
* Update tests for the above changes.

## What is *not* in this PR?

These are left for future PRs

* Use `-Zborrowck=mir` in NLL compare mode tests (#56993)
* Remove the `-Zborrowck=compare` option (#59193)
* Remove the `-Ztwo-phase-borrows` flag. It's kept, as a flag that does nothing so that perf.rlo has time to stop using it (cc @Mark-Simulacrum)
* Remove MIR typeck as its own MIR pass - it's now run by NLL.
* Enabling `-Zborrowck=mir` by default (#58781)
* Replace `allow_bind_by_move_patterns_with_guards` and `check_for_mutation_in_guard_via_ast_walk` with just using the feature gate. (#59192)

Soundness issues that are fixed by NLL will stay open until full NLL is emitting hard errors. However, these diagnostics and completeness issues can now be closed:

Closes #18330
Closes #22323
Closes #23591
Closes #26736
Closes #27487
Closes #28092
Closes #28970
Closes #29733
Closes #30104
Closes #38915
Closes #39908
Closes #43407
Closes #47524
Closes #48540
Closes #49073
Closes #52614
Closes #55085
Closes #56093
Closes #56496
Closes #57804

cc #43234

r? @pnkfelix
cc @rust-lang/lang
cc @rust-lang/wg-compiler-nll
This commit is contained in:
bors 2019-04-22 12:09:59 +00:00
commit c21fbfe7e3
1372 changed files with 6080 additions and 22289 deletions

View file

@ -92,8 +92,8 @@ impl SuppressRegionErrors {
/// enabled.
pub fn when_nll_is_enabled(tcx: TyCtxt<'_, '_, '_>) -> Self {
match tcx.borrowck_mode() {
// If we're on AST or Migrate mode, report AST region errors
BorrowckMode::Ast | BorrowckMode::Migrate => SuppressRegionErrors { suppressed: false },
// If we're on Migrate mode, report AST region errors
BorrowckMode::Migrate => SuppressRegionErrors { suppressed: false },
// If we're on MIR or Compare mode, don't report AST region errors as they should
// be reported by NLL

View file

@ -460,7 +460,6 @@ pub enum PrintRequest {
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum BorrowckMode {
Ast,
Mir,
Compare,
Migrate,
@ -471,7 +470,6 @@ impl BorrowckMode {
/// on the AST borrow check if the MIR-based one errors.
pub fn migrate(self) -> bool {
match self {
BorrowckMode::Ast => false,
BorrowckMode::Compare => false,
BorrowckMode::Mir => false,
BorrowckMode::Migrate => true,
@ -481,21 +479,11 @@ impl BorrowckMode {
/// Should we emit the AST-based borrow checker errors?
pub fn use_ast(self) -> bool {
match self {
BorrowckMode::Ast => true,
BorrowckMode::Compare => true,
BorrowckMode::Mir => false,
BorrowckMode::Migrate => false,
}
}
/// Should we emit the MIR-based borrow checker errors?
pub fn use_mir(self) -> bool {
match self {
BorrowckMode::Ast => false,
BorrowckMode::Compare => true,
BorrowckMode::Mir => true,
BorrowckMode::Migrate => true,
}
}
}
pub enum Input {
@ -627,7 +615,7 @@ impl Default for Options {
incremental: None,
debugging_opts: basic_debugging_options(),
prints: Vec::new(),
borrowck_mode: BorrowckMode::Ast,
borrowck_mode: BorrowckMode::Migrate,
cg: basic_codegen_options(),
error_format: ErrorOutputType::default(),
externs: Externs(BTreeMap::new()),
@ -2326,10 +2314,9 @@ pub fn build_session_options_and_crate_config(
}));
let borrowck_mode = match debugging_opts.borrowck.as_ref().map(|s| &s[..]) {
None | Some("ast") => BorrowckMode::Ast,
None | Some("migrate") => BorrowckMode::Migrate,
Some("mir") => BorrowckMode::Mir,
Some("compare") => BorrowckMode::Compare,
Some("migrate") => BorrowckMode::Migrate,
Some(m) => early_error(error_format, &format!("unknown borrowck mode `{}`", m)),
};

View file

@ -70,7 +70,6 @@ use rustc_macros::HashStable;
use syntax::ast;
use syntax::attr;
use syntax::source_map::MultiSpan;
use syntax::edition::Edition;
use syntax::feature_gate;
use syntax::symbol::{Symbol, keywords, InternedString};
use syntax_pos::Span;
@ -1496,21 +1495,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// because that method has a narrower effect that can be toggled
/// off via a separate `-Z` flag, at least for the short term.
pub fn allow_bind_by_move_patterns_with_guards(self) -> bool {
self.features().bind_by_move_pattern_guards && self.use_mir_borrowck()
self.features().bind_by_move_pattern_guards
}
/// If true, we should use a naive AST walk to determine if match
/// guard could perform bad mutations (or mutable-borrows).
pub fn check_for_mutation_in_guard_via_ast_walk(self) -> bool {
// If someone requests the feature, then be a little more
// careful and ensure that MIR-borrowck is enabled (which can
// happen via edition selection, via `feature(nll)`, or via an
// appropriate `-Z` flag) before disabling the mutation check.
if self.allow_bind_by_move_patterns_with_guards() {
return false;
}
return true;
!self.allow_bind_by_move_patterns_with_guards()
}
/// If true, we should use the AST-based borrowck (we may *also* use
@ -1519,12 +1510,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
self.borrowck_mode().use_ast()
}
/// If true, we should use the MIR-based borrowck (we may *also* use
/// the AST-based borrowck).
pub fn use_mir_borrowck(self) -> bool {
self.borrowck_mode().use_mir()
}
/// If true, we should use the MIR-based borrow check, but also
/// fall back on the AST borrow check if the MIR-based one errors.
pub fn migrate_borrowck(self) -> bool {
@ -1541,23 +1526,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// statements (which simulate the maximal effect of executing the
/// patterns in a match arm).
pub fn emit_read_for_match(&self) -> bool {
self.use_mir_borrowck() && !self.sess.opts.debugging_opts.nll_dont_emit_read_for_match
}
/// If true, pattern variables for use in guards on match arms
/// will be bound as references to the data, and occurrences of
/// those variables in the guard expression will implicitly
/// dereference those bindings. (See rust-lang/rust#27282.)
pub fn all_pat_vars_are_implicit_refs_within_guards(self) -> bool {
self.borrowck_mode().use_mir()
}
/// If true, we should enable two-phase borrows checks. This is
/// done with either: `-Ztwo-phase-borrows`, `#![feature(nll)]`,
/// or by opting into an edition after 2015.
pub fn two_phase_borrows(self) -> bool {
self.sess.rust_2018() || self.features().nll ||
self.sess.opts.debugging_opts.two_phase_borrows
!self.sess.opts.debugging_opts.nll_dont_emit_read_for_match
}
/// What mode(s) of borrowck should we run? AST? MIR? both?
@ -1565,14 +1534,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
pub fn borrowck_mode(&self) -> BorrowckMode {
// Here are the main constraints we need to deal with:
//
// 1. An opts.borrowck_mode of `BorrowckMode::Ast` is
// 1. An opts.borrowck_mode of `BorrowckMode::Migrate` is
// synonymous with no `-Z borrowck=...` flag at all.
// (This is arguably a historical accident.)
//
// 2. `BorrowckMode::Migrate` is the limited migration to
// NLL that we are deploying with the 2018 edition.
//
// 3. We want to allow developers on the Nightly channel
// 2. We want to allow developers on the Nightly channel
// to opt back into the "hard error" mode for NLL,
// (which they can do via specifying `#![feature(nll)]`
// explicitly in their crate).
@ -1585,24 +1550,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
// a user's attempt to specify `-Z borrowck=compare`, which
// we arguably do not need anymore and should remove.)
//
// * Otherwise, if no `-Z borrowck=...` flag was given (or
// if `borrowck=ast` was specified), then use the default
// as required by the edition.
// * Otherwise, if no `-Z borrowck=...` then use migrate mode
//
// * Otherwise, use the behavior requested via `-Z borrowck=...`
if self.features().nll { return BorrowckMode::Mir; }
match self.sess.opts.borrowck_mode {
mode @ BorrowckMode::Mir |
mode @ BorrowckMode::Compare |
mode @ BorrowckMode::Migrate => mode,
BorrowckMode::Ast => match self.sess.edition() {
Edition::Edition2015 => BorrowckMode::Ast,
Edition::Edition2018 => BorrowckMode::Migrate,
},
}
self.sess.opts.borrowck_mode
}
#[inline]

View file

@ -49,8 +49,6 @@ pub mod gather_loans;
pub mod move_data;
mod unused;
#[derive(Clone, Copy)]
pub struct LoanDataFlowOperator;
@ -138,10 +136,6 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId)
check_loans::check_loans(&mut bccx, &loan_dfcx, &flowed_moves, &all_loans, body);
}
if !tcx.use_mir_borrowck() {
unused::check(&mut bccx, body);
}
Lrc::new(BorrowCheckResult {
used_mut_nodes: bccx.used_mut_nodes.into_inner(),
signalled_any_error: bccx.signalled_any_error.into_inner(),

View file

@ -1,116 +0,0 @@
use rustc::hir::intravisit::{Visitor, NestedVisitorMap};
use rustc::hir::{self, HirId};
use rustc::lint::builtin::UNUSED_MUT;
use rustc::ty;
use rustc::util::nodemap::{FxHashMap, FxHashSet};
use errors::Applicability;
use std::slice;
use syntax::ptr::P;
use crate::borrowck::BorrowckCtxt;
pub fn check<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, body: &'tcx hir::Body) {
let mut used_mut = bccx.used_mut_nodes.borrow().clone();
UsedMutFinder {
bccx,
set: &mut used_mut,
}.visit_expr(&body.value);
let mut cx = UnusedMutCx { bccx, used_mut };
for arg in body.arguments.iter() {
cx.check_unused_mut_pat(slice::from_ref(&arg.pat));
}
cx.visit_expr(&body.value);
}
struct UsedMutFinder<'a, 'tcx: 'a> {
bccx: &'a BorrowckCtxt<'a, 'tcx>,
set: &'a mut FxHashSet<HirId>,
}
struct UnusedMutCx<'a, 'tcx: 'a> {
bccx: &'a BorrowckCtxt<'a, 'tcx>,
used_mut: FxHashSet<HirId>,
}
impl<'a, 'tcx> UnusedMutCx<'a, 'tcx> {
fn check_unused_mut_pat(&self, pats: &[P<hir::Pat>]) {
let tcx = self.bccx.tcx;
let mut mutables: FxHashMap<_, Vec<_>> = Default::default();
for p in pats {
p.each_binding(|_, hir_id, span, ident| {
// Skip anything that looks like `_foo`
if ident.as_str().starts_with("_") {
return;
}
// Skip anything that looks like `&foo` or `&mut foo`, only look
// for by-value bindings
if let Some(&bm) = self.bccx.tables.pat_binding_modes().get(hir_id) {
match bm {
ty::BindByValue(hir::MutMutable) => {}
_ => return,
}
mutables.entry(ident.name).or_default().push((hir_id, span));
} else {
tcx.sess.delay_span_bug(span, "missing binding mode");
}
});
}
for (_name, ids) in mutables {
// If any id for this name was used mutably then consider them all
// ok, so move on to the next
if ids.iter().any(|&(ref hir_id, _)| self.used_mut.contains(hir_id)) {
continue;
}
let (hir_id, span) = ids[0];
if span.compiler_desugaring_kind().is_some() {
// If the `mut` arises as part of a desugaring, we should ignore it.
continue;
}
// Ok, every name wasn't used mutably, so issue a warning that this
// didn't need to be mutable.
let mut_span = tcx.sess.source_map().span_until_non_whitespace(span);
tcx.struct_span_lint_hir(UNUSED_MUT,
hir_id,
span,
"variable does not need to be mutable")
.span_suggestion_short(
mut_span,
"remove this `mut`",
String::new(),
Applicability::MachineApplicable,
)
.emit();
}
}
}
impl<'a, 'tcx> Visitor<'tcx> for UnusedMutCx<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::OnlyBodies(&self.bccx.tcx.hir())
}
fn visit_arm(&mut self, arm: &hir::Arm) {
self.check_unused_mut_pat(&arm.pats)
}
fn visit_local(&mut self, local: &hir::Local) {
self.check_unused_mut_pat(slice::from_ref(&local.pat));
}
}
impl<'a, 'tcx> Visitor<'tcx> for UsedMutFinder<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::OnlyBodies(&self.bccx.tcx.hir())
}
fn visit_nested_body(&mut self, id: hir::BodyId) {
let def_id = self.bccx.tcx.hir().body_owner_def_id(id);
self.set.extend(self.bccx.tcx.borrowck(def_id).used_mut_nodes.iter().cloned());
self.visit_body(self.bccx.tcx.hir().body(id));
}
}

View file

@ -303,9 +303,8 @@ impl<'a, 'gcx, 'tcx> GatherBorrows<'a, 'gcx, 'tcx> {
/// allowed to be split into separate Reservation and
/// Activation phases.
fn allow_two_phase_borrow(&self, kind: mir::BorrowKind) -> bool {
self.tcx.two_phase_borrows()
&& (kind.allows_two_phase_borrow()
|| self.tcx.sess.opts.debugging_opts.two_phase_beyond_autoref)
kind.allows_two_phase_borrow()
|| self.tcx.sess.opts.debugging_opts.two_phase_beyond_autoref
}
/// If this is a two-phase borrow, then we will record it

View file

@ -74,37 +74,28 @@ fn mir_borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> BorrowC
let input_mir = tcx.mir_validated(def_id);
debug!("run query mir_borrowck: {}", tcx.def_path_str(def_id));
let mut return_early;
// Return early if we are not supposed to use MIR borrow checker for this function.
return_early = !tcx.has_attr(def_id, "rustc_mir") && !tcx.use_mir_borrowck();
// We are not borrow checking the automatically generated struct/variant constructors
// because we want to accept structs such as this (taken from the `linked-hash-map`
// crate):
// ```rust
// struct Qey<Q: ?Sized>(Q);
// ```
// MIR of this struct constructor looks something like this:
// ```rust
// fn Qey(_1: Q) -> Qey<Q>{
// let mut _0: Qey<Q>; // return place
//
// bb0: {
// (_0.0: Q) = move _1; // bb0[0]: scope 0 at src/main.rs:1:1: 1:26
// return; // bb0[1]: scope 0 at src/main.rs:1:1: 1:26
// }
// }
// ```
// The problem here is that `(_0.0: Q) = move _1;` is valid only if `Q` is
// of statically known size, which is not known to be true because of the
// `Q: ?Sized` constraint. However, it is true because the constructor can be
// called only when `Q` is of statically known size.
if tcx.is_constructor(def_id) {
// We are not borrow checking the automatically generated struct/variant constructors
// because we want to accept structs such as this (taken from the `linked-hash-map`
// crate):
// ```rust
// struct Qey<Q: ?Sized>(Q);
// ```
// MIR of this struct constructor looks something like this:
// ```rust
// fn Qey(_1: Q) -> Qey<Q>{
// let mut _0: Qey<Q>; // return place
//
// bb0: {
// (_0.0: Q) = move _1; // bb0[0]: scope 0 at src/main.rs:1:1: 1:26
// return; // bb0[1]: scope 0 at src/main.rs:1:1: 1:26
// }
// }
// ```
// The problem here is that `(_0.0: Q) = move _1;` is valid only if `Q` is
// of statically known size, which is not known to be true because of the
// `Q: ?Sized` constraint. However, it is true because the constructor can be
// called only when `Q` is of statically known size.
return_early = true;
}
if return_early {
return BorrowCheckResult {
closure_requirements: None,
used_mut_upvars: SmallVec::new(),
@ -1505,10 +1496,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
span: Span,
flow_state: &Flows<'cx, 'gcx, 'tcx>,
) {
if !self.infcx.tcx.two_phase_borrows() {
return;
}
// Two-phase borrow support: For each activation that is newly
// generated at this statement, check if it interferes with
// another borrow.

View file

@ -474,10 +474,6 @@ impl<'cg, 'cx, 'tcx, 'gcx> InvalidationGenerator<'cx, 'tcx, 'gcx> {
&mut self,
location: Location,
) {
if !self.tcx.two_phase_borrows() {
return;
}
// Two-phase borrow support: For each activation that is newly
// generated at this statement, check if it interferes with
// another borrow.

View file

@ -2672,9 +2672,8 @@ impl MirPass for TypeckMir {
let def_id = src.def_id();
debug!("run_pass: {:?}", def_id);
// When NLL is enabled, the borrow checker runs the typeck
// itself, so we don't need this MIR pass anymore.
if tcx.use_mir_borrowck() {
// FIXME: We don't need this MIR pass anymore.
if true {
return;
}

View file

@ -15,9 +15,8 @@ pub(super) fn allow_two_phase_borrow<'a, 'tcx, 'gcx: 'tcx>(
tcx: &TyCtxt<'a, 'gcx, 'tcx>,
kind: BorrowKind
) -> bool {
tcx.two_phase_borrows()
&& (kind.allows_two_phase_borrow()
|| tcx.sess.opts.debugging_opts.two_phase_beyond_autoref)
kind.allows_two_phase_borrow()
|| tcx.sess.opts.debugging_opts.two_phase_beyond_autoref
}
/// Control for the path borrow checking code

View file

@ -112,11 +112,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
}
ExprKind::SelfRef => block.and(Place::Base(PlaceBase::Local(Local::new(1)))),
ExprKind::VarRef { id } => {
let place = if this.is_bound_var_in_guard(id) && this
.hir
.tcx()
.all_pat_vars_are_implicit_refs_within_guards()
{
let place = if this.is_bound_var_in_guard(id) {
let index = this.var_local_id(id, RefWithinGuard);
Place::Base(PlaceBase::Local(index)).deref()
} else {

View file

@ -1425,26 +1425,22 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
// the reference that we create for the arm.
// * So we eagerly create the reference for the arm and then take a
// reference to that.
let tcx = self.hir.tcx();
let autoref = tcx.all_pat_vars_are_implicit_refs_within_guards();
if let Some(guard) = guard {
if autoref {
self.bind_matched_candidate_for_guard(
block,
&candidate.bindings,
);
let guard_frame = GuardFrame {
locals: candidate
.bindings
.iter()
.map(|b| GuardFrameLocal::new(b.var_id, b.binding_mode))
.collect(),
};
debug!("Entering guard building context: {:?}", guard_frame);
self.guard_context.push(guard_frame);
} else {
self.bind_matched_candidate_for_arm_body(block, &candidate.bindings);
}
let tcx = self.hir.tcx();
self.bind_matched_candidate_for_guard(
block,
&candidate.bindings,
);
let guard_frame = GuardFrame {
locals: candidate
.bindings
.iter()
.map(|b| GuardFrameLocal::new(b.var_id, b.binding_mode))
.collect(),
};
debug!("Entering guard building context: {:?}", guard_frame);
self.guard_context.push(guard_frame);
let re_erased = tcx.types.re_erased;
let scrutinee_source_info = self.source_info(scrutinee_span);
@ -1470,13 +1466,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let source_info = self.source_info(guard.span);
let guard_end = self.source_info(tcx.sess.source_map().end_point(guard.span));
let cond = unpack!(block = self.as_local_operand(block, guard));
if autoref {
let guard_frame = self.guard_context.pop().unwrap();
debug!(
"Exiting guard building context with locals: {:?}",
guard_frame
);
}
let guard_frame = self.guard_context.pop().unwrap();
debug!(
"Exiting guard building context with locals: {:?}",
guard_frame
);
for &(_, temp) in fake_borrows {
self.cfg.push(block, Statement {
@ -1526,28 +1520,26 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
),
);
if autoref {
let by_value_bindings = candidate.bindings.iter().filter(|binding| {
if let BindingMode::ByValue = binding.binding_mode { true } else { false }
});
// Read all of the by reference bindings to ensure that the
// place they refer to can't be modified by the guard.
for binding in by_value_bindings.clone() {
let local_id = self.var_local_id(binding.var_id, RefWithinGuard);
let by_value_bindings = candidate.bindings.iter().filter(|binding| {
if let BindingMode::ByValue = binding.binding_mode { true } else { false }
});
// Read all of the by reference bindings to ensure that the
// place they refer to can't be modified by the guard.
for binding in by_value_bindings.clone() {
let local_id = self.var_local_id(binding.var_id, RefWithinGuard);
let place = Place::Base(PlaceBase::Local(local_id));
self.cfg.push(
block,
Statement {
source_info: guard_end,
kind: StatementKind::FakeRead(FakeReadCause::ForGuardBinding, place),
},
);
}
self.bind_matched_candidate_for_arm_body(
post_guard_block,
by_value_bindings,
self.cfg.push(
block,
Statement {
source_info: guard_end,
kind: StatementKind::FakeRead(FakeReadCause::ForGuardBinding, place),
},
);
}
self.bind_matched_candidate_for_arm_body(
post_guard_block,
by_value_bindings,
);
self.cfg.terminate(
post_guard_block,
@ -1604,8 +1596,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
}
}
// Only called when all_pat_vars_are_implicit_refs_within_guards,
// and thus all code/comments assume we are in that context.
fn bind_matched_candidate_for_guard(
&mut self,
block: BasicBlock,
@ -1739,7 +1729,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
}))),
};
let for_arm_body = self.local_decls.push(local.clone());
let locals = if has_guard.0 && tcx.all_pat_vars_are_implicit_refs_within_guards() {
let locals = if has_guard.0 {
let ref_for_guard = self.local_decls.push(LocalDecl::<'tcx> {
// This variable isn't mutated but has a name, so has to be
// immutable to avoid the unused mut lint.

View file

@ -877,12 +877,14 @@ https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html
"##,
E0383: r##"
#### Note: this error code is no longer emitted by the compiler.
This error occurs when an attempt is made to partially reinitialize a
structure that is currently uninitialized.
For example, this can happen when a drop has taken place:
```compile_fail,E0383
```compile_fail
struct Foo {
a: u32,
}
@ -966,10 +968,12 @@ y.set(2);
"##,*/
E0387: r##"
#### Note: this error code is no longer emitted by the compiler.
This error occurs when an attempt is made to mutate or mutably reference data
that a closure has captured immutably. Examples of this error are shown below:
```compile_fail,E0387
```compile_fail
// Accepts a function or a closure that captures its environment immutably.
// Closures passed to foo will not be able to mutate their closed-over state.
fn foo<F: Fn()>(f: F) { }
@ -1026,13 +1030,15 @@ E0388 was removed and is no longer issued.
"##,
E0389: r##"
#### Note: this error code is no longer emitted by the compiler.
An attempt was made to mutate data using a non-mutable reference. This
commonly occurs when attempting to assign to a non-mutable reference of a
mutable reference (`&(&mut T)`).
Example of erroneous code:
```compile_fail,E0389
```compile_fail
struct FancyNum {
num: u8,
}
@ -1202,6 +1208,7 @@ A variable was borrowed as mutable more than once. Erroneous code example:
let mut i = 0;
let mut x = &mut i;
let mut a = &mut i;
x;
// error: cannot borrow `i` as mutable more than once at a time
```
@ -1220,35 +1227,33 @@ let mut i = 0;
let a = &i; // ok!
let b = &i; // still ok!
let c = &i; // still ok!
b;
a;
```
"##,
E0500: r##"
A borrowed variable was used in another closure. Example of erroneous code:
A borrowed variable was used by a closure. Example of erroneous code:
```compile_fail
```compile_fail,E0500
fn you_know_nothing(jon_snow: &mut i32) {
let nights_watch = || {
*jon_snow = 2;
};
let nights_watch = &jon_snow;
let starks = || {
*jon_snow = 3; // error: closure requires unique access to `jon_snow`
// but it is already borrowed
};
println!("{}", nights_watch);
}
```
In here, `jon_snow` is already borrowed by the `nights_watch` closure, so it
In here, `jon_snow` is already borrowed by the `nights_watch` reference, so it
cannot be borrowed by the `starks` closure at the same time. To fix this issue,
you can put the closure in its own scope:
you can create the closure after the borrow has ended:
```
fn you_know_nothing(jon_snow: &mut i32) {
{
let nights_watch = || {
*jon_snow = 2;
};
} // At this point, `jon_snow` is free.
let nights_watch = &jon_snow;
println!("{}", nights_watch);
let starks = || {
*jon_snow = 3;
};
@ -1261,12 +1266,10 @@ closures:
```
fn you_know_nothing(jon_snow: &mut i32) {
let mut jon_copy = jon_snow.clone();
let nights_watch = || {
jon_copy = 2;
};
let starks = || {
*jon_snow = 3;
};
println!("{}", jon_copy);
}
```
"##,
@ -1293,26 +1296,28 @@ fn outside_closure(x: &mut i32) {
}
fn foo(a: &mut i32) {
let bar = || {
let mut bar = || {
inside_closure(a)
};
outside_closure(a); // error: cannot borrow `*a` as mutable because previous
// closure requires unique access.
bar();
}
```
To fix this error, you can place the closure in its own scope:
To fix this error, you can finish using the closure before using the captured
variable:
```
fn inside_closure(x: &mut i32) {}
fn outside_closure(x: &mut i32) {}
fn foo(a: &mut i32) {
{
let bar = || {
inside_closure(a)
};
} // borrow on `a` ends.
let mut bar = || {
inside_closure(a)
};
bar();
// borrow on `a` ends.
outside_closure(a); // ok!
}
```
@ -1324,7 +1329,7 @@ fn inside_closure(x: &mut i32) {}
fn outside_closure(x: &mut i32) {}
fn foo(a: &mut i32) {
let bar = |s: &mut i32| {
let mut bar = |s: &mut i32| {
inside_closure(s)
};
outside_closure(a);
@ -1340,9 +1345,10 @@ fn outside_closure(x: &mut i32) {}
fn foo(a: &mut i32) {
outside_closure(a);
let bar = || {
let mut bar = || {
inside_closure(a)
};
bar();
}
```
"##,
@ -1359,6 +1365,7 @@ fn foo(a: &mut i32) {
let ref y = a; // a is borrowed as immutable.
bar(a); // error: cannot borrow `*a` as mutable because `a` is also borrowed
// as immutable
println!("{}", y);
}
```
@ -1370,6 +1377,7 @@ fn bar(x: &mut i32) {}
fn foo(a: &mut i32) {
bar(a);
let ref y = a; // ok!
println!("{}", y);
}
```
@ -1385,11 +1393,11 @@ Example of erroneous code:
```compile_fail,E0503
fn main() {
let mut value = 3;
// Create a mutable borrow of `value`. This borrow
// lives until the end of this function.
let _borrow = &mut value;
// Create a mutable borrow of `value`.
let borrow = &mut value;
let _sum = value + 1; // error: cannot use `value` because
// it was mutably borrowed
println!("{}", borrow);
}
```
@ -1397,16 +1405,14 @@ In this example, `value` is mutably borrowed by `borrow` and cannot be
used to calculate `sum`. This is not possible because this would violate
Rust's mutability rules.
You can fix this error by limiting the scope of the borrow:
You can fix this error by finishing using the borrow before the next use of
the value:
```
fn main() {
let mut value = 3;
// By creating a new block, you can limit the scope
// of the reference.
{
let _borrow = &mut value; // Use `_borrow` inside this block.
}
let borrow = &mut value;
println!("{}", borrow);
// The block has ended and with it the borrow.
// You can now use `value` again.
let _sum = value + 1;
@ -1422,10 +1428,11 @@ fn main() {
let value_cloned = value.clone();
// The mutable borrow is a reference to `value` and
// not to `value_cloned`...
let _borrow = &mut value;
let borrow = &mut value;
// ... which means we can still use `value_cloned`,
let _sum = value_cloned + 1;
// even though the borrow only ends here.
println!("{}", borrow);
}
```
@ -1434,12 +1441,14 @@ http://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html
"##,
E0504: r##"
#### Note: this error code is no longer emitted by the compiler.
This error occurs when an attempt is made to move a borrowed variable into a
closure.
Example of erroneous code:
```compile_fail,E0504
```compile_fail
struct FancyNum {
num: u8,
}
@ -1577,9 +1586,10 @@ fn eat(val: &Value) {}
fn main() {
let x = Value{};
let _ref_to_val: &Value = &x;
let ref_to_val: &Value = &x;
eat(&x); // pass by reference, if it's possible
borrow(_ref_to_val);
borrow(ref_to_val);
}
```
@ -1594,11 +1604,11 @@ fn eat(val: Value) {}
fn main() {
let x = Value{};
{
let _ref_to_val: &Value = &x;
borrow(_ref_to_val);
}
eat(x); // release borrow and then move it.
let ref_to_val: &Value = &x;
borrow(ref_to_val);
// ref_to_val is no longer used.
eat(x);
}
```
@ -1614,9 +1624,9 @@ fn eat(val: Value) {}
fn main() {
let x = Value{};
let _ref_to_val: &Value = &x;
let ref_to_val: &Value = &x;
eat(x); // it will be copied here.
borrow(_ref_to_val);
borrow(ref_to_val);
}
```
@ -2053,11 +2063,13 @@ fn get_owned_iterator() -> IntoIter<i32> {
"##,
E0595: r##"
#### Note: this error code is no longer emitted by the compiler.
Closures cannot mutate immutable captured variables.
Erroneous code example:
```compile_fail,E0595
```compile_fail,E0594
let x = 3; // error: closure cannot assign to immutable local variable `x`
let mut c = || { x += 1 };
```
@ -2090,8 +2102,7 @@ let y = &mut x; // ok!
"##,
E0597: r##"
This error occurs because a borrow was made inside a variable which has a
greater lifetime than the borrowed one.
This error occurs because a value was dropped while it was still borrowed
Example of erroneous code:
@ -2101,23 +2112,28 @@ struct Foo<'a> {
}
let mut x = Foo { x: None };
let y = 0;
x.x = Some(&y); // error: `y` does not live long enough
{
let y = 0;
x.x = Some(&y); // error: `y` does not live long enough
}
println!("{:?}", x.x);
```
In here, `x` is created before `y` and therefore has a greater lifetime. Always
keep in mind that values in a scope are dropped in the opposite order they are
created. So to fix the previous example, just make the `y` lifetime greater than
the `x`'s one:
In here, `y` is dropped at the end of the inner scope, but it is borrowed by
`x` until the `println`. To fix the previous example, just remove the scope
so that `y` isn't dropped until after the println
```
struct Foo<'a> {
x: Option<&'a u32>,
}
let y = 0;
let mut x = Foo { x: None };
let y = 0;
x.x = Some(&y);
println!("{:?}", x.x);
```
"##,

View file

@ -565,7 +565,7 @@ fn check_legality_of_move_bindings(
let mut err = struct_span_err!(cx.tcx.sess, p.span, E0008,
"cannot bind by-move into a pattern guard");
err.span_label(p.span, "moves value into pattern guard");
if cx.tcx.sess.opts.unstable_features.is_nightly_build() && cx.tcx.use_mir_borrowck() {
if cx.tcx.sess.opts.unstable_features.is_nightly_build() {
err.help("add #![feature(bind_by_move_pattern_guards)] to the \
crate attributes to enable");
}
@ -649,9 +649,7 @@ impl<'a, 'tcx> Delegate<'tcx> for MutationChecker<'a, 'tcx> {
let mut err = struct_span_err!(self.cx.tcx.sess, span, E0301,
"cannot mutably borrow in a pattern guard");
err.span_label(span, "borrowed mutably in pattern guard");
if self.cx.tcx.sess.opts.unstable_features.is_nightly_build() &&
self.cx.tcx.use_mir_borrowck()
{
if self.cx.tcx.sess.opts.unstable_features.is_nightly_build() {
err.help("add #![feature(bind_by_move_pattern_guards)] to the \
crate attributes to enable");
}

View file

@ -40,7 +40,7 @@ impl Origin {
pub fn should_emit_errors(self, mode: BorrowckMode) -> bool {
match self {
Origin::Ast => mode.use_ast(),
Origin::Mir => mode.use_mir(),
Origin::Mir => true,
}
}
}

View file

@ -445,9 +445,7 @@ declare_features! (
(active, custom_inner_attributes, "1.30.0", Some(54726), None),
// Allow mixing of bind-by-move in patterns and references to
// those identifiers in guards, *if* we are using MIR-borrowck
// (aka NLL). Essentially this means you need to be using the
// 2018 edition or later.
// those identifiers in guards.
(active, bind_by_move_pattern_guards, "1.30.0", Some(15287), None),
// Allows `impl Trait` in bindings (`let`, `const`, `static`).

View file

@ -4,10 +4,10 @@
// compile-flags: -Z query-dep-graph
#![feature(rustc_attrs)]
#![cfg_attr(rpass1, feature(nll))]
#![cfg_attr(rpass1, feature(abi_unadjusted))]
fn main() {
let mut v = vec![1];
v.push(v[0]);
//[cfail2]~^ ERROR cannot borrow
}
extern "unadjusted" fn foo() {}
//[cfail2]~^ ERROR: unadjusted ABI is an implementation detail and perma-unstable

View file

@ -60,9 +60,11 @@ fn main() {
// goto -> bb16;
// }
// bb12: {
// StorageLive(_8);
// _8 = _2;
// switchInt(move _8) -> [false: bb6, otherwise: bb11];
// _8 = &shallow _1;
// StorageLive(_9);
// _9 = _2;
// FakeRead(ForMatchGuard, _8);
// switchInt(move _9) -> [false: bb6, otherwise: bb11];
// }
// bb13: {
// _3 = const 1i32;
@ -77,7 +79,7 @@ fn main() {
// goto -> bb16;
// }
// bb16: {
// StorageDead(_8);
// StorageDead(_9);
// _0 = ();
// StorageDead(_2);
// StorageDead(_1);

View file

@ -1,6 +1,6 @@
// error-pattern:panic 1
// revisions: ast mir
// revisions: migrate mir
//[mir]compile-flags: -Z borrowck=mir
fn main() {

View file

@ -1,6 +1,3 @@
// revisions: ast mir
//[mir]compile-flags: -Z borrowck=mir
#![feature(asm)]
#![allow(dead_code)]

View file

@ -1,6 +1,3 @@
// revisions ast mir
//[mir]compile-flags: -Z borrowck=mir
#![feature(asm)]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]

View file

@ -2,9 +2,6 @@
#![allow(dead_code)]
// Test taken from #45641 (https://github.com/rust-lang/rust/issues/45641)
// revisions: ast mir
//[mir]compile-flags: -Z borrowck=mir
static mut Y: u32 = 0;
unsafe fn should_ok() {

View file

@ -1,6 +1,4 @@
// run-pass
// revisions: ast mir
//[mir]compile-flags: -Z borrowck=mir
// Test file taken from issue 45129 (https://github.com/rust-lang/rust/issues/45129)

View file

@ -1,5 +1,4 @@
// run-pass
// compile-flags: -Z borrowck=mir -Z two-phase-borrows
// This is the "goto example" for why we want two phase borrows.

View file

@ -1,8 +1,4 @@
// run-pass
// revisions: lxl nll
//[lxl]compile-flags: -Z borrowck=mir -Z two-phase-borrows
#![cfg_attr(nll, feature(nll))]
fn main() {
let mut a = 0;

View file

@ -1,8 +1,6 @@
// run-pass
#![allow(unused_assignments)]
#![allow(unused_variables)]
// revisions:lexical nll
#![cfg_attr(nll, feature(nll))]
// ignore-wasm32-bare compiled with panic=abort by default

View file

@ -2,9 +2,6 @@
#![allow(dead_code)]
#![allow(dead_code)]
// revisions:lexical nll
#![cfg_attr(nll, feature(nll))]
#![feature(generators)]
fn bar<'a>() {

View file

@ -1,8 +1,5 @@
// run-pass
// revisions: normal nll
//[nll] compile-flags:-Zborrowck=mir
#![feature(fn_traits,
step_trait,
unboxed_closures,

View file

@ -2,9 +2,9 @@
// This test is bogus (i.e., should be compile-fail) during the period
// where #54986 is implemented and #54987 is *not* implemented. For
// now: just ignore it under nll
// now: just ignore it
//
// ignore-compare-mode-nll
// ignore-test
// This test is checking that the write to `c.0` (which has been moved out of)
// won't overwrite the state in `c2`.

View file

@ -2,9 +2,9 @@
// This test is bogus (i.e., should be compile-fail) during the period
// where #54986 is implemented and #54987 is *not* implemented. For
// now: just ignore it under nll
// now: just ignore it
//
// ignore-compare-mode-nll
// ignore-test
// These are variants of issue-26996.rs. In all cases we are writing
// into a record field that has been moved out of, and ensuring that

View file

@ -4,9 +4,9 @@
// This test is bogus (i.e., should be compile-fail) during the period
// where #54986 is implemented and #54987 is *not* implemented. For
// now: just ignore it under nll
// now: just ignore it
//
// ignore-compare-mode-nll
// ignore-test
// This test is checking that the space allocated for `x.1` does not
// overlap with `y`. (The reason why such a thing happened at one

View file

@ -1,12 +1,13 @@
error[E0597]: `arena` does not live long enough
--> $DIR/dropck-tarena-cycle-checked.rs:116:8
--> $DIR/dropck-tarena-cycle-checked.rs:116:7
|
LL | f(&arena);
| ^^^^^ borrowed value does not live long enough
| ^^^^^^ borrowed value does not live long enough
LL | }
| - `arena` dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
| -
| |
| `arena` dropped here while still borrowed
| borrow might be used here, when `arena` is dropped and runs the `Drop` code for type `arena::TypedArena`
error: aborting due to previous error

View file

@ -1,12 +1,13 @@
error[E0597]: `arena` does not live long enough
--> $DIR/dropck-tarena-unsound-drop.rs:41:8
--> $DIR/dropck-tarena-unsound-drop.rs:41:7
|
LL | f(&arena);
| ^^^^^ borrowed value does not live long enough
| ^^^^^^ borrowed value does not live long enough
LL | }
| - `arena` dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
| -
| |
| `arena` dropped here while still borrowed
| borrow might be used here, when `arena` is dropped and runs the `Drop` code for type `arena::TypedArena`
error: aborting due to previous error

View file

@ -1,31 +0,0 @@
error[E0501]: cannot borrow `*a` as mutable because previous closure requires unique access
--> $DIR/E0501.rs:18:23
|
LL | let bar = || {
| -- closure construction occurs here
LL | inside_closure(a)
| - previous borrow occurs due to use of `a` in closure
LL | };
LL | outside_closure_1(a);
| ^ borrow occurs here
...
LL | }
| - borrow from closure ends here
error[E0501]: cannot borrow `*a` as immutable because previous closure requires unique access
--> $DIR/E0501.rs:21:23
|
LL | let bar = || {
| -- closure construction occurs here
LL | inside_closure(a)
| - previous borrow occurs due to use of `a` in closure
...
LL | outside_closure_2(a);
| ^ borrow occurs here
...
LL | }
| - borrow from closure ends here
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0501`.

View file

@ -1,31 +0,0 @@
error[E0501]: cannot borrow `*a` as mutable because previous closure requires unique access
--> $DIR/E0501.rs:18:23
|
LL | let bar = || {
| -- closure construction occurs here
LL | inside_closure(a)
| - first borrow occurs due to use of `a` in closure
LL | };
LL | outside_closure_1(a);
| ^ second borrow occurs here
...
LL | drop(bar);
| --- first borrow later used here
error[E0501]: cannot borrow `*a` as immutable because previous closure requires unique access
--> $DIR/E0501.rs:21:23
|
LL | let bar = || {
| -- closure construction occurs here
LL | inside_closure(a)
| - first borrow occurs due to use of `a` in closure
...
LL | outside_closure_2(a);
| ^ second borrow occurs here
...
LL | drop(bar);
| --- first borrow later used here
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0501`.

View file

@ -1,7 +1,3 @@
// ignore-tidy-linelength
// revisions: ast mir
//[mir]compile-flags: -Z borrowck=mir
fn inside_closure(x: &mut i32) {
}
@ -15,11 +11,11 @@ fn foo(a: &mut i32) {
let bar = || {
inside_closure(a)
};
outside_closure_1(a); //[ast]~ ERROR cannot borrow `*a` as mutable because previous closure requires unique access
//[mir]~^ ERROR cannot borrow `*a` as mutable because previous closure requires unique access
outside_closure_1(a);
//~^ ERROR cannot borrow `*a` as mutable because previous closure requires unique access
outside_closure_2(a); //[ast]~ ERROR cannot borrow `*a` as immutable because previous closure requires unique access
//[mir]~^ ERROR cannot borrow `*a` as immutable because previous closure requires unique access
outside_closure_2(a);
//~^ ERROR cannot borrow `*a` as immutable because previous closure requires unique access
drop(bar);
}

View file

@ -1,5 +1,5 @@
error[E0501]: cannot borrow `*a` as mutable because previous closure requires unique access
--> $DIR/E0501.rs:18:23
--> $DIR/E0501.rs:14:23
|
LL | let bar = || {
| -- closure construction occurs here
@ -13,7 +13,7 @@ LL | drop(bar);
| --- first borrow later used here
error[E0501]: cannot borrow `*a` as immutable because previous closure requires unique access
--> $DIR/E0501.rs:21:23
--> $DIR/E0501.rs:17:23
|
LL | let bar = || {
| -- closure construction occurs here

View file

@ -1,11 +0,0 @@
error[E0506]: cannot assign to `fancy_num` because it is borrowed
--> $DIR/E0506.rs:11:5
|
LL | let fancy_ref = &fancy_num;
| --------- borrow of `fancy_num` occurs here
LL | fancy_num = FancyNum { num: 6 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `fancy_num` occurs here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0506`.

View file

@ -1,14 +0,0 @@
error[E0506]: cannot assign to `fancy_num` because it is borrowed
--> $DIR/E0506.rs:11:5
|
LL | let fancy_ref = &fancy_num;
| ---------- borrow of `fancy_num` occurs here
LL | fancy_num = FancyNum { num: 6 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `fancy_num` occurs here
...
LL | println!("Num: {}, Ref: {}", fancy_num.num, fancy_ref.num);
| ------------- borrow later used here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0506`.

View file

@ -1,6 +1,3 @@
// revisions: ast mir
//[mir]compile-flags: -Z borrowck=mir
struct FancyNum {
num: u8,
}
@ -8,8 +5,7 @@ struct FancyNum {
fn main() {
let mut fancy_num = FancyNum { num: 5 };
let fancy_ref = &fancy_num;
fancy_num = FancyNum { num: 6 }; //[ast]~ ERROR E0506
//[mir]~^ ERROR [E0506]
fancy_num = FancyNum { num: 6 }; //~ ERROR [E0506]
println!("Num: {}, Ref: {}", fancy_num.num, fancy_ref.num);
}

View file

@ -1,11 +1,11 @@
error[E0506]: cannot assign to `fancy_num` because it is borrowed
--> $DIR/E0506.rs:11:5
--> $DIR/E0506.rs:8:5
|
LL | let fancy_ref = &fancy_num;
| ---------- borrow of `fancy_num` occurs here
LL | fancy_num = FancyNum { num: 6 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `fancy_num` occurs here
...
LL |
LL | println!("Num: {}, Ref: {}", fancy_num.num, fancy_ref.num);
| ------------- borrow later used here

View file

@ -1,12 +0,0 @@
error[E0508]: cannot move out of type `[NonCopy; 1]`, a non-copy array
--> $DIR/E0508-fail.rs:8:18
|
LL | let _value = array[0];
| ^^^^^^^^
| |
| cannot move out of here
| help: consider borrowing here: `&array[0]`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0508`.

View file

@ -1,12 +0,0 @@
error[E0508]: cannot move out of type `[NonCopy; 1]`, a non-copy array
--> $DIR/E0508-fail.rs:8:18
|
LL | let _value = array[0];
| ^^^^^^^^
| |
| cannot move out of here
| help: consider using a reference instead: `&array[0]`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0508`.

View file

@ -1,12 +0,0 @@
error[E0508]: cannot move out of type `[NonCopy; 1]`, a non-copy array
--> $DIR/E0508-fail.rs:8:18
|
LL | let _value = array[0];
| ^^^^^^^^
| |
| cannot move out of here
| help: consider borrowing here: `&array[0]`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0508`.

View file

@ -1,10 +1,6 @@
// revisions: ast mir
//[mir]compile-flags: -Z borrowck=mir
struct NonCopy;
fn main() {
let array = [NonCopy; 1];
let _value = array[0]; //[ast]~ ERROR [E0508]
//[mir]~^ ERROR [E0508]
let _value = array[0]; //~ ERROR [E0508]
}

View file

@ -1,5 +1,5 @@
error[E0508]: cannot move out of type `[NonCopy; 1]`, a non-copy array
--> $DIR/E0508.rs:5:18
--> $DIR/E0508-fail.rs:5:18
|
LL | let _value = array[0];
| ^^^^^^^^

View file

@ -5,7 +5,7 @@ LL | let _value = array[0];
| ^^^^^^^^
| |
| cannot move out of here
| help: consider using a reference instead: `&array[0]`
| help: consider borrowing here: `&array[0]`
error: aborting due to previous error

View file

@ -1,8 +0,0 @@
error[E0594]: cannot assign to immutable static item
--> $DIR/E0594.rs:7:5
|
LL | NUM = 20;
| ^^^^^^^^
error: aborting due to previous error

View file

@ -1,8 +0,0 @@
error[E0594]: cannot assign to immutable static item `NUM`
--> $DIR/E0594.rs:7:5
|
LL | NUM = 20;
| ^^^^^^^^ cannot assign
error: aborting due to previous error

View file

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

View file

@ -1,5 +1,5 @@
error[E0594]: cannot assign to immutable static item `NUM`
--> $DIR/E0594.rs:7:5
--> $DIR/E0594.rs:4:5
|
LL | NUM = 20;
| ^^^^^^^^ cannot assign

View file

@ -1,11 +0,0 @@
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/E0596.rs:6:13
|
LL | let x = 1;
| - help: consider changing this to be mutable: `mut x`
LL | let y = &mut x;
| ^^^^^^ cannot borrow as mutable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0596`.

View file

@ -1,11 +0,0 @@
error[E0596]: cannot borrow immutable local variable `x` as mutable
--> $DIR/E0596.rs:6:18
|
LL | let x = 1;
| - help: make this binding mutable: `mut x`
LL | let y = &mut x;
| ^ cannot borrow mutably
error: aborting due to previous error
For more information about this error, try `rustc --explain E0596`.

View file

@ -1,8 +1,4 @@
// revisions: ast mir
//[mir]compile-flags: -Z borrowck=mir
fn main() {
let x = 1;
let y = &mut x; //[ast]~ ERROR [E0596]
//[mir]~^ ERROR [E0596]
let y = &mut x; //~ ERROR [E0596]
}

View file

@ -1,5 +1,5 @@
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/E0596.rs:6:13
--> $DIR/E0596.rs:3:13
|
LL | let x = 1;
| - help: consider changing this to be mutable: `mut x`

View file

@ -1,18 +0,0 @@
error[E0507]: cannot move out of borrowed content
--> $DIR/access-mode-in-closures.rs:8:15
|
LL | match *s { S(v) => v }
| ^^ - data moved here
| |
| cannot move out of borrowed content
| help: consider removing the `*`: `s`
|
note: move occurs because `v` has type `std::vec::Vec<isize>`, which does not implement the `Copy` trait
--> $DIR/access-mode-in-closures.rs:8:22
|
LL | match *s { S(v) => v }
| ^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0507`.

View file

@ -2,9 +2,16 @@ error[E0507]: cannot move out of borrowed content
--> $DIR/access-mode-in-closures.rs:8:15
|
LL | match *s { S(v) => v }
| ^^ - hint: to prevent move, use `ref v` or `ref mut v`
| ^^ - data moved here
| |
| cannot move out of borrowed content
| help: consider removing the `*`: `s`
|
note: move occurs because `v` has type `std::vec::Vec<isize>`, which does not implement the `Copy` trait
--> $DIR/access-mode-in-closures.rs:8:22
|
LL | match *s { S(v) => v }
| ^
error: aborting due to previous error

View file

@ -1,14 +0,0 @@
error[E0384]: cannot assign twice to immutable variable `x`
--> $DIR/asm-out-assign-imm.rs:24:34
|
LL | let x: isize;
| - help: make this binding mutable: `mut x`
LL | x = 1;
| ----- first assignment to `x`
...
LL | asm!("mov $1, $0" : "=r"(x) : "r"(5));
| ^ cannot assign twice to immutable variable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0384`.

View file

@ -1,6 +1,8 @@
error[E0384]: cannot assign twice to immutable variable `x`
--> $DIR/asm-out-assign-imm.rs:24:34
|
LL | let x: isize;
| - help: make this binding mutable: `mut x`
LL | x = 1;
| ----- first assignment to `x`
...

View file

@ -1,9 +0,0 @@
error[E0381]: use of possibly uninitialized variable: `x`
--> $DIR/asm-out-read-uninit.rs:25:43
|
LL | asm!("mov $1, $0" : "=r"(x) : "r"(x));
| ^ use of possibly uninitialized `x`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0381`.

View file

@ -8,9 +8,6 @@
// ignore-mips
// ignore-mips64
// revisions: ast mir
//[mir]compile-flags: -Z borrowck=mir
#![feature(asm)]
fn foo(x: isize) { println!("{}", x); }
@ -23,8 +20,7 @@ pub fn main() {
let x: isize;
unsafe {
asm!("mov $1, $0" : "=r"(x) : "r"(x));
//[ast]~^ ERROR use of possibly uninitialized variable: `x`
//[mir]~^^ ERROR use of possibly uninitialized variable: `x`
//~^ ERROR use of possibly uninitialized variable: `x`
}
foo(x);
}

View file

@ -1,5 +1,5 @@
error[E0381]: use of possibly uninitialized variable: `x`
--> $DIR/asm-out-read-uninit.rs:25:43
--> $DIR/asm-out-read-uninit.rs:22:43
|
LL | asm!("mov $1, $0" : "=r"(x) : "r"(x));
| ^ use of possibly uninitialized `x`

View file

@ -1,15 +0,0 @@
error[E0384]: cannot assign twice to immutable variable `v`
--> $DIR/assign-imm-local-twice.rs:11:5
|
LL | let v: isize;
| - help: make this binding mutable: `mut v`
...
LL | v = 1;
| ----- first assignment to `v`
...
LL | v = 2;
| ^^^^^ cannot assign twice to immutable variable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0384`.

View file

@ -1,12 +0,0 @@
error[E0384]: cannot assign twice to immutable variable `v`
--> $DIR/assign-imm-local-twice.rs:11:5
|
LL | v = 1;
| ----- first assignment to `v`
...
LL | v = 2;
| ^^^^^ cannot assign twice to immutable variable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0384`.

View file

@ -1,17 +1,11 @@
// revisions: ast mir
//[mir]compile-flags: -Zborrowck=mir
fn test() {
let v: isize;
//[mir]~^ HELP make this binding mutable
//[mir]~| SUGGESTION mut v
v = 1; //[ast]~ NOTE first assignment
//[mir]~^ NOTE first assignment
//~^ HELP make this binding mutable
//~| SUGGESTION mut v
v = 1; //~ NOTE first assignment
println!("v={}", v);
v = 2; //[ast]~ ERROR cannot assign twice to immutable variable
//[mir]~^ ERROR cannot assign twice to immutable variable `v`
//[ast]~| NOTE cannot assign twice to immutable
//[mir]~| NOTE cannot assign twice to immutable
v = 2; //~ ERROR cannot assign twice to immutable variable
//~| NOTE cannot assign twice to immutable
println!("v={}", v);
}

View file

@ -1,12 +1,12 @@
error[E0384]: cannot assign twice to immutable variable `v`
--> $DIR/assign-imm-local-twice.rs:11:5
--> $DIR/assign-imm-local-twice.rs:7:5
|
LL | let v: isize;
| - help: make this binding mutable: `mut v`
...
LL | v = 1;
| ----- first assignment to `v`
...
LL | println!("v={}", v);
LL | v = 2;
| ^^^^^ cannot assign twice to immutable variable

View file

@ -1,13 +0,0 @@
error[E0505]: cannot move out of `x` because it is borrowed
--> $DIR/associated-types-outlives.rs:22:14
|
LL | 's: loop { y = denormalise(&x); break }
| -- borrow of `x` occurs here
LL | drop(x);
| ^ move out of `x` occurs here
LL | return f(y);
| - borrow later used here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0505`.

View file

@ -2,9 +2,11 @@ error[E0505]: cannot move out of `x` because it is borrowed
--> $DIR/associated-types-outlives.rs:22:14
|
LL | 's: loop { y = denormalise(&x); break }
| - borrow of `x` occurs here
| -- borrow of `x` occurs here
LL | drop(x);
| ^ move out of `x` occurs here
LL | return f(y);
| - borrow later used here
error: aborting due to previous error

View file

@ -1,22 +0,0 @@
error[E0505]: cannot move out of `x` because it is borrowed
--> $DIR/augmented-assignments.rs:16:5
|
LL | x
| - borrow of `x` occurs here
...
LL | x;
| ^ move out of `x` occurs here
error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable
--> $DIR/augmented-assignments.rs:21:5
|
LL | let y = Int(2);
| - help: consider changing this to be mutable: `mut y`
...
LL | y
| ^ cannot borrow as mutable
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0505, E0596.
For more information about an error, try `rustc --explain E0505`.

View file

@ -10,16 +10,18 @@ impl AddAssign for Int {
fn main() {
let mut x = Int(1);
x //~ error: use of moved value: `x`
//~^ value used here after move
x
//~^ NOTE borrow of `x` occurs here
+=
x; //~ value moved here
x;
//~^ ERROR cannot move out of `x` because it is borrowed
//~| move out of `x` occurs here
let y = Int(2);
//~^ HELP make this binding mutable
//~^ HELP consider changing this to be mutable
//~| SUGGESTION mut y
y //~ error: cannot borrow immutable local variable `y` as mutable
//~| cannot borrow
y //~ ERROR cannot borrow `y` as mutable, as it is not declared as mutable
//~| cannot borrow as mutable
+=
Int(1);
}

View file

@ -1,24 +1,22 @@
error[E0596]: cannot borrow immutable local variable `y` as mutable
--> $DIR/augmented-assignments.rs:21:5
|
LL | let y = Int(2);
| - help: make this binding mutable: `mut y`
...
LL | y
| ^ cannot borrow mutably
error[E0382]: use of moved value: `x`
--> $DIR/augmented-assignments.rs:13:5
error[E0505]: cannot move out of `x` because it is borrowed
--> $DIR/augmented-assignments.rs:16:5
|
LL | x
| ^ value used here after move
| - borrow of `x` occurs here
...
LL | x;
| - value moved here
| ^ move out of `x` occurs here
error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable
--> $DIR/augmented-assignments.rs:23:5
|
= note: move occurs because `x` has type `Int`, which does not implement the `Copy` trait
LL | let y = Int(2);
| - help: consider changing this to be mutable: `mut y`
...
LL | y
| ^ cannot borrow as mutable
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0382, E0596.
For more information about an error, try `rustc --explain E0382`.
Some errors have detailed explanations: E0505, E0596.
For more information about an error, try `rustc --explain E0505`.

View file

@ -1,11 +0,0 @@
error[E0008]: cannot bind by-move into a pattern guard
--> $DIR/bind-by-move-no-guards.rs:8:14
|
LL | Some(z) if z.recv().unwrap() => { panic!() },
| ^ moves value into pattern guard
|
= help: add #![feature(bind_by_move_pattern_guards)] to the crate attributes to enable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0008`.

View file

@ -3,6 +3,8 @@ error[E0008]: cannot bind by-move into a pattern guard
|
LL | Some(z) if z.recv().unwrap() => { panic!() },
| ^ moves value into pattern guard
|
= help: add #![feature(bind_by_move_pattern_guards)] to the crate attributes to enable
error: aborting due to previous error

View file

@ -1,253 +0,0 @@
error[E0382]: use of moved value: `lhs`
--> $DIR/binop-consume-args.rs:7:10
|
LL | fn add<A: Add<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs + rhs;
| --- value moved here
LL | drop(lhs);
| ^^^ value used here after move
error[E0382]: use of moved value: `rhs`
--> $DIR/binop-consume-args.rs:8:10
|
LL | fn add<A: Add<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs + rhs;
| --- value moved here
LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
error[E0382]: use of moved value: `lhs`
--> $DIR/binop-consume-args.rs:13:10
|
LL | fn sub<A: Sub<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs - rhs;
| --- value moved here
LL | drop(lhs);
| ^^^ value used here after move
error[E0382]: use of moved value: `rhs`
--> $DIR/binop-consume-args.rs:14:10
|
LL | fn sub<A: Sub<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs - rhs;
| --- value moved here
LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
error[E0382]: use of moved value: `lhs`
--> $DIR/binop-consume-args.rs:19:10
|
LL | fn mul<A: Mul<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs * rhs;
| --- value moved here
LL | drop(lhs);
| ^^^ value used here after move
error[E0382]: use of moved value: `rhs`
--> $DIR/binop-consume-args.rs:20:10
|
LL | fn mul<A: Mul<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs * rhs;
| --- value moved here
LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
error[E0382]: use of moved value: `lhs`
--> $DIR/binop-consume-args.rs:25:10
|
LL | fn div<A: Div<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs / rhs;
| --- value moved here
LL | drop(lhs);
| ^^^ value used here after move
error[E0382]: use of moved value: `rhs`
--> $DIR/binop-consume-args.rs:26:10
|
LL | fn div<A: Div<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs / rhs;
| --- value moved here
LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
error[E0382]: use of moved value: `lhs`
--> $DIR/binop-consume-args.rs:31:10
|
LL | fn rem<A: Rem<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs % rhs;
| --- value moved here
LL | drop(lhs);
| ^^^ value used here after move
error[E0382]: use of moved value: `rhs`
--> $DIR/binop-consume-args.rs:32:10
|
LL | fn rem<A: Rem<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs % rhs;
| --- value moved here
LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
error[E0382]: use of moved value: `lhs`
--> $DIR/binop-consume-args.rs:37:10
|
LL | fn bitand<A: BitAnd<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs & rhs;
| --- value moved here
LL | drop(lhs);
| ^^^ value used here after move
error[E0382]: use of moved value: `rhs`
--> $DIR/binop-consume-args.rs:38:10
|
LL | fn bitand<A: BitAnd<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs & rhs;
| --- value moved here
LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
error[E0382]: use of moved value: `lhs`
--> $DIR/binop-consume-args.rs:43:10
|
LL | fn bitor<A: BitOr<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs | rhs;
| --- value moved here
LL | drop(lhs);
| ^^^ value used here after move
error[E0382]: use of moved value: `rhs`
--> $DIR/binop-consume-args.rs:44:10
|
LL | fn bitor<A: BitOr<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs | rhs;
| --- value moved here
LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
error[E0382]: use of moved value: `lhs`
--> $DIR/binop-consume-args.rs:49:10
|
LL | fn bitxor<A: BitXor<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs ^ rhs;
| --- value moved here
LL | drop(lhs);
| ^^^ value used here after move
error[E0382]: use of moved value: `rhs`
--> $DIR/binop-consume-args.rs:50:10
|
LL | fn bitxor<A: BitXor<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs ^ rhs;
| --- value moved here
LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
error[E0382]: use of moved value: `lhs`
--> $DIR/binop-consume-args.rs:55:10
|
LL | fn shl<A: Shl<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs << rhs;
| --- value moved here
LL | drop(lhs);
| ^^^ value used here after move
error[E0382]: use of moved value: `rhs`
--> $DIR/binop-consume-args.rs:56:10
|
LL | fn shl<A: Shl<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs << rhs;
| --- value moved here
LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
error[E0382]: use of moved value: `lhs`
--> $DIR/binop-consume-args.rs:61:10
|
LL | fn shr<A: Shr<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs >> rhs;
| --- value moved here
LL | drop(lhs);
| ^^^ value used here after move
error[E0382]: use of moved value: `rhs`
--> $DIR/binop-consume-args.rs:62:10
|
LL | fn shr<A: Shr<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs >> rhs;
| --- value moved here
LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
error: aborting due to 20 previous errors
For more information about this error, try `rustc --explain E0382`.

View file

@ -1,212 +1,252 @@
error[E0382]: use of moved value: `lhs`
--> $DIR/binop-consume-args.rs:7:10
|
LL | fn add<A: Add<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs + rhs;
| --- value moved here
LL | drop(lhs);
| ^^^ value used here after move
|
= note: move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `rhs`
--> $DIR/binop-consume-args.rs:8:10
|
LL | fn add<A: Add<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs + rhs;
| --- value moved here
LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
|
= note: move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `lhs`
--> $DIR/binop-consume-args.rs:13:10
|
LL | fn sub<A: Sub<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs - rhs;
| --- value moved here
LL | drop(lhs);
| ^^^ value used here after move
|
= note: move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `rhs`
--> $DIR/binop-consume-args.rs:14:10
|
LL | fn sub<A: Sub<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs - rhs;
| --- value moved here
LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
|
= note: move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `lhs`
--> $DIR/binop-consume-args.rs:19:10
|
LL | fn mul<A: Mul<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs * rhs;
| --- value moved here
LL | drop(lhs);
| ^^^ value used here after move
|
= note: move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `rhs`
--> $DIR/binop-consume-args.rs:20:10
|
LL | fn mul<A: Mul<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs * rhs;
| --- value moved here
LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
|
= note: move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `lhs`
--> $DIR/binop-consume-args.rs:25:10
|
LL | fn div<A: Div<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs / rhs;
| --- value moved here
LL | drop(lhs);
| ^^^ value used here after move
|
= note: move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `rhs`
--> $DIR/binop-consume-args.rs:26:10
|
LL | fn div<A: Div<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs / rhs;
| --- value moved here
LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
|
= note: move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `lhs`
--> $DIR/binop-consume-args.rs:31:10
|
LL | fn rem<A: Rem<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs % rhs;
| --- value moved here
LL | drop(lhs);
| ^^^ value used here after move
|
= note: move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `rhs`
--> $DIR/binop-consume-args.rs:32:10
|
LL | fn rem<A: Rem<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs % rhs;
| --- value moved here
LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
|
= note: move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `lhs`
--> $DIR/binop-consume-args.rs:37:10
|
LL | fn bitand<A: BitAnd<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs & rhs;
| --- value moved here
LL | drop(lhs);
| ^^^ value used here after move
|
= note: move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `rhs`
--> $DIR/binop-consume-args.rs:38:10
|
LL | fn bitand<A: BitAnd<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs & rhs;
| --- value moved here
LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
|
= note: move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `lhs`
--> $DIR/binop-consume-args.rs:43:10
|
LL | fn bitor<A: BitOr<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs | rhs;
| --- value moved here
LL | drop(lhs);
| ^^^ value used here after move
|
= note: move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `rhs`
--> $DIR/binop-consume-args.rs:44:10
|
LL | fn bitor<A: BitOr<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs | rhs;
| --- value moved here
LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
|
= note: move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `lhs`
--> $DIR/binop-consume-args.rs:49:10
|
LL | fn bitxor<A: BitXor<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs ^ rhs;
| --- value moved here
LL | drop(lhs);
| ^^^ value used here after move
|
= note: move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `rhs`
--> $DIR/binop-consume-args.rs:50:10
|
LL | fn bitxor<A: BitXor<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs ^ rhs;
| --- value moved here
LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
|
= note: move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `lhs`
--> $DIR/binop-consume-args.rs:55:10
|
LL | fn shl<A: Shl<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs << rhs;
| --- value moved here
LL | drop(lhs);
| ^^^ value used here after move
|
= note: move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `rhs`
--> $DIR/binop-consume-args.rs:56:10
|
LL | fn shl<A: Shl<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs << rhs;
| --- value moved here
LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
|
= note: move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `lhs`
--> $DIR/binop-consume-args.rs:61:10
|
LL | fn shr<A: Shr<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs >> rhs;
| --- value moved here
LL | drop(lhs);
| ^^^ value used here after move
|
= note: move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `rhs`
--> $DIR/binop-consume-args.rs:62:10
|
LL | fn shr<A: Shr<B, Output=()>, B>(lhs: A, rhs: B) {
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | lhs >> rhs;
| --- value moved here
LL | drop(lhs);
LL | drop(rhs);
| ^^^ value used here after move
|
= note: move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
error: aborting due to 20 previous errors

View file

@ -1,95 +0,0 @@
error[E0382]: use of moved value: `x`
--> $DIR/binop-move-semantics.rs:8:5
|
LL | fn double_move<T: Add<Output=()>>(x: T) {
| - - move occurs because `x` has type `T`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | x
| - value moved here
LL | +
LL | x;
| ^ value used here after move
error[E0382]: borrow of moved value: `x`
--> $DIR/binop-move-semantics.rs:14:5
|
LL | fn move_then_borrow<T: Add<Output=()> + Clone>(x: T) {
| - - move occurs because `x` has type `T`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | x
| - value moved here
LL | +
LL | x.clone();
| ^ value borrowed here after move
error[E0505]: cannot move out of `x` because it is borrowed
--> $DIR/binop-move-semantics.rs:21:5
|
LL | let m = &x;
| -- borrow of `x` occurs here
...
LL | x
| ^ move out of `x` occurs here
...
LL | use_mut(n); use_imm(m);
| - borrow later used here
error[E0505]: cannot move out of `y` because it is borrowed
--> $DIR/binop-move-semantics.rs:23:5
|
LL | let n = &mut y;
| ------ borrow of `y` occurs here
...
LL | y;
| ^ move out of `y` occurs here
LL | use_mut(n); use_imm(m);
| - borrow later used here
error[E0507]: cannot move out of borrowed content
--> $DIR/binop-move-semantics.rs:30:5
|
LL | *m
| ^^ cannot move out of borrowed content
error[E0507]: cannot move out of borrowed content
--> $DIR/binop-move-semantics.rs:32:5
|
LL | *n;
| ^^ cannot move out of borrowed content
error[E0502]: cannot borrow `f` as immutable because it is also borrowed as mutable
--> $DIR/binop-move-semantics.rs:54:5
|
LL | &mut f
| ------
| |
| _____mutable borrow occurs here
| |
LL | | +
LL | | &f;
| | ^-
| |_____||
| |mutable borrow later used here
| immutable borrow occurs here
error[E0502]: cannot borrow `f` as mutable because it is also borrowed as immutable
--> $DIR/binop-move-semantics.rs:62:5
|
LL | &f
| --
| |
| _____immutable borrow occurs here
| |
LL | | +
LL | | &mut f;
| | ^^^^^-
| |_____|____|
| | immutable borrow later used here
| mutable borrow occurs here
error: aborting due to 8 previous errors
Some errors have detailed explanations: E0382, E0502, E0505, E0507.
For more information about an error, try `rustc --explain E0382`.

View file

@ -11,7 +11,7 @@ fn double_move<T: Add<Output=()>>(x: T) {
fn move_then_borrow<T: Add<Output=()> + Clone>(x: T) {
x
+
x.clone(); //~ ERROR: use of moved value
x.clone(); //~ ERROR: borrow of moved value
}
fn move_borrowed<T: Add<Output=()>>(x: T, mut y: T) {

View file

@ -1,42 +1,51 @@
error[E0382]: use of moved value: `x`
--> $DIR/binop-move-semantics.rs:8:5
|
LL | fn double_move<T: Add<Output=()>>(x: T) {
| - - move occurs because `x` has type `T`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | x
| - value moved here
LL | +
LL | x;
| ^ value used here after move
|
= note: move occurs because `x` has type `T`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `x`
error[E0382]: borrow of moved value: `x`
--> $DIR/binop-move-semantics.rs:14:5
|
LL | fn move_then_borrow<T: Add<Output=()> + Clone>(x: T) {
| - - move occurs because `x` has type `T`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | x
| - value moved here
LL | +
LL | x.clone();
| ^ value used here after move
|
= note: move occurs because `x` has type `T`, which does not implement the `Copy` trait
| ^ value borrowed here after move
error[E0505]: cannot move out of `x` because it is borrowed
--> $DIR/binop-move-semantics.rs:21:5
|
LL | let m = &x;
| - borrow of `x` occurs here
| -- borrow of `x` occurs here
...
LL | x
| ^ move out of `x` occurs here
...
LL | use_mut(n); use_imm(m);
| - borrow later used here
error[E0505]: cannot move out of `y` because it is borrowed
--> $DIR/binop-move-semantics.rs:23:5
|
LL | let n = &mut y;
| - borrow of `y` occurs here
| ------ borrow of `y` occurs here
...
LL | y;
| ^ move out of `y` occurs here
LL | use_mut(n); use_imm(m);
| - borrow later used here
error[E0507]: cannot move out of borrowed content
--> $DIR/binop-move-semantics.rs:30:5
@ -51,28 +60,34 @@ LL | *n;
| ^^ cannot move out of borrowed content
error[E0502]: cannot borrow `f` as immutable because it is also borrowed as mutable
--> $DIR/binop-move-semantics.rs:54:6
--> $DIR/binop-move-semantics.rs:54:5
|
LL | &mut f
| - mutable borrow occurs here
LL | +
LL | &f;
| ^
| |
| immutable borrow occurs here
| mutable borrow ends here
LL | &mut f
| ------
| |
| _____mutable borrow occurs here
| |
LL | | +
LL | | &f;
| | ^-
| |_____||
| |mutable borrow later used here
| immutable borrow occurs here
error[E0502]: cannot borrow `f` as mutable because it is also borrowed as immutable
--> $DIR/binop-move-semantics.rs:62:10
--> $DIR/binop-move-semantics.rs:62:5
|
LL | &f
| - immutable borrow occurs here
LL | +
LL | &mut f;
| ^
| |
| mutable borrow occurs here
| immutable borrow ends here
LL | &f
| --
| |
| _____immutable borrow occurs here
| |
LL | | +
LL | | &mut f;
| | ^^^^^-
| |_____|____|
| | immutable borrow later used here
| mutable borrow occurs here
error: aborting due to 8 previous errors

View file

@ -1,15 +0,0 @@
error[E0381]: assign to part of possibly uninitialized variable: `x`
--> $DIR/assign_mutable_fields.rs:9:5
|
LL | x.0 = 1;
| ^^^^^^^ use of possibly uninitialized `x`
error[E0381]: assign to part of possibly uninitialized variable: `x`
--> $DIR/assign_mutable_fields.rs:17:5
|
LL | x.0 = 1;
| ^^^^^^^ use of possibly uninitialized `x`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0381`.

View file

@ -1,22 +1,22 @@
// Currently, we permit you to assign to individual fields of a mut
// var, but we do not permit you to use the complete var afterwards.
// Currently, we do permit you to assign to individual fields of an
// uninitialized var.
// We hope to fix this at some point.
//
// FIXME(#54987)
fn assign_both_fields_and_use() {
let mut x: (u32, u32);
x.0 = 1;
x.0 = 1; //~ ERROR
x.1 = 22;
drop(x.0); //~ ERROR
drop(x.1); //~ ERROR
drop(x.0);
drop(x.1);
}
fn assign_both_fields_the_use_var() {
let mut x: (u32, u32);
x.0 = 1;
x.0 = 1; //~ ERROR
x.1 = 22;
drop(x); //~ ERROR
drop(x);
}
fn main() { }

View file

@ -1,21 +1,15 @@
error[E0381]: use of possibly uninitialized variable: `x.0`
--> $DIR/assign_mutable_fields.rs:11:10
error[E0381]: assign to part of possibly uninitialized variable: `x`
--> $DIR/assign_mutable_fields.rs:9:5
|
LL | drop(x.0);
| ^^^ use of possibly uninitialized `x.0`
LL | x.0 = 1;
| ^^^^^^^ use of possibly uninitialized `x`
error[E0381]: use of possibly uninitialized variable: `x.1`
--> $DIR/assign_mutable_fields.rs:12:10
error[E0381]: assign to part of possibly uninitialized variable: `x`
--> $DIR/assign_mutable_fields.rs:17:5
|
LL | drop(x.1);
| ^^^ use of possibly uninitialized `x.1`
LL | x.0 = 1;
| ^^^^^^^ use of possibly uninitialized `x`
error[E0381]: use of possibly uninitialized variable: `x`
--> $DIR/assign_mutable_fields.rs:19:10
|
LL | drop(x);
| ^ use of possibly uninitialized `x`
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0381`.

View file

@ -1,75 +0,0 @@
error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure
--> $DIR/borrow-immutable-upvar-mutation.rs:15:27
|
LL | let _f = to_fn(|| x = 42);
| ^^^^^^ cannot assign
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/borrow-immutable-upvar-mutation.rs:15:24
|
LL | let _f = to_fn(|| x = 42);
| ^^^^^^^^^
error[E0596]: cannot borrow `y` as mutable, as it is a captured variable in a `Fn` closure
--> $DIR/borrow-immutable-upvar-mutation.rs:18:31
|
LL | let _g = to_fn(|| set(&mut y));
| ^^^^^^ cannot borrow as mutable
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/borrow-immutable-upvar-mutation.rs:18:24
|
LL | let _g = to_fn(|| set(&mut y));
| ^^^^^^^^^^^^^^
error[E0594]: cannot assign to `z`, as it is a captured variable in a `Fn` closure
--> $DIR/borrow-immutable-upvar-mutation.rs:21:55
|
LL | let _h = to_fn_mut(|| { set(&mut z); to_fn(|| z = 42); });
| ^^^^^^ cannot assign
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/borrow-immutable-upvar-mutation.rs:21:52
|
LL | let _h = to_fn_mut(|| { set(&mut z); to_fn(|| z = 42); });
| ^^^^^^^^^
error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure
--> $DIR/borrow-immutable-upvar-mutation.rs:27:32
|
LL | let _f = to_fn(move || x = 42);
| ^^^^^^ cannot assign
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/borrow-immutable-upvar-mutation.rs:27:24
|
LL | let _f = to_fn(move || x = 42);
| ^^^^^^^^^^^^^^
error[E0596]: cannot borrow `y` as mutable, as it is a captured variable in a `Fn` closure
--> $DIR/borrow-immutable-upvar-mutation.rs:30:36
|
LL | let _g = to_fn(move || set(&mut y));
| ^^^^^^ cannot borrow as mutable
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/borrow-immutable-upvar-mutation.rs:30:24
|
LL | let _g = to_fn(move || set(&mut y));
| ^^^^^^^^^^^^^^^^^^^
error[E0594]: cannot assign to `z`, as it is a captured variable in a `Fn` closure
--> $DIR/borrow-immutable-upvar-mutation.rs:33:65
|
LL | let _h = to_fn_mut(move || { set(&mut z); to_fn(move || z = 42); });
| ^^^^^^ cannot assign
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/borrow-immutable-upvar-mutation.rs:33:57
|
LL | let _h = to_fn_mut(move || { set(&mut z); to_fn(move || z = 42); });
| ^^^^^^^^^^^^^^
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0596`.

View file

@ -1,72 +1,70 @@
error[E0387]: cannot assign to data in a captured outer variable in an `Fn` closure
error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure
--> $DIR/borrow-immutable-upvar-mutation.rs:15:27
|
LL | let _f = to_fn(|| x = 42);
| ^^^^^^
| ^^^^^^ cannot assign
|
help: consider changing this closure to take self by mutable reference
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/borrow-immutable-upvar-mutation.rs:15:24
|
LL | let _f = to_fn(|| x = 42);
| ^^^^^^^^^
error[E0387]: cannot borrow data mutably in a captured outer variable in an `Fn` closure
--> $DIR/borrow-immutable-upvar-mutation.rs:18:36
error[E0596]: cannot borrow `y` as mutable, as it is a captured variable in a `Fn` closure
--> $DIR/borrow-immutable-upvar-mutation.rs:18:31
|
LL | let _g = to_fn(|| set(&mut y));
| ^
| ^^^^^^ cannot borrow as mutable
|
help: consider changing this closure to take self by mutable reference
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/borrow-immutable-upvar-mutation.rs:18:24
|
LL | let _g = to_fn(|| set(&mut y));
| ^^^^^^^^^^^^^^
error[E0387]: cannot assign to data in a captured outer variable in an `Fn` closure
error[E0594]: cannot assign to `z`, as it is a captured variable in a `Fn` closure
--> $DIR/borrow-immutable-upvar-mutation.rs:21:55
|
LL | let _h = to_fn_mut(|| { set(&mut z); to_fn(|| z = 42); });
| ^^^^^^
| ^^^^^^ cannot assign
|
help: consider changing this closure to take self by mutable reference
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/borrow-immutable-upvar-mutation.rs:21:52
|
LL | let _h = to_fn_mut(|| { set(&mut z); to_fn(|| z = 42); });
| ^^^^^^^^^
error[E0594]: cannot assign to captured outer variable in an `Fn` closure
error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure
--> $DIR/borrow-immutable-upvar-mutation.rs:27:32
|
LL | let _f = to_fn(move || x = 42);
| ^^^^^^
| ^^^^^^ cannot assign
|
= note: `Fn` closures cannot capture their enclosing environment for modifications
help: consider changing this closure to take self by mutable reference
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/borrow-immutable-upvar-mutation.rs:27:24
|
LL | let _f = to_fn(move || x = 42);
| ^^^^^^^^^^^^^^
error[E0596]: cannot borrow captured outer variable in an `Fn` closure as mutable
--> $DIR/borrow-immutable-upvar-mutation.rs:30:41
error[E0596]: cannot borrow `y` as mutable, as it is a captured variable in a `Fn` closure
--> $DIR/borrow-immutable-upvar-mutation.rs:30:36
|
LL | let _g = to_fn(move || set(&mut y));
| ^
| ^^^^^^ cannot borrow as mutable
|
help: consider changing this closure to take self by mutable reference
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/borrow-immutable-upvar-mutation.rs:30:24
|
LL | let _g = to_fn(move || set(&mut y));
| ^^^^^^^^^^^^^^^^^^^
error[E0594]: cannot assign to captured outer variable in an `Fn` closure
error[E0594]: cannot assign to `z`, as it is a captured variable in a `Fn` closure
--> $DIR/borrow-immutable-upvar-mutation.rs:33:65
|
LL | let _h = to_fn_mut(move || { set(&mut z); to_fn(move || z = 42); });
| ^^^^^^
| ^^^^^^ cannot assign
|
= note: `Fn` closures cannot capture their enclosing environment for modifications
help: consider changing this closure to take self by mutable reference
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/borrow-immutable-upvar-mutation.rs:33:57
|
LL | let _h = to_fn_mut(move || { set(&mut z); to_fn(move || z = 42); });
@ -74,5 +72,4 @@ LL | let _h = to_fn_mut(move || { set(&mut z); to_fn(move || z = 42); })
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0387, E0596.
For more information about an error, try `rustc --explain E0387`.
For more information about this error, try `rustc --explain E0596`.

View file

@ -1,65 +0,0 @@
error[E0505]: cannot move out of `x` because it is borrowed
--> $DIR/borrow-tuple-fields.rs:12:13
|
LL | let r = &x.0;
| ---- borrow of `x.0` occurs here
LL | let y = x;
| ^ move out of `x` occurs here
LL |
LL | r.use_ref();
| - borrow later used here
error[E0502]: cannot borrow `x.0` as mutable because it is also borrowed as immutable
--> $DIR/borrow-tuple-fields.rs:18:13
|
LL | let a = &x.0;
| ---- immutable borrow occurs here
LL | let b = &mut x.0;
| ^^^^^^^^ mutable borrow occurs here
LL | a.use_ref();
| - immutable borrow later used here
error[E0499]: cannot borrow `x.0` as mutable more than once at a time
--> $DIR/borrow-tuple-fields.rs:23:13
|
LL | let a = &mut x.0;
| -------- first mutable borrow occurs here
LL | let b = &mut x.0;
| ^^^^^^^^ second mutable borrow occurs here
LL | a.use_ref();
| - first borrow later used here
error[E0505]: cannot move out of `x` because it is borrowed
--> $DIR/borrow-tuple-fields.rs:28:13
|
LL | let r = &x.0;
| ---- borrow of `x.0` occurs here
LL | let y = x;
| ^ move out of `x` occurs here
LL | r.use_ref();
| - borrow later used here
error[E0502]: cannot borrow `x.0` as mutable because it is also borrowed as immutable
--> $DIR/borrow-tuple-fields.rs:33:13
|
LL | let a = &x.0;
| ---- immutable borrow occurs here
LL | let b = &mut x.0;
| ^^^^^^^^ mutable borrow occurs here
LL | a.use_ref();
| - immutable borrow later used here
error[E0499]: cannot borrow `x.0` as mutable more than once at a time
--> $DIR/borrow-tuple-fields.rs:38:13
|
LL | let a = &mut x.0;
| -------- first mutable borrow occurs here
LL | let b = &mut x.0;
| ^^^^^^^^ second mutable borrow occurs here
LL | a.use_mut();
| - first borrow later used here
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0499, E0502, E0505.
For more information about an error, try `rustc --explain E0499`.

View file

@ -1,62 +1,63 @@
error[E0505]: cannot move out of `x` because it is borrowed
--> $DIR/borrow-tuple-fields.rs:12:9
--> $DIR/borrow-tuple-fields.rs:12:13
|
LL | let r = &x.0;
| --- borrow of `x.0` occurs here
| ---- borrow of `x.0` occurs here
LL | let y = x;
| ^ move out of `x` occurs here
| ^ move out of `x` occurs here
LL |
LL | r.use_ref();
| - borrow later used here
error[E0502]: cannot borrow `x.0` as mutable because it is also borrowed as immutable
--> $DIR/borrow-tuple-fields.rs:18:18
--> $DIR/borrow-tuple-fields.rs:18:13
|
LL | let a = &x.0;
| --- immutable borrow occurs here
| ---- immutable borrow occurs here
LL | let b = &mut x.0;
| ^^^ mutable borrow occurs here
...
LL | }
| - immutable borrow ends here
| ^^^^^^^^ mutable borrow occurs here
LL | a.use_ref();
| - immutable borrow later used here
error[E0499]: cannot borrow `x.0` as mutable more than once at a time
--> $DIR/borrow-tuple-fields.rs:23:18
--> $DIR/borrow-tuple-fields.rs:23:13
|
LL | let a = &mut x.0;
| --- first mutable borrow occurs here
| -------- first mutable borrow occurs here
LL | let b = &mut x.0;
| ^^^ second mutable borrow occurs here
...
LL | }
| - first borrow ends here
| ^^^^^^^^ second mutable borrow occurs here
LL | a.use_ref();
| - first borrow later used here
error[E0505]: cannot move out of `x` because it is borrowed
--> $DIR/borrow-tuple-fields.rs:28:9
--> $DIR/borrow-tuple-fields.rs:28:13
|
LL | let r = &x.0;
| --- borrow of `x.0` occurs here
| ---- borrow of `x.0` occurs here
LL | let y = x;
| ^ move out of `x` occurs here
| ^ move out of `x` occurs here
LL | r.use_ref();
| - borrow later used here
error[E0502]: cannot borrow `x.0` as mutable because it is also borrowed as immutable
--> $DIR/borrow-tuple-fields.rs:33:18
--> $DIR/borrow-tuple-fields.rs:33:13
|
LL | let a = &x.0;
| --- immutable borrow occurs here
| ---- immutable borrow occurs here
LL | let b = &mut x.0;
| ^^^ mutable borrow occurs here
...
LL | }
| - immutable borrow ends here
| ^^^^^^^^ mutable borrow occurs here
LL | a.use_ref();
| - immutable borrow later used here
error[E0499]: cannot borrow `x.0` as mutable more than once at a time
--> $DIR/borrow-tuple-fields.rs:38:18
--> $DIR/borrow-tuple-fields.rs:38:13
|
LL | let a = &mut x.0;
| --- first mutable borrow occurs here
| -------- first mutable borrow occurs here
LL | let b = &mut x.0;
| ^^^ second mutable borrow occurs here
| ^^^^^^^^ second mutable borrow occurs here
LL | a.use_mut();
LL | }
| - first borrow ends here
| - first borrow later used here
error: aborting due to 6 previous errors

View file

@ -1,46 +0,0 @@
error[E0596]: cannot borrow immutable local variable `x` as mutable
--> $DIR/borrowck-access-permissions.rs:12:24
|
LL | let x = 1;
| - help: make this binding mutable: `mut x`
...
LL | let _y1 = &mut x;
| ^ cannot borrow mutably
error[E0596]: cannot borrow immutable static item as mutable
--> $DIR/borrowck-access-permissions.rs:18:24
|
LL | let _y1 = &mut static_x;
| ^^^^^^^^
error[E0596]: cannot borrow immutable `Box` content `*box_x` as mutable
--> $DIR/borrowck-access-permissions.rs:27:24
|
LL | let box_x = Box::new(1);
| ----- help: make this binding mutable: `mut box_x`
...
LL | let _y1 = &mut *box_x;
| ^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow immutable borrowed content `*ref_x` as mutable
--> $DIR/borrowck-access-permissions.rs:36:24
|
LL | let _y1 = &mut *ref_x;
| ^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow immutable dereference of raw pointer `*ptr_x` as mutable
--> $DIR/borrowck-access-permissions.rs:46:28
|
LL | let _y1 = &mut *ptr_x;
| ^^^^^^ cannot borrow as mutable
error[E0389]: cannot borrow data mutably in a `&` reference
--> $DIR/borrowck-access-permissions.rs:56:23
|
LL | let _y = &mut *foo_ref.f;
| ^^^^^^^^^^ assignment into an immutable reference
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0389, E0596.
For more information about an error, try `rustc --explain E0389`.

View file

@ -1,53 +0,0 @@
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/borrowck-access-permissions.rs:12:19
|
LL | let x = 1;
| - help: consider changing this to be mutable: `mut x`
...
LL | let _y1 = &mut x;
| ^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow immutable static item `static_x` as mutable
--> $DIR/borrowck-access-permissions.rs:18:19
|
LL | let _y1 = &mut static_x;
| ^^^^^^^^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow `*box_x` as mutable, as `box_x` is not declared as mutable
--> $DIR/borrowck-access-permissions.rs:27:19
|
LL | let box_x = Box::new(1);
| ----- help: consider changing this to be mutable: `mut box_x`
...
LL | let _y1 = &mut *box_x;
| ^^^^^^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow `*ref_x` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-access-permissions.rs:36:19
|
LL | let ref_x = &x;
| -- help: consider changing this to be a mutable reference: `&mut x`
...
LL | let _y1 = &mut *ref_x;
| ^^^^^^^^^^^ `ref_x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow `*ptr_x` as mutable, as it is behind a `*const` pointer
--> $DIR/borrowck-access-permissions.rs:46:23
|
LL | let ptr_x : *const _ = &x;
| -- help: consider changing this to be a mutable pointer: `&mut x`
...
LL | let _y1 = &mut *ptr_x;
| ^^^^^^^^^^^ `ptr_x` is a `*const` pointer, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow `*foo_ref.f` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-access-permissions.rs:56:18
|
LL | let foo_ref = &foo;
| ---- help: consider changing this to be a mutable reference: `&mut foo`
LL | let _y = &mut *foo_ref.f;
| ^^^^^^^^^^^^^^^ `foo_ref` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0596`.

View file

@ -1,6 +1,3 @@
// revisions: ast mir
//[mir]compile-flags: -Z borrowck=mir
static static_x : i32 = 1;
static mut static_x_mut : i32 = 1;
@ -9,14 +6,12 @@ fn main() {
let mut x_mut = 1;
{ // borrow of local
let _y1 = &mut x; //[ast]~ ERROR [E0596]
//[mir]~^ ERROR [E0596]
let _y1 = &mut x; //~ ERROR [E0596]
let _y2 = &mut x_mut; // No error
}
{ // borrow of static
let _y1 = &mut static_x; //[ast]~ ERROR [E0596]
//[mir]~^ ERROR [E0596]
let _y1 = &mut static_x; //~ ERROR [E0596]
unsafe { let _y2 = &mut static_x_mut; } // No error
}
@ -24,8 +19,7 @@ fn main() {
let box_x = Box::new(1);
let mut box_x_mut = Box::new(1);
let _y1 = &mut *box_x; //[ast]~ ERROR [E0596]
//[mir]~^ ERROR [E0596]
let _y1 = &mut *box_x; //~ ERROR [E0596]
let _y2 = &mut *box_x_mut; // No error
}
@ -33,8 +27,7 @@ fn main() {
let ref_x = &x;
let ref_x_mut = &mut x_mut;
let _y1 = &mut *ref_x; //[ast]~ ERROR [E0596]
//[mir]~^ ERROR [E0596]
let _y1 = &mut *ref_x; //~ ERROR [E0596]
let _y2 = &mut *ref_x_mut; // No error
}
@ -43,8 +36,7 @@ fn main() {
let ptr_mut_x : *mut _ = &mut x_mut;
unsafe {
let _y1 = &mut *ptr_x; //[ast]~ ERROR [E0596]
//[mir]~^ ERROR [E0596]
let _y1 = &mut *ptr_x; //~ ERROR [E0596]
let _y2 = &mut *ptr_mut_x; // No error
}
}
@ -53,8 +45,6 @@ fn main() {
struct Foo<'a> { f: &'a mut i32, g: &'a i32 };
let mut foo = Foo { f: &mut x_mut, g: &x };
let foo_ref = &foo;
let _y = &mut *foo_ref.f; //[ast]~ ERROR [E0389]
//[mir]~^ ERROR [E0596]
// FIXME: Wrong error in MIR
let _y = &mut *foo_ref.f; //~ ERROR [E0596]
}
}

View file

@ -1,5 +1,5 @@
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/borrowck-access-permissions.rs:12:19
--> $DIR/borrowck-access-permissions.rs:9:19
|
LL | let x = 1;
| - help: consider changing this to be mutable: `mut x`
@ -8,13 +8,13 @@ LL | let _y1 = &mut x;
| ^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow immutable static item `static_x` as mutable
--> $DIR/borrowck-access-permissions.rs:18:19
--> $DIR/borrowck-access-permissions.rs:14:19
|
LL | let _y1 = &mut static_x;
| ^^^^^^^^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow `*box_x` as mutable, as `box_x` is not declared as mutable
--> $DIR/borrowck-access-permissions.rs:27:19
--> $DIR/borrowck-access-permissions.rs:22:19
|
LL | let box_x = Box::new(1);
| ----- help: consider changing this to be mutable: `mut box_x`
@ -23,7 +23,7 @@ LL | let _y1 = &mut *box_x;
| ^^^^^^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow `*ref_x` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-access-permissions.rs:36:19
--> $DIR/borrowck-access-permissions.rs:30:19
|
LL | let ref_x = &x;
| -- help: consider changing this to be a mutable reference: `&mut x`
@ -32,7 +32,7 @@ LL | let _y1 = &mut *ref_x;
| ^^^^^^^^^^^ `ref_x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow `*ptr_x` as mutable, as it is behind a `*const` pointer
--> $DIR/borrowck-access-permissions.rs:46:23
--> $DIR/borrowck-access-permissions.rs:39:23
|
LL | let ptr_x : *const _ = &x;
| -- help: consider changing this to be a mutable pointer: `&mut x`
@ -41,7 +41,7 @@ LL | let _y1 = &mut *ptr_x;
| ^^^^^^^^^^^ `ptr_x` is a `*const` pointer, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow `*foo_ref.f` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-access-permissions.rs:56:18
--> $DIR/borrowck-access-permissions.rs:48:18
|
LL | let foo_ref = &foo;
| ---- help: consider changing this to be a mutable reference: `&mut foo`

View file

@ -1,9 +0,0 @@
error[E0381]: borrow of possibly uninitialized variable: `i`
--> $DIR/borrowck-and-init.rs:5:20
|
LL | println!("{}", i);
| ^ use of possibly uninitialized `i`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0381`.

View file

@ -2,5 +2,5 @@ fn main() {
let i: isize;
println!("{}", false && { i = 5; true });
println!("{}", i); //~ ERROR use of possibly uninitialized variable: `i`
println!("{}", i); //~ ERROR borrow of possibly uninitialized variable: `i`
}

View file

@ -1,4 +1,4 @@
error[E0381]: use of possibly uninitialized variable: `i`
error[E0381]: borrow of possibly uninitialized variable: `i`
--> $DIR/borrowck-and-init.rs:5:20
|
LL | println!("{}", i);

View file

@ -1,15 +0,0 @@
error[E0499]: cannot borrow `y.0` as mutable more than once at a time
--> $DIR/borrowck-anon-fields-struct.rs:29:11
|
LL | Y(ref mut a, _) => a
| --------- first mutable borrow occurs here
...
LL | Y(ref mut b, _) => b
| ^^^^^^^^^ second mutable borrow occurs here
...
LL | *a += 1;
| ------- first borrow later used here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0499`.

View file

@ -7,8 +7,8 @@ LL | Y(ref mut a, _) => a
LL | Y(ref mut b, _) => b
| ^^^^^^^^^ second mutable borrow occurs here
...
LL | }
| - first borrow ends here
LL | *a += 1;
| ------- first borrow later used here
error: aborting due to previous error

View file

@ -1,15 +0,0 @@
error[E0499]: cannot borrow `y.0` as mutable more than once at a time
--> $DIR/borrowck-anon-fields-tuple.rs:27:10
|
LL | (ref mut a, _) => a
| --------- first mutable borrow occurs here
...
LL | (ref mut b, _) => b
| ^^^^^^^^^ second mutable borrow occurs here
...
LL | *a += 1;
| ------- first borrow later used here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0499`.

View file

@ -7,8 +7,8 @@ LL | (ref mut a, _) => a
LL | (ref mut b, _) => b
| ^^^^^^^^^ second mutable borrow occurs here
...
LL | }
| - first borrow ends here
LL | *a += 1;
| ------- first borrow later used here
error: aborting due to previous error

View file

@ -1,43 +0,0 @@
warning[E0503]: cannot use `y` because it was mutably borrowed
--> $DIR/borrowck-anon-fields-variant.rs:17:7
|
LL | Foo::Y(ref mut a, _) => a,
| --------- borrow of `y.0` occurs here
...
LL | Foo::Y(_, ref mut b) => b,
| ^^^^^^^^^^^^^^^^^^^^ use of borrowed `y.0`
...
LL | *a += 1;
| ------- borrow later used here
|
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
error[E0503]: cannot use `y` because it was mutably borrowed
--> $DIR/borrowck-anon-fields-variant.rs:34:7
|
LL | Foo::Y(ref mut a, _) => a,
| --------- borrow of `y.0` occurs here
...
LL | Foo::Y(ref mut b, _) => b,
| ^^^^^^^^^^^^^^^^^^^^ use of borrowed `y.0`
...
LL | *a += 1;
| ------- borrow later used here
error[E0499]: cannot borrow `y.0` as mutable more than once at a time
--> $DIR/borrowck-anon-fields-variant.rs:34:14
|
LL | Foo::Y(ref mut a, _) => a,
| --------- first mutable borrow occurs here
...
LL | Foo::Y(ref mut b, _) => b,
| ^^^^^^^^^ second mutable borrow occurs here
...
LL | *a += 1;
| ------- first borrow later used here
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0499, E0503.
For more information about an error, try `rustc --explain E0499`.

View file

@ -1,6 +1,3 @@
// Tests that we are able to distinguish when loans borrow different
// anonymous fields of an enum variant vs the same anonymous field.
enum Foo {
X, Y(usize, usize)
}
@ -13,8 +10,14 @@ fn distinct_variant() {
Foo::X => panic!()
};
// While `a` and `b` are disjoint, borrowck doesn't know that `a` is not
// also used for the discriminant of `Foo`, which it would be if `a` was a
// reference.
let b = match y {
Foo::Y(_, ref mut b) => b,
//~^ WARNING cannot use `y`
//~| WARNING this error has been downgraded to a warning
//~| WARNING this warning will become a hard error in the future
Foo::X => panic!()
};
@ -31,7 +34,8 @@ fn same_variant() {
};
let b = match y {
Foo::Y(ref mut b, _) => b, //~ ERROR cannot borrow
Foo::Y(ref mut b, _) => b, //~ ERROR cannot use `y`
//~| ERROR cannot borrow `y.0` as mutable
Foo::X => panic!()
};

View file

@ -1,5 +1,32 @@
warning[E0503]: cannot use `y` because it was mutably borrowed
--> $DIR/borrowck-anon-fields-variant.rs:17:7
|
LL | Foo::Y(ref mut a, _) => a,
| --------- borrow of `y.0` occurs here
...
LL | Foo::Y(_, ref mut b) => b,
| ^^^^^^^^^^^^^^^^^^^^ use of borrowed `y.0`
...
LL | *a += 1;
| ------- borrow later used here
|
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
error[E0503]: cannot use `y` because it was mutably borrowed
--> $DIR/borrowck-anon-fields-variant.rs:37:7
|
LL | Foo::Y(ref mut a, _) => a,
| --------- borrow of `y.0` occurs here
...
LL | Foo::Y(ref mut b, _) => b,
| ^^^^^^^^^^^^^^^^^^^^ use of borrowed `y.0`
...
LL | *a += 1;
| ------- borrow later used here
error[E0499]: cannot borrow `y.0` as mutable more than once at a time
--> $DIR/borrowck-anon-fields-variant.rs:34:14
--> $DIR/borrowck-anon-fields-variant.rs:37:14
|
LL | Foo::Y(ref mut a, _) => a,
| --------- first mutable borrow occurs here
@ -7,9 +34,10 @@ LL | Foo::Y(ref mut a, _) => a,
LL | Foo::Y(ref mut b, _) => b,
| ^^^^^^^^^ second mutable borrow occurs here
...
LL | }
| - first borrow ends here
LL | *a += 1;
| ------- first borrow later used here
error: aborting due to previous error
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0499`.
Some errors have detailed explanations: E0499, E0503.
For more information about an error, try `rustc --explain E0499`.

View file

@ -1,35 +0,0 @@
error[E0596]: cannot borrow `arg` as mutable, as it is not declared as mutable
--> $DIR/borrowck-argument.rs:10:5
|
LL | fn func(arg: S) {
| --- help: consider changing this to be mutable: `mut arg`
LL | arg.mutate();
| ^^^ cannot borrow as mutable
error[E0596]: cannot borrow `arg` as mutable, as it is not declared as mutable
--> $DIR/borrowck-argument.rs:15:9
|
LL | fn method(&self, arg: S) {
| --- help: consider changing this to be mutable: `mut arg`
LL | arg.mutate();
| ^^^ cannot borrow as mutable
error[E0596]: cannot borrow `arg` as mutable, as it is not declared as mutable
--> $DIR/borrowck-argument.rs:21:9
|
LL | fn default(&self, arg: S) {
| --- help: consider changing this to be mutable: `mut arg`
LL | arg.mutate();
| ^^^ cannot borrow as mutable
error[E0596]: cannot borrow `arg` as mutable, as it is not declared as mutable
--> $DIR/borrowck-argument.rs:32:17
|
LL | (|arg: S| { arg.mutate() })(s);
| --- ^^^ cannot borrow as mutable
| |
| help: consider changing this to be mutable: `mut arg`
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0596`.

Some files were not shown because too many files have changed in this diff Show more