diff options
| author | Mara Bos <m-ou.se@m-ou.se> | 2020-11-08 13:36:33 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-11-08 13:36:33 +0100 |
| commit | 91759b2de528f95289596e94c69b88a1927a94e0 (patch) | |
| tree | 543bc6807689dcf1da90dc4d25e5f3ddb1e7a32a /compiler | |
| parent | c4e262ee6f35ac8d501eedc4a52d3b7c779b21fe (diff) | |
| parent | bd3f3fa32a7ffe30b47625edc4c6bf814aed4964 (diff) | |
| download | rust-91759b2de528f95289596e94c69b88a1927a94e0.tar.gz rust-91759b2de528f95289596e94c69b88a1927a94e0.zip | |
Rollup merge of #78865 - Aaron1011:fix/const-item-mut-reborrow, r=varkor
Don't fire `CONST_ITEM_MUTATION` lint when borrowing a deref Fixes #78819 This extends the check for dereferences added in PR #77324 to cover mutable borrows, as well as direct writes. If we're operating on a dereference of a `const` item, we shouldn't be firing the lint.
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_mir/src/transform/check_const_item_mutation.rs | 51 |
1 files changed, 30 insertions, 21 deletions
diff --git a/compiler/rustc_mir/src/transform/check_const_item_mutation.rs b/compiler/rustc_mir/src/transform/check_const_item_mutation.rs index fb89b36060a..a8457043278 100644 --- a/compiler/rustc_mir/src/transform/check_const_item_mutation.rs +++ b/compiler/rustc_mir/src/transform/check_const_item_mutation.rs @@ -61,22 +61,35 @@ impl<'a, 'tcx> ConstMutationChecker<'a, 'tcx> { fn lint_const_item_usage( &self, + place: &Place<'tcx>, const_item: DefId, location: Location, decorate: impl for<'b> FnOnce(LintDiagnosticBuilder<'b>) -> DiagnosticBuilder<'b>, ) { - let source_info = self.body.source_info(location); - let lint_root = self.body.source_scopes[source_info.scope] - .local_data - .as_ref() - .assert_crate_local() - .lint_root; + // Don't lint on borrowing/assigning to a dereference + // e.g: + // + // `unsafe { *FOO = 0; *BAR.field = 1; }` + // `unsafe { &mut *FOO }` + if !matches!(place.projection.last(), Some(PlaceElem::Deref)) { + let source_info = self.body.source_info(location); + let lint_root = self.body.source_scopes[source_info.scope] + .local_data + .as_ref() + .assert_crate_local() + .lint_root; - self.tcx.struct_span_lint_hir(CONST_ITEM_MUTATION, lint_root, source_info.span, |lint| { - decorate(lint) - .span_note(self.tcx.def_span(const_item), "`const` item defined here") - .emit() - }); + self.tcx.struct_span_lint_hir( + CONST_ITEM_MUTATION, + lint_root, + source_info.span, + |lint| { + decorate(lint) + .span_note(self.tcx.def_span(const_item), "`const` item defined here") + .emit() + }, + ); + } } } @@ -88,15 +101,11 @@ impl<'a, 'tcx> Visitor<'tcx> for ConstMutationChecker<'a, 'tcx> { // so emitting a lint would be redundant. if !lhs.projection.is_empty() { if let Some(def_id) = self.is_const_item_without_destructor(lhs.local) { - // Don't lint on writes through a pointer - // (e.g. `unsafe { *FOO = 0; *BAR.field = 1; }`) - if !matches!(lhs.projection.last(), Some(PlaceElem::Deref)) { - self.lint_const_item_usage(def_id, loc, |lint| { - let mut lint = lint.build("attempting to modify a `const` item"); - lint.note("each usage of a `const` item creates a new temporary - the original `const` item will not be modified"); - lint - }) - } + self.lint_const_item_usage(&lhs, def_id, loc, |lint| { + let mut lint = lint.build("attempting to modify a `const` item"); + lint.note("each usage of a `const` item creates a new temporary; the original `const` item will not be modified"); + lint + }) } } // We are looking for MIR of the form: @@ -127,7 +136,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ConstMutationChecker<'a, 'tcx> { }); let lint_loc = if method_did.is_some() { self.body.terminator_loc(loc.block) } else { loc }; - self.lint_const_item_usage(def_id, lint_loc, |lint| { + self.lint_const_item_usage(place, def_id, lint_loc, |lint| { let mut lint = lint.build("taking a mutable reference to a `const` item"); lint .note("each usage of a `const` item creates a new temporary") |
