@@ -1836,6 +1836,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
1836
1836
"value referencing"
1837
1837
} ;
1838
1838
1839
+ let mut implicit_temporary = None ;
1840
+
1839
1841
let ( place_desc, note) = if let Some ( place_desc) = opt_place_desc {
1840
1842
let local_kind = if let Some ( local) = borrow. borrowed_place . as_local ( ) {
1841
1843
match self . body . local_kind ( local) {
@@ -1861,7 +1863,22 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
1861
1863
let root_place =
1862
1864
self . prefixes ( borrow. borrowed_place . as_ref ( ) , PrefixSet :: All ) . last ( ) . unwrap ( ) ;
1863
1865
let local = root_place. local ;
1864
- match self . body . local_kind ( local) {
1866
+ let local_kind = self . body . local_kind ( local) ;
1867
+ if let LocalKind :: Temp = local_kind {
1868
+ // Mutable references to constants and functions will implicitly create
1869
+ // temporaries, even though immutable references don't. We use these below to add a
1870
+ // note about this.
1871
+ match & self . body . local_decls [ local] . local_info {
1872
+ Some ( box LocalInfo :: FnDefRef ) => {
1873
+ implicit_temporary = Some ( ( "function" , "function pointer" ) ) ;
1874
+ }
1875
+ Some ( box LocalInfo :: ConstRef { .. } ) => {
1876
+ implicit_temporary = Some ( ( "constant" , "value" ) ) ;
1877
+ }
1878
+ _ => { }
1879
+ }
1880
+ }
1881
+ match local_kind {
1865
1882
LocalKind :: ReturnPointer | LocalKind :: Temp => {
1866
1883
( "temporary value" . to_string ( ) , "temporary value created here" . to_string ( ) )
1867
1884
}
@@ -1906,6 +1923,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
1906
1923
}
1907
1924
}
1908
1925
1926
+ if let Some ( ( item_name, value_desc) ) = implicit_temporary {
1927
+ err. note ( format ! (
1928
+ "mutably borrowing a {} implicitly copies the {} to a temporary" ,
1929
+ item_name, value_desc
1930
+ ) ) ;
1931
+ }
1932
+
1909
1933
Some ( err)
1910
1934
}
1911
1935
0 commit comments