Skip to content

Commit 82a9e87

Browse files
Fix PartialEq args when #[const_trait] is enabled
1 parent 5facb42 commit 82a9e87

File tree

5 files changed

+56
-37
lines changed

5 files changed

+56
-37
lines changed

compiler/rustc_hir_typeck/src/callee.rs

+2-33
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::errors;
66
use rustc_ast::util::parser::PREC_POSTFIX;
77
use rustc_errors::{Applicability, Diagnostic, ErrorGuaranteed, StashKey};
88
use rustc_hir as hir;
9-
use rustc_hir::def::{self, CtorKind, DefKind, Namespace, Res};
9+
use rustc_hir::def::{self, CtorKind, Namespace, Res};
1010
use rustc_hir::def_id::DefId;
1111
use rustc_hir::HirId;
1212
use rustc_hir_analysis::autoderef::Autoderef;
@@ -781,38 +781,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
781781
let generics = tcx.generics_of(callee_did);
782782
let Some(host_effect_index) = generics.host_effect_index else { return };
783783

784-
// if the callee does have the param, we need to equate the param to some const
785-
// value no matter whether the effects feature is enabled in the local crate,
786-
// because inference will fail if we don't.
787-
let mut host_always_on =
788-
!tcx.features().effects || tcx.sess.opts.unstable_opts.unleash_the_miri_inside_of_you;
789-
790-
// Compute the constness required by the context.
791-
let context = tcx.hir().enclosing_body_owner(call_expr_hir);
792-
let const_context = tcx.hir().body_const_context(context);
793-
794-
let kind = tcx.def_kind(context.to_def_id());
795-
debug_assert_ne!(kind, DefKind::ConstParam);
796-
797-
if tcx.has_attr(context.to_def_id(), sym::rustc_do_not_const_check) {
798-
trace!("do not const check this context");
799-
host_always_on = true;
800-
}
801-
802-
let effect = match const_context {
803-
_ if host_always_on => tcx.consts.true_,
804-
Some(hir::ConstContext::Static(_) | hir::ConstContext::Const { .. }) => {
805-
tcx.consts.false_
806-
}
807-
Some(hir::ConstContext::ConstFn) => {
808-
let host_idx = tcx
809-
.generics_of(context)
810-
.host_effect_index
811-
.expect("ConstContext::Maybe must have host effect param");
812-
ty::GenericArgs::identity_for_item(tcx, context).const_at(host_idx)
813-
}
814-
None => tcx.consts.true_,
815-
};
784+
let effect = tcx.expected_const_effect_param_for_body(self.body_id);
816785

817786
trace!(?effect, ?generics, ?callee_args);
818787

compiler/rustc_middle/src/ty/util.rs

+34
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,40 @@ impl<'tcx> TyCtxt<'tcx> {
779779
// the language.
780780
|| self.extern_crate(key.as_def_id()).is_some_and(|e| e.is_direct())
781781
}
782+
783+
pub fn expected_const_effect_param_for_body(self, def_id: LocalDefId) -> ty::Const<'tcx> {
784+
// if the callee does have the param, we need to equate the param to some const
785+
// value no matter whether the effects feature is enabled in the local crate,
786+
// because inference will fail if we don't.
787+
let mut host_always_on =
788+
!self.features().effects || self.sess.opts.unstable_opts.unleash_the_miri_inside_of_you;
789+
790+
// Compute the constness required by the context.
791+
let const_context = self.hir().body_const_context(def_id);
792+
793+
let kind = self.def_kind(def_id);
794+
debug_assert_ne!(kind, DefKind::ConstParam);
795+
796+
if self.has_attr(def_id, sym::rustc_do_not_const_check) {
797+
trace!("do not const check this context");
798+
host_always_on = true;
799+
}
800+
801+
match const_context {
802+
_ if host_always_on => self.consts.true_,
803+
Some(hir::ConstContext::Static(_) | hir::ConstContext::Const { .. }) => {
804+
self.consts.false_
805+
}
806+
Some(hir::ConstContext::ConstFn) => {
807+
let host_idx = self
808+
.generics_of(def_id)
809+
.host_effect_index
810+
.expect("ConstContext::Maybe must have host effect param");
811+
ty::GenericArgs::identity_for_item(self, def_id).const_at(host_idx)
812+
}
813+
None => self.consts.true_,
814+
}
815+
}
782816
}
783817

784818
struct OpaqueTypeExpander<'tcx> {

compiler/rustc_mir_build/src/build/matches/test.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
494494
}
495495

496496
let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, Some(source_info.span));
497-
let method = trait_method(self.tcx, eq_def_id, sym::eq, [ty, ty]);
497+
498+
let mut args: Vec<ty::GenericArg<'tcx>> = vec![ty.into(), ty.into()];
499+
// If `PartialEq` is `#[const_trait]`, then add a const effect param
500+
if self.tcx.generics_of(eq_def_id).host_effect_index.is_some() {
501+
args.push(self.tcx.expected_const_effect_param_for_body(self.def_id).into());
502+
}
503+
504+
let method = trait_method(self.tcx, eq_def_id, sym::eq, args);
498505

499506
let bool_ty = self.tcx.types.bool;
500507
let eq_result = self.temp(bool_ty, source_info.span);

compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -258,18 +258,27 @@ impl<'tcx> ConstToPat<'tcx> {
258258

259259
#[instrument(level = "trace", skip(self), ret)]
260260
fn type_has_partial_eq_impl(&self, ty: Ty<'tcx>) -> bool {
261+
let tcx = self.tcx();
261262
// double-check there even *is* a semantic `PartialEq` to dispatch to.
262263
//
263264
// (If there isn't, then we can safely issue a hard
264265
// error, because that's never worked, due to compiler
265266
// using `PartialEq::eq` in this scenario in the past.)
266-
let tcx = self.tcx();
267267
let partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::PartialEq, Some(self.span));
268+
let mut args: Vec<ty::GenericArg<'tcx>> = vec![ty.into(), ty.into()];
269+
// If `PartialEq` is `#[const_trait]`, then add a const effect param
270+
if tcx.generics_of(partial_eq_trait_id).host_effect_index.is_some() {
271+
args.push(
272+
tcx.expected_const_effect_param_for_body(tcx.hir().enclosing_body_owner(self.id))
273+
.into(),
274+
);
275+
}
276+
268277
let partial_eq_obligation = Obligation::new(
269278
tcx,
270279
ObligationCause::dummy(),
271280
self.param_env,
272-
ty::TraitRef::new(tcx, partial_eq_trait_id, [ty, ty]),
281+
ty::TraitRef::new(tcx, partial_eq_trait_id, args),
273282
);
274283

275284
// This *could* accept a type that isn't actually `PartialEq`, because region bounds get

tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ fn from_str(s: &str) -> Result<bool, ()> {
336336
}
337337

338338
#[lang = "eq"]
339-
// FIXME #[const_trait]
339+
#[const_trait]
340340
trait PartialEq<Rhs: ?Sized = Self> {
341341
fn eq(&self, other: &Rhs) -> bool;
342342
fn ne(&self, other: &Rhs) -> bool {

0 commit comments

Comments
 (0)