Skip to content

Commit 9565dfe

Browse files
committed
Auto merge of #103683 - fee1-dead-contrib:fix-deferred-cast-checks-constness, r=oli-obk
Retain ParamEnv constness when running deferred cast checks Fixes #103677.
2 parents 77e7b74 + a990b4c commit 9565dfe

File tree

5 files changed

+33
-5
lines changed

5 files changed

+33
-5
lines changed

Diff for: compiler/rustc_hir_typeck/src/cast.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ pub struct CastCheck<'tcx> {
6060
cast_ty: Ty<'tcx>,
6161
cast_span: Span,
6262
span: Span,
63+
/// whether the cast is made in a const context or not.
64+
pub constness: hir::Constness,
6365
}
6466

6567
/// The kind of pointer and associated metadata (thin, length or vtable) - we
@@ -210,9 +212,10 @@ impl<'a, 'tcx> CastCheck<'tcx> {
210212
cast_ty: Ty<'tcx>,
211213
cast_span: Span,
212214
span: Span,
215+
constness: hir::Constness,
213216
) -> Result<CastCheck<'tcx>, ErrorGuaranteed> {
214217
let expr_span = expr.span.find_ancestor_inside(span).unwrap_or(expr.span);
215-
let check = CastCheck { expr, expr_ty, expr_span, cast_ty, cast_span, span };
218+
let check = CastCheck { expr, expr_ty, expr_span, cast_ty, cast_span, span, constness };
216219

217220
// For better error messages, check for some obviously unsized
218221
// cases now. We do a more thorough check at the end, once

Diff for: compiler/rustc_hir_typeck/src/expr.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -1272,7 +1272,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12721272
} else {
12731273
// Defer other checks until we're done type checking.
12741274
let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
1275-
match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) {
1275+
match cast::CastCheck::new(
1276+
self,
1277+
e,
1278+
t_expr,
1279+
t_cast,
1280+
t.span,
1281+
expr.span,
1282+
self.param_env.constness(),
1283+
) {
12761284
Ok(cast_check) => {
12771285
debug!(
12781286
"check_expr_cast: deferring cast from {:?} to {:?}: {:?}",

Diff for: compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,27 @@ use rustc_span::{self, sym, Span};
3333
use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext};
3434

3535
use std::iter;
36+
use std::mem;
3637
use std::ops::ControlFlow;
3738
use std::slice;
3839

3940
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
40-
pub(in super::super) fn check_casts(&self) {
41-
let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
41+
pub(in super::super) fn check_casts(&mut self) {
42+
// don't hold the borrow to deferred_cast_checks while checking to avoid borrow checker errors
43+
// when writing to `self.param_env`.
44+
let mut deferred_cast_checks = mem::take(&mut *self.deferred_cast_checks.borrow_mut());
45+
4246
debug!("FnCtxt::check_casts: {} deferred checks", deferred_cast_checks.len());
4347
for cast in deferred_cast_checks.drain(..) {
48+
let prev_env = self.param_env;
49+
self.param_env = self.param_env.with_constness(cast.constness);
50+
4451
cast.check(self);
52+
53+
self.param_env = prev_env;
4554
}
55+
56+
*self.deferred_cast_checks.borrow_mut() = deferred_cast_checks;
4657
}
4758

4859
pub(in super::super) fn check_transmutes(&self) {
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// check-pass
2+
3+
const _: fn(&String) = |s| { &*s as &str; };
4+
5+
fn main() {}

Diff for: src/tools/clippy/clippy_lints/src/transmute/utils.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use rustc_hir_typeck::{cast, FnCtxt, Inherited};
33
use rustc_lint::LateContext;
44
use rustc_middle::ty::{cast::CastKind, Ty};
55
use rustc_span::DUMMY_SP;
6+
use rustc_hir as hir;
67

78
// check if the component types of the transmuted collection and the result have different ABI,
89
// size or alignment
@@ -56,7 +57,7 @@ fn check_cast<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>
5657
if let Ok(check) = cast::CastCheck::new(
5758
&fn_ctxt, e, from_ty, to_ty,
5859
// We won't show any error to the user, so we don't care what the span is here.
59-
DUMMY_SP, DUMMY_SP,
60+
DUMMY_SP, DUMMY_SP, hir::Constness::NotConst,
6061
) {
6162
let res = check.do_check(&fn_ctxt);
6263

0 commit comments

Comments
 (0)