@@ -241,7 +241,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
241241 access_place_error_reported : FxHashSet ( ) ,
242242 reservation_error_reported : FxHashSet ( ) ,
243243 moved_error_reported : FxHashSet ( ) ,
244- nonlexical_regioncx : opt_regioncx ,
244+ nonlexical_regioncx : regioncx ,
245245 used_mut : FxHashSet ( ) ,
246246 used_mut_upvars : SmallVec :: new ( ) ,
247247 nonlexical_cause_info : None ,
@@ -276,7 +276,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
276276
277277 tcx. struct_span_lint_node (
278278 UNUSED_MUT ,
279- vsi[ source_info . scope ] . lint_root ,
279+ vsi[ local_decl . syntactic_scope ] . lint_root ,
280280 source_info. span ,
281281 "variable does not need to be mutable"
282282 )
@@ -1366,7 +1366,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
13661366 ) {
13671367 debug ! ( "check_if_reassignment_to_immutable_state({:?})" , place) ;
13681368 // determine if this path has a non-mut owner (and thus needs checking).
1369- if let Ok ( ( ) ) = self . is_mutable ( place, LocalMutationIsAllowed :: No ) {
1369+ if let Ok ( _ ) = self . is_mutable ( place, LocalMutationIsAllowed :: No ) {
13701370 return ;
13711371 }
13721372 debug ! (
@@ -1679,27 +1679,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
16791679 }
16801680 }
16811681 Reservation ( WriteKind :: MutableBorrow ( BorrowKind :: Mut { .. } ) )
1682- | Write ( WriteKind :: MutableBorrow ( BorrowKind :: Mut { .. } ) ) => if let Err ( place_err) =
1683- self . is_mutable ( place, is_local_mutation_allowed)
1684- {
1685- error_reported = true ;
1686- let item_msg = self . get_default_err_msg ( place) ;
1687- let mut err = self . tcx
1688- . cannot_borrow_path_as_mutable ( span, & item_msg, Origin :: Mir ) ;
1689- err. span_label ( span, "cannot borrow as mutable" ) ;
1690-
1691- if place != place_err {
1692- if let Some ( name) = self . describe_place ( place_err) {
1693- err. note ( & format ! ( "the value which is causing this path not to be mutable \
1694- is...: `{}`", name) ) ;
1695- }
1696- }
1697-
1698- err. emit ( ) ;
1699- } ,
1700- Reservation ( WriteKind :: Mutate ) | Write ( WriteKind :: Mutate ) => {
1701- match place {
1702- Place :: Local ( local) => {
1682+ | Write ( WriteKind :: MutableBorrow ( BorrowKind :: Mut { .. } ) ) => {
1683+ match self . is_mutable ( place, is_local_mutation_allowed) {
1684+ Ok ( Place :: Local ( local) )
1685+ if is_local_mutation_allowed != LocalMutationIsAllowed :: Yes =>
1686+ {
17031687 // If the local may be initialized, and it is now currently being
17041688 // mutated, then it is justified to be annotated with the `mut` keyword,
17051689 // since the mutation may be a possible reassignment.
@@ -1708,77 +1692,118 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
17081692 self . used_mut . insert ( * local) ;
17091693 }
17101694 }
1711- Place :: Projection ( ref proj) => {
1695+ Ok ( Place :: Projection ( ref proj) ) => {
17121696 if let Some ( field) = self . is_upvar_field_projection ( & proj. base ) {
17131697 self . used_mut_upvars . push ( field) ;
17141698 }
17151699 }
1716- Place :: Static ( ..) => { }
1717- }
1718- if let Err ( place_err) = self . is_mutable ( place, is_local_mutation_allowed) {
1719- error_reported = true ;
1720- let mut err_info = None ;
1721- match * place_err {
1722-
1723- Place :: Projection ( box Projection {
1724- ref base, elem : ProjectionElem :: Deref } ) => {
1725- match * base {
1726- Place :: Local ( local) => {
1727- let locations = self . mir . find_assignments ( local) ;
1728- if locations. len ( ) > 0 {
1729- let item_msg = if error_reported {
1730- self . get_secondary_err_msg ( base)
1731- } else {
1732- self . get_default_err_msg ( place)
1733- } ;
1734- let sp = self . mir . source_info ( locations[ 0 ] ) . span ;
1735- let mut to_suggest_span = String :: new ( ) ;
1736- if let Ok ( src) =
1737- self . tcx . sess . codemap ( ) . span_to_snippet ( sp) {
1738- to_suggest_span = src[ 1 ..] . to_string ( ) ;
1739- } ;
1740- err_info = Some ( (
1741- sp,
1742- "consider changing this to be a \
1743- mutable reference",
1744- to_suggest_span,
1745- item_msg,
1746- self . get_primary_err_msg ( base) ) ) ;
1747- }
1748- } ,
1749- _ => { } ,
1750- }
1751- } ,
1752- _ => { } ,
1753- }
1700+ Ok ( Place :: Local ( _) ) |
1701+ Ok ( Place :: Static ( ..) ) => { }
1702+ Err ( place_err) => {
1703+ error_reported = true ;
1704+ let item_msg = self . get_default_err_msg ( place) ;
1705+ let mut err = self . tcx
1706+ . cannot_borrow_path_as_mutable ( span, & item_msg, Origin :: Mir ) ;
1707+ err. span_label ( span, "cannot borrow as mutable" ) ;
17541708
1755- if let Some ( ( err_help_span,
1756- err_help_stmt,
1757- to_suggest_span,
1758- item_msg,
1759- sec_span) ) = err_info {
1760- let mut err = self . tcx . cannot_assign ( span, & item_msg, Origin :: Mir ) ;
1761- err. span_suggestion ( err_help_span,
1762- err_help_stmt,
1763- format ! ( "&mut {}" , to_suggest_span) ) ;
1764- if place != place_err {
1765- err. span_label ( span, sec_span) ;
1766- }
1767- err. emit ( )
1768- } else {
1769- let item_msg_ = self . get_default_err_msg ( place) ;
1770- let mut err = self . tcx . cannot_assign ( span, & item_msg_, Origin :: Mir ) ;
1771- err. span_label ( span, "cannot mutate" ) ;
17721709 if place != place_err {
17731710 if let Some ( name) = self . describe_place ( place_err) {
17741711 err. note ( & format ! ( "the value which is causing this path not to be \
1775- mutable is...: `{}`", name) ) ;
1712+ mutable is...: `{}`", name) ) ;
17761713 }
17771714 }
1715+
17781716 err. emit ( ) ;
17791717 }
17801718 }
17811719 }
1720+ Reservation ( WriteKind :: Mutate ) | Write ( WriteKind :: Mutate ) => {
1721+ match self . is_mutable ( place, is_local_mutation_allowed) {
1722+ Ok ( Place :: Local ( local) )
1723+ if is_local_mutation_allowed != LocalMutationIsAllowed :: Yes =>
1724+ {
1725+ // If the local may be initialized, and it is now currently being
1726+ // mutated, then it is justified to be annotated with the `mut` keyword,
1727+ // since the mutation may be a possible reassignment.
1728+ let mpi = self . move_data . rev_lookup . find_local ( * local) ;
1729+ if flow_state. inits . contains ( & mpi) {
1730+ self . used_mut . insert ( * local) ;
1731+ }
1732+ }
1733+ Ok ( Place :: Projection ( ref proj) ) => {
1734+ if let Some ( field) = self . is_upvar_field_projection ( & proj. base ) {
1735+ self . used_mut_upvars . push ( field) ;
1736+ }
1737+ }
1738+ Ok ( Place :: Local ( _) ) |
1739+ Ok ( Place :: Static ( ..) ) => { }
1740+ Err ( place_err) => {
1741+ error_reported = true ;
1742+
1743+ let err_info = if let Place :: Projection (
1744+ box Projection {
1745+ ref base,
1746+ elem : ProjectionElem :: Deref
1747+ }
1748+ ) = * place_err {
1749+ if let Place :: Local ( local) = * base {
1750+ let locations = self . mir . find_assignments ( local) ;
1751+ if locations. len ( ) > 0 {
1752+ let item_msg = if error_reported {
1753+ self . get_secondary_err_msg ( base)
1754+ } else {
1755+ self . get_default_err_msg ( place)
1756+ } ;
1757+ let sp = self . mir . source_info ( locations[ 0 ] ) . span ;
1758+ let mut to_suggest_span = String :: new ( ) ;
1759+ if let Ok ( src) =
1760+ self . tcx . sess . codemap ( ) . span_to_snippet ( sp) {
1761+ to_suggest_span = src[ 1 ..] . to_string ( ) ;
1762+ } ;
1763+ Some ( ( sp,
1764+ "consider changing this to be a \
1765+ mutable reference",
1766+ to_suggest_span,
1767+ item_msg,
1768+ self . get_primary_err_msg ( base) ) )
1769+ } else {
1770+ None
1771+ }
1772+ } else {
1773+ None
1774+ }
1775+ } else {
1776+ None
1777+ } ;
1778+
1779+ if let Some ( ( err_help_span,
1780+ err_help_stmt,
1781+ to_suggest_span,
1782+ item_msg,
1783+ sec_span) ) = err_info {
1784+ let mut err = self . tcx . cannot_assign ( span, & item_msg, Origin :: Mir ) ;
1785+ err. span_suggestion ( err_help_span,
1786+ err_help_stmt,
1787+ format ! ( "&mut {}" , to_suggest_span) ) ;
1788+ if place != place_err {
1789+ err. span_label ( span, sec_span) ;
1790+ }
1791+ err. emit ( )
1792+ } else {
1793+ let item_msg = self . get_default_err_msg ( place) ;
1794+ let mut err = self . tcx . cannot_assign ( span, & item_msg, Origin :: Mir ) ;
1795+ err. span_label ( span, "cannot mutate" ) ;
1796+ if place != place_err {
1797+ if let Some ( name) = self . describe_place ( place_err) {
1798+ err. note ( & format ! ( "the value which is causing this path not \
1799+ to be mutable is...: `{}`", name) ) ;
1800+ }
1801+ }
1802+ err. emit ( ) ;
1803+ }
1804+ }
1805+ }
1806+ }
17821807 Reservation ( WriteKind :: Move )
17831808 | Reservation ( WriteKind :: StorageDeadOrDrop )
17841809 | Reservation ( WriteKind :: MutableBorrow ( BorrowKind :: Shared ) )
@@ -1810,25 +1835,25 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
18101835 & self ,
18111836 place : & ' d Place < ' tcx > ,
18121837 is_local_mutation_allowed : LocalMutationIsAllowed ,
1813- ) -> Result < ( ) , & ' d Place < ' tcx > > {
1838+ ) -> Result < & ' d Place < ' tcx > , & ' d Place < ' tcx > > {
18141839 match * place {
18151840 Place :: Local ( local) => {
18161841 let local = & self . mir . local_decls [ local] ;
18171842 match local. mutability {
18181843 Mutability :: Not => match is_local_mutation_allowed {
18191844 LocalMutationIsAllowed :: Yes | LocalMutationIsAllowed :: ExceptUpvars => {
1820- Ok ( ( ) )
1845+ Ok ( place )
18211846 }
18221847 LocalMutationIsAllowed :: No => Err ( place) ,
18231848 } ,
1824- Mutability :: Mut => Ok ( ( ) ) ,
1849+ Mutability :: Mut => Ok ( place ) ,
18251850 }
18261851 }
18271852 Place :: Static ( ref static_) =>
18281853 if self . tcx . is_static ( static_. def_id ) != Some ( hir:: Mutability :: MutMutable ) {
18291854 Err ( place)
18301855 } else {
1831- Ok ( ( ) )
1856+ Ok ( place )
18321857 } ,
18331858 Place :: Projection ( ref proj) => {
18341859 match proj. elem {
@@ -1866,7 +1891,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
18661891 hir:: MutImmutable => return Err ( place) ,
18671892 // `*mut` raw pointers are always mutable, regardless of context
18681893 // The users have to check by themselve.
1869- hir:: MutMutable => return Ok ( ( ) ) ,
1894+ hir:: MutMutable => return Ok ( place ) ,
18701895 }
18711896 }
18721897 // `Box<T>` owns its content, so mutable if its location is mutable
0 commit comments