about summary refs log tree commit diff
path: root/compiler/rustc_const_eval
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-03-08 12:39:26 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-07-24 16:00:48 +0000
commitacba6449f8597c85b450d96eccda31025cdc0049 (patch)
tree9c3e4e8cb11097d1a2b5114502185aa4c484b5d4 /compiler/rustc_const_eval
parentfdff100545850376e0f48d382ca3f92c959ff1cc (diff)
Do not try to reveal hidden types when trying to prove Freeze in the defining scope
Diffstat (limited to 'compiler/rustc_const_eval')
-rw-r--r--compiler/rustc_const_eval/src/check_consts/qualifs.rs28
1 files changed, 27 insertions, 1 deletions
diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
index 9fd7219499b..d5d3f7767b1 100644
--- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
@@ -100,7 +100,33 @@ impl Qualif for HasMutInterior {
     }
 
     fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
-        !ty.is_freeze(cx.tcx, cx.param_env)
+        // Avoid selecting for simple cases, such as builtin types.
+        if ty.is_trivially_freeze() {
+            return false;
+        }
+
+        // We do not use `ty.is_freeze` here, because that requires revealing opaque types, which
+        // requires borrowck, which in turn will invoke mir_const_qualifs again, causing a cycle error.
+        // Instead we invoke an obligation context manually, and provide the opaque type inference settings
+        // that allow the trait solver to just error out instead of cycling.
+        let freeze_def_id = cx.tcx.require_lang_item(LangItem::Freeze, Some(cx.body.span));
+
+        let obligation = Obligation::new(
+            cx.tcx,
+            ObligationCause::dummy_with_span(cx.body.span),
+            cx.param_env,
+            ty::TraitRef::new(cx.tcx, freeze_def_id, [ty::GenericArg::from(ty)]),
+        );
+
+        let infcx = cx
+            .tcx
+            .infer_ctxt()
+            .with_opaque_type_inference(cx.body.source.def_id().expect_local())
+            .build();
+        let ocx = ObligationCtxt::new(&infcx);
+        ocx.register_obligation(obligation);
+        let errors = ocx.select_all_or_error();
+        !errors.is_empty()
     }
 
     fn in_adt_inherently<'tcx>(