Skip to content

Commit 99f6cb1

Browse files
committed
Add a note for implicit temporaries on &mut (fn or const)
1 parent bfffe40 commit 99f6cb1

File tree

14 files changed

+43
-14
lines changed

14 files changed

+43
-14
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1836,6 +1836,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
18361836
"value referencing"
18371837
};
18381838

1839+
let mut implicit_temporary = None;
1840+
18391841
let (place_desc, note) = if let Some(place_desc) = opt_place_desc {
18401842
let local_kind = if let Some(local) = borrow.borrowed_place.as_local() {
18411843
match self.body.local_kind(local) {
@@ -1861,7 +1863,22 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
18611863
let root_place =
18621864
self.prefixes(borrow.borrowed_place.as_ref(), PrefixSet::All).last().unwrap();
18631865
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 {
18651882
LocalKind::ReturnPointer | LocalKind::Temp => {
18661883
("temporary value".to_string(), "temporary value created here".to_string())
18671884
}
@@ -1906,6 +1923,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
19061923
}
19071924
}
19081925

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+
19091933
Some(err)
19101934
}
19111935

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,8 @@ pub enum LocalInfo<'tcx> {
900900
StaticRef { def_id: DefId, is_thread_local: bool },
901901
/// A temporary created that references the const with the given `DefId`
902902
ConstRef { def_id: DefId },
903+
/// A temporary created that references a function
904+
FnDefRef,
903905
/// A temporary created during the creation of an aggregate
904906
/// (e.g. a temporary for `foo` in `MyStruct { my_field: foo }`)
905907
AggregateTemp,

compiler/rustc_middle/src/thir.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -432,8 +432,8 @@ pub enum ExprKind<'tcx> {
432432
lit: ty::ScalarInt,
433433
user_ty: UserTy<'tcx>,
434434
},
435-
/// A literal of a ZST type.
436-
ZstLiteral {
435+
/// Named functions, associated functions, and constructors (including `Self(...)`)
436+
NamedFn {
437437
user_ty: UserTy<'tcx>,
438438
},
439439
/// Associated constants and named constants

compiler/rustc_middle/src/thir/visit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
136136
}) => {}
137137
Literal { lit: _, neg: _ } => {}
138138
NonHirLiteral { lit: _, user_ty: _ } => {}
139-
ZstLiteral { user_ty: _ } => {}
139+
NamedFn { user_ty: _ } => {}
140140
NamedConst { def_id: _, substs: _, user_ty: _ } => {}
141141
ConstParam { param: _, def_id: _ } => {}
142142
StaticRef { alloc_id: _, ty: _, def_id: _ } => {}

compiler/rustc_mir_build/src/build/custom/parse/instruction.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
153153
ExprKind::Literal { .. }
154154
| ExprKind::NamedConst { .. }
155155
| ExprKind::NonHirLiteral { .. }
156-
| ExprKind::ZstLiteral { .. }
156+
| ExprKind::NamedFn { .. }
157157
| ExprKind::ConstParam { .. }
158158
| ExprKind::ConstBlock { .. } => {
159159
Ok(Operand::Constant(Box::new(

compiler/rustc_mir_build/src/build/expr/as_constant.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ pub fn as_constant_inner<'tcx>(
6868

6969
Constant { span, user_ty, literal }
7070
}
71-
ExprKind::ZstLiteral { ref user_ty } => {
71+
ExprKind::NamedFn { ref user_ty } => {
7272
let user_ty = user_ty.as_ref().map(push_cuta).flatten();
7373

7474
let literal = ConstantKind::Val(ConstValue::ZeroSized, ty);

compiler/rustc_mir_build/src/build/expr/as_place.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
554554
| ExprKind::Literal { .. }
555555
| ExprKind::NamedConst { .. }
556556
| ExprKind::NonHirLiteral { .. }
557-
| ExprKind::ZstLiteral { .. }
557+
| ExprKind::NamedFn { .. }
558558
| ExprKind::ConstParam { .. }
559559
| ExprKind::ConstBlock { .. }
560560
| ExprKind::StaticRef { .. }

compiler/rustc_mir_build/src/build/expr/as_rvalue.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
459459
ExprKind::Literal { .. }
460460
| ExprKind::NamedConst { .. }
461461
| ExprKind::NonHirLiteral { .. }
462-
| ExprKind::ZstLiteral { .. }
462+
| ExprKind::NamedFn { .. }
463463
| ExprKind::ConstParam { .. }
464464
| ExprKind::ConstBlock { .. }
465465
| ExprKind::StaticRef { .. } => {

compiler/rustc_mir_build/src/build/expr/as_temp.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
7070
ExprKind::NamedConst { def_id, .. } | ExprKind::ConstParam { def_id, .. } => {
7171
local_decl.local_info = Some(Box::new(LocalInfo::ConstRef { def_id }));
7272
}
73+
ExprKind::NamedFn { .. } => {
74+
local_decl.local_info = Some(Box::new(LocalInfo::FnDefRef));
75+
}
7376
_ => {}
7477
}
7578
this.local_decls.push(local_decl)

compiler/rustc_mir_build/src/build/expr/category.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl Category {
7272
ExprKind::ConstBlock { .. }
7373
| ExprKind::Literal { .. }
7474
| ExprKind::NonHirLiteral { .. }
75-
| ExprKind::ZstLiteral { .. }
75+
| ExprKind::NamedFn { .. }
7676
| ExprKind::ConstParam { .. }
7777
| ExprKind::StaticRef { .. }
7878
| ExprKind::NamedConst { .. } => Some(Category::Constant),

compiler/rustc_mir_build/src/build/expr/into.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
554554
| ExprKind::Literal { .. }
555555
| ExprKind::NamedConst { .. }
556556
| ExprKind::NonHirLiteral { .. }
557-
| ExprKind::ZstLiteral { .. }
557+
| ExprKind::NamedFn { .. }
558558
| ExprKind::ConstParam { .. }
559559
| ExprKind::ThreadLocalRef(_)
560560
| ExprKind::StaticRef { .. } => {

compiler/rustc_mir_build/src/check_unsafety.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
295295
| ExprKind::Literal { .. }
296296
| ExprKind::NamedConst { .. }
297297
| ExprKind::NonHirLiteral { .. }
298-
| ExprKind::ZstLiteral { .. }
298+
| ExprKind::NamedFn { .. }
299299
| ExprKind::ConstParam { .. }
300300
| ExprKind::ConstBlock { .. }
301301
| ExprKind::Deref { .. }

compiler/rustc_mir_build/src/thir/cx/expr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,7 @@ impl<'tcx> Cx<'tcx> {
822822
)
823823
}
824824
};
825-
Expr { temp_lifetime, ty, span, kind: ExprKind::ZstLiteral { user_ty } }
825+
Expr { temp_lifetime, ty, span, kind: ExprKind::NamedFn { user_ty } }
826826
}
827827

828828
fn convert_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) -> ArmId {
@@ -851,7 +851,7 @@ impl<'tcx> Cx<'tcx> {
851851
| Res::Def(DefKind::Ctor(_, CtorKind::Fn), _)
852852
| Res::SelfCtor(_) => {
853853
let user_ty = self.user_substs_applied_to_res(expr.hir_id, res);
854-
ExprKind::ZstLiteral { user_ty }
854+
ExprKind::NamedFn { user_ty }
855855
}
856856

857857
Res::Def(DefKind::ConstParam, def_id) => {

compiler/rustc_ty_utils/src/consts.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ fn recurse_build<'tcx>(
127127
let val = ty::ValTree::from_scalar_int(lit);
128128
tcx.mk_const(val, node.ty)
129129
}
130-
&ExprKind::ZstLiteral { user_ty: _ } => {
130+
&ExprKind::NamedFn { user_ty: _ } => {
131131
let val = ty::ValTree::zst();
132132
tcx.mk_const(val, node.ty)
133133
}

0 commit comments

Comments
 (0)