mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-02 11:44:28 +00:00
Auto merge of #43582 - ivanbakel:unused_mut_ref, r=arielb1
Fixed mutable vars being marked used when they weren't #### NB : bootstrapping is slow on my machine, even with `keep-stage` - fixes for occurances in the current codebase are <s>in the pipeline</s> done. This PR is being put up for review of the fix of the issue. Fixes #43526, Fixes #30280, Fixes #25049 ### Issue Whenever the compiler detected a mutable deref being used mutably, it marked an associated value as being used mutably as well. In the case of derefencing local variables which were mutable references, this incorrectly marked the reference itself being used mutably, instead of its contents - with the consequence of making the following code emit no warnings ``` fn do_thing<T>(mut arg : &mut T) { ... // don't touch arg - just deref it to access the T } ``` ### Fix Make dereferences not be counted as a mutable use, but only when they're on borrows on local variables. #### Why not on things other than local variables? * Whenever you capture a variable in a closure, it gets turned into a hidden reference - when you use it in the closure, it gets dereferenced. If the closure uses the variable mutably, that is actually a mutable use of the thing being dereffed to, so it has to be counted. * If you deref a mutable `Box` to access the contents mutably, you are using the `Box` mutably - so it has to be counted.
This commit is contained in:
commit
d21ec9b4ef
@ -1037,7 +1037,7 @@ impl<'a, K: 'a, V: 'a, NodeType>
|
||||
Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::KV> {
|
||||
|
||||
pub fn into_kv_mut(self) -> (&'a mut K, &'a mut V) {
|
||||
let (mut keys, mut vals) = self.node.into_slices_mut();
|
||||
let (keys, vals) = self.node.into_slices_mut();
|
||||
unsafe {
|
||||
(keys.get_unchecked_mut(self.idx), vals.get_unchecked_mut(self.idx))
|
||||
}
|
||||
@ -1047,7 +1047,7 @@ impl<'a, K: 'a, V: 'a, NodeType>
|
||||
impl<'a, K, V, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::KV> {
|
||||
pub fn kv_mut(&mut self) -> (&mut K, &mut V) {
|
||||
unsafe {
|
||||
let (mut keys, mut vals) = self.node.reborrow_mut().into_slices_mut();
|
||||
let (keys, vals) = self.node.reborrow_mut().into_slices_mut();
|
||||
(keys.get_unchecked_mut(self.idx), vals.get_unchecked_mut(self.idx))
|
||||
}
|
||||
}
|
||||
|
@ -1751,7 +1751,7 @@ impl<'a, T> IntoIterator for &'a mut Vec<T> {
|
||||
type Item = &'a mut T;
|
||||
type IntoIter = slice::IterMut<'a, T>;
|
||||
|
||||
fn into_iter(mut self) -> slice::IterMut<'a, T> {
|
||||
fn into_iter(self) -> slice::IterMut<'a, T> {
|
||||
self.iter_mut()
|
||||
}
|
||||
}
|
||||
|
@ -2394,7 +2394,7 @@ impl<'a, T> IntoIterator for &'a mut VecDeque<T> {
|
||||
type Item = &'a mut T;
|
||||
type IntoIter = IterMut<'a, T>;
|
||||
|
||||
fn into_iter(mut self) -> IterMut<'a, T> {
|
||||
fn into_iter(self) -> IterMut<'a, T> {
|
||||
self.iter_mut()
|
||||
}
|
||||
}
|
||||
@ -2558,7 +2558,7 @@ impl<'a, T> Place<T> for PlaceBack<'a, T> {
|
||||
impl<'a, T> InPlace<T> for PlaceBack<'a, T> {
|
||||
type Owner = &'a mut T;
|
||||
|
||||
unsafe fn finalize(mut self) -> &'a mut T {
|
||||
unsafe fn finalize(self) -> &'a mut T {
|
||||
let head = self.vec_deque.head;
|
||||
self.vec_deque.head = self.vec_deque.wrap_add(head, 1);
|
||||
&mut *(self.vec_deque.ptr().offset(head as isize))
|
||||
@ -2605,7 +2605,7 @@ impl<'a, T> Place<T> for PlaceFront<'a, T> {
|
||||
impl<'a, T> InPlace<T> for PlaceFront<'a, T> {
|
||||
type Owner = &'a mut T;
|
||||
|
||||
unsafe fn finalize(mut self) -> &'a mut T {
|
||||
unsafe fn finalize(self) -> &'a mut T {
|
||||
self.vec_deque.tail = self.vec_deque.wrap_sub(self.vec_deque.tail, 1);
|
||||
&mut *(self.vec_deque.ptr().offset(self.vec_deque.tail as isize))
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ mod impls {
|
||||
where F : FnMut<A>
|
||||
{
|
||||
type Output = F::Output;
|
||||
extern "rust-call" fn call_once(mut self, args: A) -> F::Output {
|
||||
extern "rust-call" fn call_once(self, args: A) -> F::Output {
|
||||
(*self).call_mut(args)
|
||||
}
|
||||
}
|
||||
|
@ -872,7 +872,7 @@ impl<'a, T> IntoIterator for &'a mut Option<T> {
|
||||
type Item = &'a mut T;
|
||||
type IntoIter = IterMut<'a, T>;
|
||||
|
||||
fn into_iter(mut self) -> IterMut<'a, T> {
|
||||
fn into_iter(self) -> IterMut<'a, T> {
|
||||
self.iter_mut()
|
||||
}
|
||||
}
|
||||
|
@ -909,7 +909,7 @@ impl<'a, T, E> IntoIterator for &'a mut Result<T, E> {
|
||||
type Item = &'a mut T;
|
||||
type IntoIter = IterMut<'a, T>;
|
||||
|
||||
fn into_iter(mut self) -> IterMut<'a, T> {
|
||||
fn into_iter(self) -> IterMut<'a, T> {
|
||||
self.iter_mut()
|
||||
}
|
||||
}
|
||||
|
@ -105,27 +105,27 @@ fn test_chunks_last() {
|
||||
|
||||
#[test]
|
||||
fn test_chunks_mut_count() {
|
||||
let mut v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
|
||||
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
|
||||
let c = v.chunks_mut(3);
|
||||
assert_eq!(c.count(), 2);
|
||||
|
||||
let mut v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
|
||||
let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
|
||||
let c2 = v2.chunks_mut(2);
|
||||
assert_eq!(c2.count(), 3);
|
||||
|
||||
let mut v3: &mut [i32] = &mut [];
|
||||
let v3: &mut [i32] = &mut [];
|
||||
let c3 = v3.chunks_mut(2);
|
||||
assert_eq!(c3.count(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_chunks_mut_nth() {
|
||||
let mut v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
|
||||
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
|
||||
let mut c = v.chunks_mut(2);
|
||||
assert_eq!(c.nth(1).unwrap()[1], 3);
|
||||
assert_eq!(c.next().unwrap()[0], 4);
|
||||
|
||||
let mut v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
|
||||
let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
|
||||
let mut c2 = v2.chunks_mut(3);
|
||||
assert_eq!(c2.nth(1).unwrap()[1], 4);
|
||||
assert_eq!(c2.next(), None);
|
||||
@ -194,7 +194,7 @@ fn get_range() {
|
||||
|
||||
#[test]
|
||||
fn get_mut_range() {
|
||||
let mut v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
|
||||
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
|
||||
assert_eq!(v.get_mut(..), Some(&mut [0, 1, 2, 3, 4, 5][..]));
|
||||
assert_eq!(v.get_mut(..2), Some(&mut [0, 1][..]));
|
||||
assert_eq!(v.get_mut(2..), Some(&mut [2, 3, 4, 5][..]));
|
||||
|
@ -415,8 +415,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
/// -------- this type is the same as a type argument in the other type, not highlighted
|
||||
/// ```
|
||||
fn highlight_outer(&self,
|
||||
mut value: &mut DiagnosticStyledString,
|
||||
mut other_value: &mut DiagnosticStyledString,
|
||||
value: &mut DiagnosticStyledString,
|
||||
other_value: &mut DiagnosticStyledString,
|
||||
name: String,
|
||||
sub: &ty::subst::Substs<'tcx>,
|
||||
pos: usize,
|
||||
|
@ -560,7 +560,7 @@ pub fn fully_normalize<'a, 'gcx, 'tcx, T>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||
{
|
||||
debug!("fully_normalize(value={:?})", value);
|
||||
|
||||
let mut selcx = &mut SelectionContext::new(infcx);
|
||||
let selcx = &mut SelectionContext::new(infcx);
|
||||
// FIXME (@jroesch) ISSUE 26721
|
||||
// I'm not sure if this is a bug or not, needs further investigation.
|
||||
// It appears that by reusing the fulfillment_cx here we incur more
|
||||
|
@ -494,7 +494,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
never_obligation.predicate = never_obligation.predicate.map_bound(|mut trait_pred| {
|
||||
// Swap out () with ! so we can check if the trait is impld for !
|
||||
{
|
||||
let mut trait_ref = &mut trait_pred.trait_ref;
|
||||
let trait_ref = &mut trait_pred.trait_ref;
|
||||
let unit_substs = trait_ref.substs;
|
||||
let mut never_substs = Vec::with_capacity(unit_substs.len());
|
||||
never_substs.push(From::from(tcx.types.never));
|
||||
|
@ -171,7 +171,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
||||
match self.sty {
|
||||
TyAdt(def, substs) => {
|
||||
{
|
||||
let mut substs_set = visited.entry(def.did).or_insert(FxHashSet::default());
|
||||
let substs_set = visited.entry(def.did).or_insert(FxHashSet::default());
|
||||
if !substs_set.insert(substs) {
|
||||
// We are already calculating the inhabitedness of this type.
|
||||
// The type must contain a reference to itself. Break the
|
||||
@ -193,7 +193,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
||||
}
|
||||
}
|
||||
let ret = def.uninhabited_from(visited, tcx, substs);
|
||||
let mut substs_set = visited.get_mut(&def.did).unwrap();
|
||||
let substs_set = visited.get_mut(&def.did).unwrap();
|
||||
substs_set.remove(substs);
|
||||
ret
|
||||
},
|
||||
|
@ -188,7 +188,7 @@ impl<'a> AllocFnFactory<'a> {
|
||||
fn arg_ty(&self,
|
||||
ty: &AllocatorTy,
|
||||
args: &mut Vec<Arg>,
|
||||
mut ident: &mut FnMut() -> Ident) -> P<Expr> {
|
||||
ident: &mut FnMut() -> Ident) -> P<Expr> {
|
||||
match *ty {
|
||||
AllocatorTy::Layout => {
|
||||
let usize = self.cx.path_ident(self.span, Ident::from_str("usize"));
|
||||
@ -263,7 +263,7 @@ impl<'a> AllocFnFactory<'a> {
|
||||
fn ret_ty(&self,
|
||||
ty: &AllocatorTy,
|
||||
args: &mut Vec<Arg>,
|
||||
mut ident: &mut FnMut() -> Ident,
|
||||
ident: &mut FnMut() -> Ident,
|
||||
expr: P<Expr>) -> (P<Ty>, P<Expr>)
|
||||
{
|
||||
match *ty {
|
||||
|
@ -436,20 +436,40 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
|
||||
//! For mutable loans of content whose mutability derives
|
||||
//! from a local variable, mark the mutability decl as necessary.
|
||||
|
||||
match loan_path.kind {
|
||||
LpVar(local_id) |
|
||||
LpUpvar(ty::UpvarId{ var_id: local_id, closure_expr_id: _ }) => {
|
||||
self.tcx().used_mut_nodes.borrow_mut().insert(local_id);
|
||||
}
|
||||
LpDowncast(ref base, _) |
|
||||
LpExtend(ref base, mc::McInherited, _) |
|
||||
LpExtend(ref base, mc::McDeclared, _) => {
|
||||
self.mark_loan_path_as_mutated(&base);
|
||||
}
|
||||
LpExtend(_, mc::McImmutable, _) => {
|
||||
// Nothing to do.
|
||||
let mut wrapped_path = Some(loan_path);
|
||||
let mut through_borrow = false;
|
||||
|
||||
while let Some(current_path) = wrapped_path {
|
||||
wrapped_path = match current_path.kind {
|
||||
LpVar(local_id) => {
|
||||
if !through_borrow {
|
||||
self.tcx().used_mut_nodes.borrow_mut().insert(local_id);
|
||||
}
|
||||
None
|
||||
}
|
||||
LpUpvar(ty::UpvarId{ var_id: local_id, closure_expr_id: _ }) => {
|
||||
self.tcx().used_mut_nodes.borrow_mut().insert(local_id);
|
||||
None
|
||||
}
|
||||
LpExtend(ref base, mc::McInherited, LpDeref(pointer_kind)) |
|
||||
LpExtend(ref base, mc::McDeclared, LpDeref(pointer_kind)) => {
|
||||
if pointer_kind != mc::Unique {
|
||||
through_borrow = true;
|
||||
}
|
||||
Some(base)
|
||||
}
|
||||
LpDowncast(ref base, _) |
|
||||
LpExtend(ref base, mc::McInherited, _) |
|
||||
LpExtend(ref base, mc::McDeclared, _) => {
|
||||
Some(base)
|
||||
}
|
||||
LpExtend(_, mc::McImmutable, _) => {
|
||||
// Nothing to do.
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub fn compute_gen_scope(&self,
|
||||
|
@ -98,7 +98,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) {
|
||||
let body_id = tcx.hir.body_owned_by(owner_id);
|
||||
let tables = tcx.typeck_tables_of(owner_def_id);
|
||||
let region_maps = tcx.region_maps(owner_def_id);
|
||||
let mut bccx = &mut BorrowckCtxt { tcx, tables, region_maps, owner_def_id };
|
||||
let bccx = &mut BorrowckCtxt { tcx, tables, region_maps, owner_def_id };
|
||||
|
||||
let body = bccx.tcx.hir.body(body_id);
|
||||
|
||||
|
@ -260,7 +260,7 @@ impl<'a, A: Array> Drop for Drain<'a, A> {
|
||||
let start = source_array_vec.len();
|
||||
let tail = self.tail_start;
|
||||
{
|
||||
let mut arr = &mut source_array_vec.values as &mut [ManuallyDrop<_>];
|
||||
let arr = &mut source_array_vec.values as &mut [ManuallyDrop<_>];
|
||||
let src = arr.as_ptr().offset(tail as isize);
|
||||
let dst = arr.as_mut_ptr().offset(start as isize);
|
||||
ptr::copy(src, dst, self.tail_len);
|
||||
|
@ -166,7 +166,7 @@ impl BitMatrix {
|
||||
pub fn add(&mut self, source: usize, target: usize) -> bool {
|
||||
let (start, _) = self.range(source);
|
||||
let (word, mask) = word_mask(target);
|
||||
let mut vector = &mut self.vector[..];
|
||||
let vector = &mut self.vector[..];
|
||||
let v1 = vector[start + word];
|
||||
let v2 = v1 | mask;
|
||||
vector[start + word] = v2;
|
||||
|
@ -259,7 +259,7 @@ impl<'a, I: Idx, T> IntoIterator for &'a mut IndexVec<I, T> {
|
||||
type IntoIter = slice::IterMut<'a, T>;
|
||||
|
||||
#[inline]
|
||||
fn into_iter(mut self) -> slice::IterMut<'a, T> {
|
||||
fn into_iter(self) -> slice::IterMut<'a, T> {
|
||||
self.raw.iter_mut()
|
||||
}
|
||||
}
|
||||
|
@ -422,7 +422,7 @@ fn show_content_with_pager(content: &String) {
|
||||
|
||||
match Command::new(pager_name).stdin(Stdio::piped()).spawn() {
|
||||
Ok(mut pager) => {
|
||||
if let Some(mut pipe) = pager.stdin.as_mut() {
|
||||
if let Some(pipe) = pager.stdin.as_mut() {
|
||||
if pipe.write_all(content.as_bytes()).is_err() {
|
||||
fallback_to_println = true;
|
||||
}
|
||||
|
@ -479,7 +479,7 @@ impl CrateStore for cstore::CStore {
|
||||
_ => {},
|
||||
}
|
||||
|
||||
let mut bfs_queue = &mut VecDeque::new();
|
||||
let bfs_queue = &mut VecDeque::new();
|
||||
let mut add_child = |bfs_queue: &mut VecDeque<_>, child: def::Export, parent: DefId| {
|
||||
let child = child.def.def_id();
|
||||
|
||||
|
@ -206,7 +206,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
self.schedule_drop(span, extent, &Lvalue::Local(local_id), var_ty);
|
||||
}
|
||||
|
||||
pub fn visit_bindings<F>(&mut self, pattern: &Pattern<'tcx>, mut f: &mut F)
|
||||
pub fn visit_bindings<F>(&mut self, pattern: &Pattern<'tcx>, f: &mut F)
|
||||
where F: FnMut(&mut Self, Mutability, Name, NodeId, Span, Ty<'tcx>)
|
||||
{
|
||||
match *pattern.kind {
|
||||
|
@ -721,7 +721,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||
value,
|
||||
obligations);
|
||||
|
||||
let mut fulfill_cx = &mut self.fulfillment_cx;
|
||||
let fulfill_cx = &mut self.fulfillment_cx;
|
||||
for obligation in obligations {
|
||||
fulfill_cx.register_predicate_obligation(self.infcx, obligation);
|
||||
}
|
||||
|
@ -781,7 +781,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
|
||||
hir::ItemTrait(.., ref trait_item_refs) => {
|
||||
self.check_item(item.id).generics().predicates();
|
||||
for trait_item_ref in trait_item_refs {
|
||||
let mut check = self.check_item(trait_item_ref.id.node_id);
|
||||
let check = self.check_item(trait_item_ref.id.node_id);
|
||||
check.generics().predicates();
|
||||
if trait_item_ref.kind != hir::AssociatedItemKind::Type ||
|
||||
trait_item_ref.defaultness.has_value() {
|
||||
@ -814,7 +814,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
|
||||
}
|
||||
hir::ItemImpl(.., ref trait_ref, _, ref impl_item_refs) => {
|
||||
{
|
||||
let mut check = self.check_item(item.id);
|
||||
let check = self.check_item(item.id);
|
||||
check.ty().generics().predicates();
|
||||
if trait_ref.is_some() {
|
||||
check.impl_trait_ref();
|
||||
|
@ -379,7 +379,7 @@ impl<'a> Resolver<'a> {
|
||||
// Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
|
||||
// during which the resolution might end up getting re-defined via a glob cycle.
|
||||
let (binding, t) = {
|
||||
let mut resolution = &mut *self.resolution(module, ident, ns).borrow_mut();
|
||||
let resolution = &mut *self.resolution(module, ident, ns).borrow_mut();
|
||||
let old_binding = resolution.binding();
|
||||
|
||||
let t = f(self, resolution);
|
||||
|
@ -1464,7 +1464,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
|
||||
let mut output = i.to_string(scx.tcx());
|
||||
output.push_str(" @@");
|
||||
let mut empty = Vec::new();
|
||||
let mut cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
|
||||
let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
|
||||
cgus.as_mut_slice().sort_by_key(|&(ref name, _)| name.clone());
|
||||
cgus.dedup();
|
||||
for &(ref cgu_name, (linkage, _)) in cgus.iter() {
|
||||
|
@ -335,7 +335,7 @@ fn place_root_translation_items<'a, 'tcx, I>(scx: &SharedCrateContext<'a, 'tcx>,
|
||||
CodegenUnit::empty(codegen_unit_name.clone())
|
||||
};
|
||||
|
||||
let mut codegen_unit = codegen_units.entry(codegen_unit_name.clone())
|
||||
let codegen_unit = codegen_units.entry(codegen_unit_name.clone())
|
||||
.or_insert_with(make_codegen_unit);
|
||||
|
||||
let (linkage, visibility) = match trans_item.explicit_linkage(tcx) {
|
||||
|
@ -70,7 +70,7 @@ impl TimeGraph {
|
||||
{
|
||||
let mut table = self.data.lock().unwrap();
|
||||
|
||||
let mut data = table.entry(timeline).or_insert(PerThread {
|
||||
let data = table.entry(timeline).or_insert(PerThread {
|
||||
timings: Vec::new(),
|
||||
open_work_package: None,
|
||||
});
|
||||
@ -90,7 +90,7 @@ impl TimeGraph {
|
||||
let end = Instant::now();
|
||||
|
||||
let mut table = self.data.lock().unwrap();
|
||||
let mut data = table.get_mut(&timeline).unwrap();
|
||||
let data = table.get_mut(&timeline).unwrap();
|
||||
|
||||
if let Some((start, work_package_kind)) = data.open_work_package {
|
||||
data.timings.push(Timing {
|
||||
|
@ -1204,7 +1204,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(mut augment_error) = augment_error {
|
||||
if let Some(augment_error) = augment_error {
|
||||
augment_error(&mut db);
|
||||
}
|
||||
|
||||
|
@ -556,7 +556,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
||||
// We can't use normalize_associated_types_in as it will pollute the
|
||||
// fcx's fulfillment context after this probe is over.
|
||||
let cause = traits::ObligationCause::misc(self.span, self.body_id);
|
||||
let mut selcx = &mut traits::SelectionContext::new(self.fcx);
|
||||
let selcx = &mut traits::SelectionContext::new(self.fcx);
|
||||
let traits::Normalized { value: xform_self_ty, obligations } =
|
||||
traits::normalize(selcx, self.param_env, cause, &xform_self_ty);
|
||||
debug!("assemble_inherent_impl_probe: xform_self_ty = {:?}",
|
||||
@ -765,7 +765,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
||||
// as it will pollute the fcx's fulfillment context after this probe
|
||||
// is over.
|
||||
let cause = traits::ObligationCause::misc(self.span, self.body_id);
|
||||
let mut selcx = &mut traits::SelectionContext::new(self.fcx);
|
||||
let selcx = &mut traits::SelectionContext::new(self.fcx);
|
||||
let traits::Normalized { value: xform_self_ty, obligations } =
|
||||
traits::normalize(selcx, self.param_env, cause, &xform_self_ty);
|
||||
|
||||
|
@ -4183,8 +4183,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
|
||||
|
||||
let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
|
||||
let mut ctxt = enclosing_breakables.find_breakable(blk.id);
|
||||
let mut coerce = ctxt.coerce.as_mut().unwrap();
|
||||
let ctxt = enclosing_breakables.find_breakable(blk.id);
|
||||
let coerce = ctxt.coerce.as_mut().unwrap();
|
||||
if let Some(tail_expr_ty) = tail_expr_ty {
|
||||
let tail_expr = tail_expr.unwrap();
|
||||
let cause = self.cause(tail_expr.span,
|
||||
|
@ -300,7 +300,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
lhs_expr: &'gcx hir::Expr,
|
||||
lhs_ty: Ty<'tcx>,
|
||||
rhs_ty: Ty<'tcx>,
|
||||
mut err: &mut errors::DiagnosticBuilder) -> bool {
|
||||
err: &mut errors::DiagnosticBuilder) -> bool {
|
||||
// If this function returns true it means a note was printed, so we don't need
|
||||
// to print the normal "implementation of `std::ops::Add` might be missing" note
|
||||
let mut is_string_addition = false;
|
||||
|
@ -1618,7 +1618,7 @@ impl<'a, K, V, S> IntoIterator for &'a mut HashMap<K, V, S>
|
||||
type Item = (&'a K, &'a mut V);
|
||||
type IntoIter = IterMut<'a, K, V>;
|
||||
|
||||
fn into_iter(mut self) -> IterMut<'a, K, V> {
|
||||
fn into_iter(self) -> IterMut<'a, K, V> {
|
||||
self.iter_mut()
|
||||
}
|
||||
}
|
||||
|
@ -563,7 +563,7 @@ impl<'t, K, V> FullBucket<K, V, &'t mut RawTable<K, V>> {
|
||||
///
|
||||
/// This works similarly to `put`, building an `EmptyBucket` out of the
|
||||
/// taken bucket.
|
||||
pub fn take(mut self) -> (EmptyBucket<K, V, &'t mut RawTable<K, V>>, K, V) {
|
||||
pub fn take(self) -> (EmptyBucket<K, V, &'t mut RawTable<K, V>>, K, V) {
|
||||
self.table.size -= 1;
|
||||
|
||||
unsafe {
|
||||
|
@ -514,7 +514,7 @@ mod tests {
|
||||
#[test]
|
||||
fn downcasting() {
|
||||
let mut a = A;
|
||||
let mut a = &mut a as &mut (Error + 'static);
|
||||
let a = &mut a as &mut (Error + 'static);
|
||||
assert_eq!(a.downcast_ref::<A>(), Some(&A));
|
||||
assert_eq!(a.downcast_ref::<B>(), None);
|
||||
assert_eq!(a.downcast_mut::<A>(), Some(&mut A));
|
||||
|
@ -456,7 +456,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_slice_reader() {
|
||||
let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7];
|
||||
let mut reader = &mut &in_buf[..];
|
||||
let reader = &mut &in_buf[..];
|
||||
let mut buf = [];
|
||||
assert_eq!(reader.read(&mut buf).unwrap(), 0);
|
||||
let mut buf = [0];
|
||||
|
@ -267,7 +267,7 @@ impl Once {
|
||||
#[cold]
|
||||
fn call_inner(&'static self,
|
||||
ignore_poisoning: bool,
|
||||
mut init: &mut FnMut(bool)) {
|
||||
init: &mut FnMut(bool)) {
|
||||
let mut state = self.state.load(Ordering::SeqCst);
|
||||
|
||||
'outer: loop {
|
||||
|
@ -12,13 +12,13 @@ pub use self::imp::OsRng;
|
||||
|
||||
use mem;
|
||||
|
||||
fn next_u32(mut fill_buf: &mut FnMut(&mut [u8])) -> u32 {
|
||||
fn next_u32(fill_buf: &mut FnMut(&mut [u8])) -> u32 {
|
||||
let mut buf: [u8; 4] = [0; 4];
|
||||
fill_buf(&mut buf);
|
||||
unsafe { mem::transmute::<[u8; 4], u32>(buf) }
|
||||
}
|
||||
|
||||
fn next_u64(mut fill_buf: &mut FnMut(&mut [u8])) -> u64 {
|
||||
fn next_u64(fill_buf: &mut FnMut(&mut [u8])) -> u64 {
|
||||
let mut buf: [u8; 8] = [0; 8];
|
||||
fill_buf(&mut buf);
|
||||
unsafe { mem::transmute::<[u8; 8], u64>(buf) }
|
||||
|
@ -768,8 +768,8 @@ fn symlink_junction_inner(target: &Path, junction: &Path) -> io::Result<()> {
|
||||
|
||||
unsafe {
|
||||
let mut data = [0u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
|
||||
let mut db = data.as_mut_ptr()
|
||||
as *mut c::REPARSE_MOUNTPOINT_DATA_BUFFER;
|
||||
let db = data.as_mut_ptr()
|
||||
as *mut c::REPARSE_MOUNTPOINT_DATA_BUFFER;
|
||||
let buf = &mut (*db).ReparseTarget as *mut _;
|
||||
let mut i = 0;
|
||||
// FIXME: this conversion is very hacky
|
||||
|
@ -211,7 +211,7 @@ pub enum NamedMatch {
|
||||
|
||||
fn nameize<I: Iterator<Item=NamedMatch>>(sess: &ParseSess, ms: &[TokenTree], mut res: I)
|
||||
-> NamedParseResult {
|
||||
fn n_rec<I: Iterator<Item=NamedMatch>>(sess: &ParseSess, m: &TokenTree, mut res: &mut I,
|
||||
fn n_rec<I: Iterator<Item=NamedMatch>>(sess: &ParseSess, m: &TokenTree, res: &mut I,
|
||||
ret_val: &mut HashMap<Ident, Rc<NamedMatch>>)
|
||||
-> Result<(), (syntax_pos::Span, String)> {
|
||||
match *m {
|
||||
@ -445,7 +445,7 @@ pub fn parse(sess: &ParseSess,
|
||||
/* error messages here could be improved with links to orig. rules */
|
||||
if token_name_eq(&parser.token, &token::Eof) {
|
||||
if eof_items.len() == 1 {
|
||||
let matches = eof_items[0].matches.iter_mut().map(|mut dv| {
|
||||
let matches = eof_items[0].matches.iter_mut().map(|dv| {
|
||||
Rc::make_mut(dv).pop().unwrap()
|
||||
});
|
||||
return nameize(sess, ms, matches);
|
||||
|
@ -86,7 +86,7 @@ impl TTMacroExpander for MacroRulesMacroExpander {
|
||||
|
||||
fn trace_macros_note(cx: &mut ExtCtxt, sp: Span, message: String) {
|
||||
let sp = sp.macro_backtrace().last().map(|trace| trace.call_site).unwrap_or(sp);
|
||||
let mut values: &mut Vec<String> = cx.expansions.entry(sp).or_insert_with(Vec::new);
|
||||
let values: &mut Vec<String> = cx.expansions.entry(sp).or_insert_with(Vec::new);
|
||||
values.push(message);
|
||||
}
|
||||
|
||||
|
@ -529,7 +529,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||
|
||||
/// Actually builds the expression which the format_args! block will be
|
||||
/// expanded to
|
||||
fn into_expr(mut self) -> P<ast::Expr> {
|
||||
fn into_expr(self) -> P<ast::Expr> {
|
||||
let mut locals = Vec::new();
|
||||
let mut counts = Vec::new();
|
||||
let mut pats = Vec::new();
|
||||
|
@ -47,6 +47,26 @@ fn main() {
|
||||
let x = |mut y: isize| 10; //~ ERROR: variable does not need to be mutable
|
||||
fn what(mut foo: isize) {} //~ ERROR: variable does not need to be mutable
|
||||
|
||||
let mut a = &mut 5; //~ ERROR: variable does not need to be mutable
|
||||
*a = 4;
|
||||
|
||||
let mut a = 5;
|
||||
let mut b = (&mut a,);
|
||||
*b.0 = 4; //~^ ERROR: variable does not need to be mutable
|
||||
|
||||
let mut x = &mut 1; //~ ERROR: variable does not need to be mutable
|
||||
let mut f = || {
|
||||
*x += 1;
|
||||
};
|
||||
f();
|
||||
|
||||
fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] {
|
||||
&mut arg[..] //~^ ERROR: variable does not need to be mutable
|
||||
}
|
||||
|
||||
let mut v : &mut Vec<()> = &mut vec![]; //~ ERROR: variable does not need to be mutable
|
||||
v.push(());
|
||||
|
||||
// positive cases
|
||||
let mut a = 2;
|
||||
a = 3;
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 305bc25d5e105e84ffe261655b46cf74570f6e5b
|
||||
Subproject commit 7704f7b1fd52607104cc7fdc435d636c9de1fe90
|
Loading…
Reference in New Issue
Block a user