From 5538a068bd4220c3f69edc9204d6b9bf58f75613 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 30 Oct 2025 09:33:53 +0000 Subject: [PATCH 1/2] Show that a test still fails with the feature gate enabled --- tests/ui/traits/const-traits/issue-103677.cnst.stderr | 9 +++++++++ tests/ui/traits/const-traits/issue-103677.rs | 9 +++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 tests/ui/traits/const-traits/issue-103677.cnst.stderr diff --git a/tests/ui/traits/const-traits/issue-103677.cnst.stderr b/tests/ui/traits/const-traits/issue-103677.cnst.stderr new file mode 100644 index 0000000000000..845bdb326db11 --- /dev/null +++ b/tests/ui/traits/const-traits/issue-103677.cnst.stderr @@ -0,0 +1,9 @@ +error[E0277]: the trait bound `String: const Deref` is not satisfied + --> $DIR/issue-103677.rs:6:5 + | +LL | &*s as &str; + | ^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/issue-103677.rs b/tests/ui/traits/const-traits/issue-103677.rs index c032cc7a68803..09f45f5ee3771 100644 --- a/tests/ui/traits/const-traits/issue-103677.rs +++ b/tests/ui/traits/const-traits/issue-103677.rs @@ -1,5 +1,10 @@ -//@ check-pass +//@[stock] check-pass +//@ revisions: stock cnst +#![cfg_attr(cnst, feature(const_trait_impl))] -const _: fn(&String) = |s| { &*s as &str; }; +const _: fn(&String) = |s| { + &*s as &str; + //[cnst]~^ ERROR: the trait bound `String: const Deref` is not satisfied +}; fn main() {} From 8762219b8fc5d3ab8d48345df6be45d6e63a20e6 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 30 Oct 2025 09:51:50 +0000 Subject: [PATCH 2/2] Fix deferred cast checks using the wrong body for determining constness --- compiler/rustc_hir_typeck/src/cast.rs | 6 ++++-- compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 11 ++++------- tests/ui/traits/const-traits/issue-103677.cnst.stderr | 9 --------- tests/ui/traits/const-traits/issue-103677.rs | 3 +-- 4 files changed, 9 insertions(+), 20 deletions(-) delete mode 100644 tests/ui/traits/const-traits/issue-103677.cnst.stderr diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 40b21c45bc564..3f13a102684e0 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -32,7 +32,7 @@ use rustc_ast::util::parser::ExprPrecedence; use rustc_data_structures::fx::FxHashSet; use rustc_errors::codes::*; use rustc_errors::{Applicability, Diag, ErrorGuaranteed}; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{self as hir, ExprKind}; use rustc_infer::infer::DefineOpaqueTypes; use rustc_macros::{TypeFoldable, TypeVisitable}; @@ -63,6 +63,7 @@ pub(crate) struct CastCheck<'tcx> { cast_ty: Ty<'tcx>, cast_span: Span, span: Span, + pub body_id: LocalDefId, } /// The kind of pointer and associated metadata (thin, length or vtable) - we @@ -244,7 +245,8 @@ impl<'a, 'tcx> CastCheck<'tcx> { span: Span, ) -> Result, ErrorGuaranteed> { let expr_span = expr.span.find_ancestor_inside(span).unwrap_or(expr.span); - let check = CastCheck { expr, expr_ty, expr_span, cast_ty, cast_span, span }; + let check = + CastCheck { expr, expr_ty, expr_span, cast_ty, cast_span, span, body_id: fcx.body_id }; // For better error messages, check for some obviously unsized // cases now. We do a more thorough check at the end, once diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 4d1c7be391977..7b75d23ed9580 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1,5 +1,5 @@ use std::ops::Deref; -use std::{fmt, iter, mem}; +use std::{fmt, iter}; use itertools::Itertools; use rustc_data_structures::fx::FxIndexSet; @@ -72,16 +72,13 @@ pub(crate) enum DivergingBlockBehavior { impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(in super::super) fn check_casts(&mut self) { - // don't hold the borrow to deferred_cast_checks while checking to avoid borrow checker errors - // when writing to `self.param_env`. - let mut deferred_cast_checks = mem::take(&mut *self.deferred_cast_checks.borrow_mut()); - + let mut deferred_cast_checks = self.root_ctxt.deferred_cast_checks.borrow_mut(); debug!("FnCtxt::check_casts: {} deferred checks", deferred_cast_checks.len()); for cast in deferred_cast_checks.drain(..) { + let body_id = std::mem::replace(&mut self.body_id, cast.body_id); cast.check(self); + self.body_id = body_id; } - - *self.deferred_cast_checks.borrow_mut() = deferred_cast_checks; } pub(in super::super) fn check_asms(&self) { diff --git a/tests/ui/traits/const-traits/issue-103677.cnst.stderr b/tests/ui/traits/const-traits/issue-103677.cnst.stderr deleted file mode 100644 index 845bdb326db11..0000000000000 --- a/tests/ui/traits/const-traits/issue-103677.cnst.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0277]: the trait bound `String: const Deref` is not satisfied - --> $DIR/issue-103677.rs:6:5 - | -LL | &*s as &str; - | ^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/issue-103677.rs b/tests/ui/traits/const-traits/issue-103677.rs index 09f45f5ee3771..8117e393753fd 100644 --- a/tests/ui/traits/const-traits/issue-103677.rs +++ b/tests/ui/traits/const-traits/issue-103677.rs @@ -1,10 +1,9 @@ -//@[stock] check-pass +//@ check-pass //@ revisions: stock cnst #![cfg_attr(cnst, feature(const_trait_impl))] const _: fn(&String) = |s| { &*s as &str; - //[cnst]~^ ERROR: the trait bound `String: const Deref` is not satisfied }; fn main() {}