about summary refs log tree commit diff
diff options
context:
space:
mode:
authorlcnr <rust@lcnr.de>2025-08-21 15:45:40 +0200
committerlcnr <rust@lcnr.de>2025-08-21 15:49:02 +0200
commite8ae1dab12bc1388cd5f6545ccc88297b779f511 (patch)
tree884c838cddbacdf9fda7396fb1f090392aa308e6
parent57e620e56b718abaf47f18e1e20a3cc3480b258b (diff)
downloadrust-e8ae1dab12bc1388cd5f6545ccc88297b779f511.tar.gz
rust-e8ae1dab12bc1388cd5f6545ccc88297b779f511.zip
next-solver fix const_trait_impl bootstrap
-rw-r--r--compiler/rustc_middle/src/ty/context.rs7
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/effect_goals.rs18
-rw-r--r--tests/ui/traits/const-traits/constructor-const-fn.rs15
-rw-r--r--tests/ui/traits/const-traits/reservation-impl-ice.rs13
-rw-r--r--tests/ui/traits/const-traits/reservation-impl-ice.stderr25
5 files changed, 69 insertions, 9 deletions
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 49a4733de3b..c215e44a965 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -33,7 +33,7 @@ use rustc_errors::{
     Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, LintDiagnostic, LintEmitter, MultiSpan,
 };
 use rustc_hir::attrs::AttributeKind;
-use rustc_hir::def::{CtorKind, DefKind};
+use rustc_hir::def::{CtorKind, CtorOf, DefKind};
 use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
 use rustc_hir::definitions::{DefPathData, Definitions, DisambiguatorState};
 use rustc_hir::intravisit::VisitorExt;
@@ -445,7 +445,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
     }
 
     fn fn_is_const(self, def_id: DefId) -> bool {
-        debug_assert_matches!(self.def_kind(def_id), DefKind::Fn | DefKind::AssocFn);
+        debug_assert_matches!(
+            self.def_kind(def_id),
+            DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(CtorOf::Struct, CtorKind::Fn)
+        );
         self.is_conditionally_const(def_id)
     }
 
diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
index 9a22bf58c03..b7ae9994c62 100644
--- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
@@ -6,7 +6,7 @@ use rustc_type_ir::inherent::*;
 use rustc_type_ir::lang_items::TraitSolverLangItem;
 use rustc_type_ir::solve::SizedTraitKind;
 use rustc_type_ir::solve::inspect::ProbeKind;
-use rustc_type_ir::{self as ty, Interner, elaborate};
+use rustc_type_ir::{self as ty, Interner, TypingMode, elaborate};
 use tracing::instrument;
 
 use super::assembly::{Candidate, structural_traits};
@@ -135,12 +135,16 @@ where
         }
 
         let impl_polarity = cx.impl_polarity(impl_def_id);
-        match impl_polarity {
+        let certainty = match impl_polarity {
             ty::ImplPolarity::Negative => return Err(NoSolution),
-            ty::ImplPolarity::Reservation => {
-                unimplemented!("reservation impl for const trait: {:?}", goal)
-            }
-            ty::ImplPolarity::Positive => {}
+            ty::ImplPolarity::Reservation => match ecx.typing_mode() {
+                TypingMode::Coherence => Certainty::AMBIGUOUS,
+                TypingMode::Analysis { .. }
+                | TypingMode::Borrowck { .. }
+                | TypingMode::PostBorrowckAnalysis { .. }
+                | TypingMode::PostAnalysis => return Err(NoSolution),
+            },
+            ty::ImplPolarity::Positive => Certainty::Yes,
         };
 
         if !cx.impl_is_const(impl_def_id) {
@@ -171,7 +175,7 @@ where
                 });
             ecx.add_goals(GoalSource::ImplWhereBound, const_conditions);
 
-            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+            ecx.evaluate_added_goals_and_make_canonical_response(certainty)
         })
     }
 
diff --git a/tests/ui/traits/const-traits/constructor-const-fn.rs b/tests/ui/traits/const-traits/constructor-const-fn.rs
new file mode 100644
index 00000000000..4a7bf531df2
--- /dev/null
+++ b/tests/ui/traits/const-traits/constructor-const-fn.rs
@@ -0,0 +1,15 @@
+//@ check-pass
+//@ compile-flags: -Znext-solver
+#![feature(const_trait_impl)]
+const fn impls_fn<F: ~const Fn(u32) -> Foo>(_: &F) {}
+
+struct Foo(u32);
+
+const fn foo() {
+    // This previously triggered an incorrect assert
+    // when checking whether the constructor of `Foo`
+    // is const.
+    impls_fn(&Foo)
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/reservation-impl-ice.rs b/tests/ui/traits/const-traits/reservation-impl-ice.rs
new file mode 100644
index 00000000000..efaea1cc6b2
--- /dev/null
+++ b/tests/ui/traits/const-traits/reservation-impl-ice.rs
@@ -0,0 +1,13 @@
+//@ compile-flags: -Znext-solver
+#![feature(const_from, never_type, const_trait_impl)]
+
+const fn impls_from<T: ~const From<!>>() {}
+
+const fn foo() {
+    // This previously ICE'd when encountering the reservation impl
+    // from the standard library.
+    impls_from::<()>();
+    //~^ ERROR the trait bound `(): From<!>` is not satisfied
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/reservation-impl-ice.stderr b/tests/ui/traits/const-traits/reservation-impl-ice.stderr
new file mode 100644
index 00000000000..a3fdcbac69e
--- /dev/null
+++ b/tests/ui/traits/const-traits/reservation-impl-ice.stderr
@@ -0,0 +1,25 @@
+error[E0277]: the trait bound `(): From<!>` is not satisfied
+  --> $DIR/reservation-impl-ice.rs:9:18
+   |
+LL |     impls_from::<()>();
+   |                  ^^ the trait `From<!>` is not implemented for `()`
+   |
+   = help: the following other types implement trait `From<T>`:
+             `(T, T)` implements `From<[T; 2]>`
+             `(T, T, T)` implements `From<[T; 3]>`
+             `(T, T, T, T)` implements `From<[T; 4]>`
+             `(T, T, T, T, T)` implements `From<[T; 5]>`
+             `(T, T, T, T, T, T)` implements `From<[T; 6]>`
+             `(T, T, T, T, T, T, T)` implements `From<[T; 7]>`
+             `(T, T, T, T, T, T, T, T)` implements `From<[T; 8]>`
+             `(T, T, T, T, T, T, T, T, T)` implements `From<[T; 9]>`
+           and 4 others
+note: required by a bound in `impls_from`
+  --> $DIR/reservation-impl-ice.rs:4:24
+   |
+LL | const fn impls_from<T: ~const From<!>>() {}
+   |                        ^^^^^^^^^^^^^^ required by this bound in `impls_from`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.