Auto merge of #75573 - Aaron1011:feature/const-mutation-lint, r=oli-obk
Add CONST_ITEM_MUTATION lint Fixes #74053 Fixes #55721 This PR adds a new lint `CONST_ITEM_MUTATION`. Given an item `const FOO: SomeType = ..`, this lint fires on: * Attempting to write directly to a field (`FOO.field = some_val`) or array entry (`FOO.array_field[0] = val`) * Taking a mutable reference to the `const` item (`&mut FOO`), including through an autoderef `FOO.some_mut_self_method()` The lint message explains that since each use of a constant creates a new temporary, the original `const` item will not be modified.
This commit is contained in:
commit
88197214b8
22 changed files with 427 additions and 116 deletions
|
@ -21,7 +21,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
let Expr { ty, temp_lifetime: _, span, kind } = expr;
|
||||
match kind {
|
||||
ExprKind::Scope { region_scope: _, lint_level: _, value } => this.as_constant(value),
|
||||
ExprKind::Literal { literal, user_ty } => {
|
||||
ExprKind::Literal { literal, user_ty, const_id: _ } => {
|
||||
let user_ty = user_ty.map(|user_ty| {
|
||||
this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
|
||||
span,
|
||||
|
|
|
@ -76,6 +76,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
local_decl.local_info =
|
||||
Some(box LocalInfo::StaticRef { def_id, is_thread_local: true });
|
||||
}
|
||||
ExprKind::Literal { const_id: Some(def_id), .. } => {
|
||||
local_decl.local_info = Some(box LocalInfo::ConstRef { def_id });
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
this.local_decls.push(local_decl)
|
||||
|
|
|
@ -247,6 +247,7 @@ fn make_mirror_unadjusted<'a, 'tcx>(
|
|||
hir::ExprKind::Lit(ref lit) => ExprKind::Literal {
|
||||
literal: cx.const_eval_literal(&lit.node, expr_ty, lit.span, false),
|
||||
user_ty: None,
|
||||
const_id: None,
|
||||
},
|
||||
|
||||
hir::ExprKind::Binary(op, ref lhs, ref rhs) => {
|
||||
|
@ -306,6 +307,7 @@ fn make_mirror_unadjusted<'a, 'tcx>(
|
|||
ExprKind::Literal {
|
||||
literal: cx.const_eval_literal(&lit.node, expr_ty, lit.span, true),
|
||||
user_ty: None,
|
||||
const_id: None,
|
||||
}
|
||||
} else {
|
||||
ExprKind::Unary { op: UnOp::Neg, arg: arg.to_ref() }
|
||||
|
@ -447,6 +449,7 @@ fn make_mirror_unadjusted<'a, 'tcx>(
|
|||
kind: ExprKind::Literal {
|
||||
literal: ty::Const::zero_sized(cx.tcx, ty),
|
||||
user_ty,
|
||||
const_id: None,
|
||||
},
|
||||
}
|
||||
.to_ref(),
|
||||
|
@ -473,6 +476,7 @@ fn make_mirror_unadjusted<'a, 'tcx>(
|
|||
kind: ExprKind::Literal {
|
||||
literal: ty::Const::zero_sized(cx.tcx, ty),
|
||||
user_ty: None,
|
||||
const_id: None,
|
||||
},
|
||||
}
|
||||
.to_ref(),
|
||||
|
@ -585,7 +589,7 @@ fn make_mirror_unadjusted<'a, 'tcx>(
|
|||
temp_lifetime,
|
||||
ty: var_ty,
|
||||
span: expr.span,
|
||||
kind: ExprKind::Literal { literal, user_ty: None },
|
||||
kind: ExprKind::Literal { literal, user_ty: None, const_id: None },
|
||||
}
|
||||
.to_ref()
|
||||
};
|
||||
|
@ -714,7 +718,11 @@ fn method_callee<'a, 'tcx>(
|
|||
temp_lifetime,
|
||||
ty,
|
||||
span,
|
||||
kind: ExprKind::Literal { literal: ty::Const::zero_sized(cx.tcx(), ty), user_ty },
|
||||
kind: ExprKind::Literal {
|
||||
literal: ty::Const::zero_sized(cx.tcx(), ty),
|
||||
user_ty,
|
||||
const_id: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -777,6 +785,7 @@ fn convert_path_expr<'a, 'tcx>(
|
|||
ExprKind::Literal {
|
||||
literal: ty::Const::zero_sized(cx.tcx, cx.typeck_results().node_type(expr.hir_id)),
|
||||
user_ty,
|
||||
const_id: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -794,6 +803,7 @@ fn convert_path_expr<'a, 'tcx>(
|
|||
.tcx
|
||||
.mk_const(ty::Const { val, ty: cx.typeck_results().node_type(expr.hir_id) }),
|
||||
user_ty: None,
|
||||
const_id: Some(def_id),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -810,6 +820,7 @@ fn convert_path_expr<'a, 'tcx>(
|
|||
ty: cx.typeck_results().node_type(expr.hir_id),
|
||||
}),
|
||||
user_ty,
|
||||
const_id: Some(def_id),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -273,6 +273,10 @@ crate enum ExprKind<'tcx> {
|
|||
Literal {
|
||||
literal: &'tcx Const<'tcx>,
|
||||
user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
|
||||
/// The `DefId` of the `const` item this literal
|
||||
/// was produced from, if this is not a user-written
|
||||
/// literal value.
|
||||
const_id: Option<DefId>,
|
||||
},
|
||||
/// A literal containing the address of a `static`.
|
||||
///
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue