Skip to content

Commit 6f40082

Browse files
committed
Auto merge of #118661 - fee1-dead-contrib:restore-const-partialEq, r=compiler-errors
Restore `const PartialEq` And thus fixes a number of tests. There is a bug that still needs to be fixed, so WIP for now. r? `@compiler-errors`
2 parents 8b1ba11 + c4c3555 commit 6f40082

38 files changed

+149
-194
lines changed

compiler/rustc_const_eval/src/util/type_name.rs

-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,6 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
120120
&mut self,
121121
print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
122122
args: &[GenericArg<'tcx>],
123-
_params: &[ty::GenericParamDef],
124123
) -> Result<(), PrintError> {
125124
print_prefix(self)?;
126125
let args =

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
641641
&mut self,
642642
print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
643643
_args: &[GenericArg<'tcx>],
644-
_params: &[ty::GenericParamDef],
645644
) -> Result<(), PrintError> {
646645
print_prefix(self)
647646
}
@@ -1237,9 +1236,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
12371236
(&ty::Adt(def1, sub1), &ty::Adt(def2, sub2)) => {
12381237
let did1 = def1.did();
12391238
let did2 = def2.did();
1240-
let (sub_no_defaults_1, _) =
1239+
let sub_no_defaults_1 =
12411240
self.tcx.generics_of(did1).own_args_no_defaults(self.tcx, sub1);
1242-
let (sub_no_defaults_2, _) =
1241+
let sub_no_defaults_2 =
12431242
self.tcx.generics_of(did2).own_args_no_defaults(self.tcx, sub2);
12441243
let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
12451244
let path1 = self.tcx.def_path_str(did1);

compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,6 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
757757
.tcx
758758
.generics_of(def.did())
759759
.own_args_no_defaults(self.tcx, args)
760-
.0
761760
.iter()
762761
.map(|&arg| self.arg_cost(arg))
763762
.sum::<usize>()
@@ -1186,7 +1185,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
11861185
}
11871186
let args = self.infcx.resolve_vars_if_possible(args);
11881187
let generic_args =
1189-
&generics.own_args_no_defaults(tcx, args).0[generics.own_counts().lifetimes..];
1188+
&generics.own_args_no_defaults(tcx, args)[generics.own_counts().lifetimes..];
11901189
let span = match expr.kind {
11911190
ExprKind::MethodCall(path, ..) => path.ident.span,
11921191
_ => expr.span,

compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
116116
// FIXME: extract this logic for use in other diagnostics.
117117
let (trait_ref, assoc_args) = proj.trait_ref_and_own_args(tcx);
118118
let item_name = tcx.item_name(proj.def_id);
119-
let item_args = self.format_generic_args(proj.def_id, assoc_args);
119+
let item_args = self.format_generic_args(assoc_args);
120120

121121
// Here, we try to see if there's an existing
122122
// trait implementation that matches the one that
@@ -775,7 +775,7 @@ fn foo(&self) -> Self::T { String::new() }
775775
let span = Span::new(pos, pos, span.ctxt(), span.parent());
776776
(span, format!(", {} = {}", assoc.ident(tcx), ty))
777777
} else {
778-
let item_args = self.format_generic_args(assoc.def_id, assoc_args);
778+
let item_args = self.format_generic_args(assoc_args);
779779
(span.shrink_to_hi(), format!("<{}{} = {}>", assoc.ident(tcx), item_args, ty))
780780
};
781781
diag.span_suggestion_verbose(span, msg(), sugg, MaybeIncorrect);
@@ -784,13 +784,9 @@ fn foo(&self) -> Self::T { String::new() }
784784
false
785785
}
786786

787-
pub fn format_generic_args(
788-
&self,
789-
assoc_def_id: DefId,
790-
args: &[ty::GenericArg<'tcx>],
791-
) -> String {
787+
pub fn format_generic_args(&self, args: &[ty::GenericArg<'tcx>]) -> String {
792788
FmtPrinter::print_string(self.tcx, hir::def::Namespace::TypeNS, |cx| {
793-
cx.path_generic_args(|_| Ok(()), args, &self.infcx.tcx.generics_of(assoc_def_id).params)
789+
cx.path_generic_args(|_| Ok(()), args)
794790
})
795791
.expect("could not write to `String`.")
796792
}

compiler/rustc_lint/src/context.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1285,7 +1285,6 @@ impl<'tcx> LateContext<'tcx> {
12851285
&mut self,
12861286
print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
12871287
_args: &[GenericArg<'tcx>],
1288-
_params: &[ty::GenericParamDef],
12891288
) -> Result<(), PrintError> {
12901289
print_prefix(self)
12911290
}

compiler/rustc_middle/src/hir/map/mod.rs

+7-9
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,8 @@ impl<'hir> Map<'hir> {
336336
/// Returns the `BodyOwnerKind` of this `LocalDefId`.
337337
///
338338
/// Panics if `LocalDefId` does not have an associated body.
339-
pub fn body_owner_kind(self, def_id: LocalDefId) -> BodyOwnerKind {
339+
pub fn body_owner_kind(self, def_id: impl Into<DefId>) -> BodyOwnerKind {
340+
let def_id = def_id.into();
340341
match self.tcx.def_kind(def_id) {
341342
DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => {
342343
BodyOwnerKind::Const { inline: false }
@@ -356,20 +357,17 @@ impl<'hir> Map<'hir> {
356357
/// This should only be used for determining the context of a body, a return
357358
/// value of `Some` does not always suggest that the owner of the body is `const`,
358359
/// just that it has to be checked as if it were.
359-
pub fn body_const_context(self, def_id: LocalDefId) -> Option<ConstContext> {
360+
pub fn body_const_context(self, def_id: impl Into<DefId>) -> Option<ConstContext> {
361+
let def_id = def_id.into();
360362
let ccx = match self.body_owner_kind(def_id) {
361363
BodyOwnerKind::Const { inline } => ConstContext::Const { inline },
362364
BodyOwnerKind::Static(mt) => ConstContext::Static(mt),
363365

364-
BodyOwnerKind::Fn if self.tcx.is_constructor(def_id.to_def_id()) => return None,
365-
BodyOwnerKind::Fn | BodyOwnerKind::Closure
366-
if self.tcx.is_const_fn_raw(def_id.to_def_id()) =>
367-
{
368-
ConstContext::ConstFn
369-
}
370-
BodyOwnerKind::Fn if self.tcx.is_const_default_method(def_id.to_def_id()) => {
366+
BodyOwnerKind::Fn if self.tcx.is_constructor(def_id) => return None,
367+
BodyOwnerKind::Fn | BodyOwnerKind::Closure if self.tcx.is_const_fn_raw(def_id) => {
371368
ConstContext::ConstFn
372369
}
370+
BodyOwnerKind::Fn if self.tcx.is_const_default_method(def_id) => ConstContext::ConstFn,
373371
BodyOwnerKind::Fn | BodyOwnerKind::Closure => return None,
374372
};
375373

compiler/rustc_middle/src/ty/generics.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -320,34 +320,34 @@ impl<'tcx> Generics {
320320
&'tcx self,
321321
tcx: TyCtxt<'tcx>,
322322
args: &'tcx [ty::GenericArg<'tcx>],
323-
) -> (&'tcx [ty::GenericArg<'tcx>], &'tcx [ty::GenericParamDef]) {
324-
let mut own_args = self.parent_count..self.count();
325-
let mut own_params = 0..self.params.len();
323+
) -> &'tcx [ty::GenericArg<'tcx>] {
324+
let mut own_params = self.parent_count..self.count();
326325
if self.has_self && self.parent.is_none() {
327-
own_args.start = 1;
328326
own_params.start = 1;
329327
}
330328

329+
let verbose = tcx.sess.verbose();
330+
331331
// Filter the default arguments.
332332
//
333333
// This currently uses structural equality instead
334334
// of semantic equivalence. While not ideal, that's
335335
// good enough for now as this should only be used
336336
// for diagnostics anyways.
337-
let num_default_params = self
337+
own_params.end -= self
338338
.params
339339
.iter()
340340
.rev()
341341
.take_while(|param| {
342342
param.default_value(tcx).is_some_and(|default| {
343343
default.instantiate(tcx, args) == args[param.index as usize]
344344
})
345+
// filter out trailing effect params, if we're not in `-Zverbose`.
346+
|| (!verbose && matches!(param.kind, GenericParamDefKind::Const { is_host_effect: true, .. }))
345347
})
346348
.count();
347-
own_params.end -= num_default_params;
348-
own_args.end -= num_default_params;
349349

350-
(&args[own_args], &self.params[own_params])
350+
&args[own_params]
351351
}
352352

353353
/// Returns the args corresponding to the generic parameters of this item, excluding `Self`.

compiler/rustc_middle/src/ty/print/mod.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ pub trait Printer<'tcx>: Sized {
8383
&mut self,
8484
print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
8585
args: &[GenericArg<'tcx>],
86-
params: &[ty::GenericParamDef],
8786
) -> Result<(), PrintError>;
8887

8988
// Defaults (should not be overridden):
@@ -142,12 +141,10 @@ pub trait Printer<'tcx>: Sized {
142141
// on top of the same path, but without its own generics.
143142
_ => {
144143
if !generics.params.is_empty() && args.len() >= generics.count() {
145-
let (args, params) =
146-
generics.own_args_no_defaults(self.tcx(), args);
144+
let args = generics.own_args_no_defaults(self.tcx(), args);
147145
return self.path_generic_args(
148146
|cx| cx.print_def_path(def_id, parent_args),
149147
args,
150-
params,
151148
);
152149
}
153150
}

compiler/rustc_middle/src/ty/print/pretty.rs

+7-19
Original file line numberDiff line numberDiff line change
@@ -965,7 +965,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
965965
define_scoped_cx!(cx);
966966
// Get the (single) generic ty (the args) of this FnOnce trait ref.
967967
let generics = tcx.generics_of(trait_ref.def_id);
968-
let (own_args, _) = generics.own_args_no_defaults(tcx, trait_ref.args);
968+
let own_args = generics.own_args_no_defaults(tcx, trait_ref.args);
969969

970970
match (entry.return_ty, own_args[0].expect_ty()) {
971971
// We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded
@@ -1031,7 +1031,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
10311031
p!(print(trait_ref.print_only_trait_name()));
10321032

10331033
let generics = tcx.generics_of(trait_ref.def_id);
1034-
let (own_args, _) = generics.own_args_no_defaults(tcx, trait_ref.args);
1034+
let own_args = generics.own_args_no_defaults(tcx, trait_ref.args);
10351035

10361036
if !own_args.is_empty() || !assoc_items.is_empty() {
10371037
let mut first = true;
@@ -1183,7 +1183,6 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
11831183
)
11841184
},
11851185
&alias_ty.args[1..],
1186-
&self.tcx().generics_of(alias_ty.def_id).params,
11871186
)
11881187
}
11891188

@@ -1232,7 +1231,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
12321231
let dummy_cx = Ty::new_fresh(cx.tcx(), 0);
12331232
let principal = principal.with_self_ty(cx.tcx(), dummy_cx);
12341233

1235-
let (args, _) = cx
1234+
let args = cx
12361235
.tcx()
12371236
.generics_of(principal.def_id)
12381237
.own_args_no_defaults(cx.tcx(), principal.args);
@@ -2030,26 +2029,14 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
20302029
&mut self,
20312030
print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
20322031
args: &[GenericArg<'tcx>],
2033-
params: &[ty::GenericParamDef],
20342032
) -> Result<(), PrintError> {
20352033
print_prefix(self)?;
20362034

2037-
let tcx = self.tcx;
2038-
let verbose = tcx.sess.verbose();
2039-
let mut args = args
2040-
.iter()
2041-
.copied()
2042-
.zip(params)
2043-
// If -Zverbose is passed, we should print the host parameter instead
2044-
// of eating it.
2045-
.filter(|(_, param)| verbose || !param.is_host_effect())
2046-
.peekable();
2047-
2048-
if args.peek().is_some() {
2035+
if !args.is_empty() {
20492036
if self.in_value {
20502037
write!(self, "::")?;
20512038
}
2052-
self.generic_delimiters(|cx| cx.comma_sep(args.map(|(arg, _)| arg)))
2039+
self.generic_delimiters(|cx| cx.comma_sep(args.iter().copied()))
20532040
} else {
20542041
Ok(())
20552042
}
@@ -2881,7 +2868,8 @@ define_print_and_forward_display! {
28812868
TraitPredPrintModifiersAndPath<'tcx> {
28822869
if let Some(idx) = cx.tcx().generics_of(self.0.trait_ref.def_id).host_effect_index
28832870
{
2884-
if self.0.trait_ref.args.const_at(idx) != cx.tcx().consts.true_ {
2871+
let arg = self.0.trait_ref.args.const_at(idx);
2872+
if arg != cx.tcx().consts.true_ && !arg.has_infer() {
28852873
p!("~const ");
28862874
}
28872875
}

compiler/rustc_middle/src/ty/util.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,8 @@ impl<'tcx> TyCtxt<'tcx> {
782782
|| self.extern_crate(key.as_def_id()).is_some_and(|e| e.is_direct())
783783
}
784784

785-
pub fn expected_host_effect_param_for_body(self, def_id: LocalDefId) -> ty::Const<'tcx> {
785+
pub fn expected_host_effect_param_for_body(self, def_id: impl Into<DefId>) -> ty::Const<'tcx> {
786+
let def_id = def_id.into();
786787
// FIXME(effects): This is suspicious and should probably not be done,
787788
// especially now that we enforce host effects and then properly handle
788789
// effect vars during fallback.

compiler/rustc_symbol_mangling/src/legacy.rs

-1
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,6 @@ impl<'tcx> Printer<'tcx> for SymbolPrinter<'tcx> {
342342
&mut self,
343343
print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
344344
args: &[GenericArg<'tcx>],
345-
_params: &[ty::GenericParamDef],
346345
) -> Result<(), PrintError> {
347346
print_prefix(self)?;
348347

compiler/rustc_symbol_mangling/src/v0.rs

-2
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,6 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
298298
)
299299
},
300300
args,
301-
&self.tcx.generics_of(impl_def_id).params,
302301
)?;
303302
} else {
304303
self.push_disambiguator(key.disambiguated_data.disambiguator as u64);
@@ -801,7 +800,6 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
801800
&mut self,
802801
print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
803802
args: &[GenericArg<'tcx>],
804-
_params: &[ty::GenericParamDef],
805803
) -> Result<(), PrintError> {
806804
// Don't print any regions if they're all erased.
807805
let print_regions = args.iter().any(|arg| match arg.unpack() {

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -3628,17 +3628,19 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
36283628
is_derivable_trait &&
36293629
// Ensure all fields impl the trait.
36303630
adt.all_fields().all(|field| {
3631-
let field_ty = field.ty(self.tcx, args);
3631+
let field_ty = ty::GenericArg::from(field.ty(self.tcx, args));
36323632
let trait_args = match diagnostic_name {
36333633
sym::PartialEq | sym::PartialOrd => {
36343634
Some(field_ty)
36353635
}
36363636
_ => None,
36373637
};
3638+
// Also add host param, if present
3639+
let host = self.tcx.generics_of(trait_pred.def_id()).host_effect_index.map(|idx| trait_pred.skip_binder().trait_ref.args[idx]);
36383640
let trait_pred = trait_pred.map_bound_ref(|tr| ty::TraitPredicate {
36393641
trait_ref: ty::TraitRef::new(self.tcx,
36403642
trait_pred.def_id(),
3641-
[field_ty].into_iter().chain(trait_args),
3643+
[field_ty].into_iter().chain(trait_args).chain(host),
36423644
),
36433645
..*tr
36443646
});
@@ -3659,6 +3661,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
36593661
trait_pred.skip_binder().self_ty(),
36603662
diagnostic_name,
36613663
),
3664+
// FIXME(effects, const_trait_impl) derive_const as suggestion?
36623665
format!("#[derive({diagnostic_name})]\n"),
36633666
Applicability::MaybeIncorrect,
36643667
);

library/core/src/cmp.rs

+12
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ use self::Ordering::*;
224224
append_const_msg
225225
)]
226226
#[rustc_diagnostic_item = "PartialEq"]
227+
#[cfg_attr(not(bootstrap), const_trait)]
227228
pub trait PartialEq<Rhs: ?Sized = Self> {
228229
/// This method tests for `self` and `other` values to be equal, and is used
229230
/// by `==`.
@@ -1414,12 +1415,23 @@ mod impls {
14141415
macro_rules! partial_eq_impl {
14151416
($($t:ty)*) => ($(
14161417
#[stable(feature = "rust1", since = "1.0.0")]
1418+
#[cfg(bootstrap)]
14171419
impl PartialEq for $t {
14181420
#[inline]
14191421
fn eq(&self, other: &$t) -> bool { (*self) == (*other) }
14201422
#[inline]
14211423
fn ne(&self, other: &$t) -> bool { (*self) != (*other) }
14221424
}
1425+
1426+
#[stable(feature = "rust1", since = "1.0.0")]
1427+
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1428+
#[cfg(not(bootstrap))]
1429+
impl const PartialEq for $t {
1430+
#[inline]
1431+
fn eq(&self, other: &$t) -> bool { (*self) == (*other) }
1432+
#[inline]
1433+
fn ne(&self, other: &$t) -> bool { (*self) != (*other) }
1434+
}
14231435
)*)
14241436
}
14251437

src/tools/clippy/clippy_lints/src/derive.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -450,12 +450,12 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r
450450
&& let Some(def_id) = trait_ref.trait_def_id()
451451
&& cx.tcx.is_diagnostic_item(sym::PartialEq, def_id)
452452
&& let param_env = param_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id)
453-
&& !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, &[])
453+
&& !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, adt.did(),&[])
454454
// If all of our fields implement `Eq`, we can implement `Eq` too
455455
&& adt
456456
.all_fields()
457457
.map(|f| f.ty(cx.tcx, args))
458-
.all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, &[]))
458+
.all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, adt.did(), &[]))
459459
{
460460
span_lint_and_sugg(
461461
cx,

src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs

+4
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@ fn is_same_generics<'tcx>(
194194
.enumerate()
195195
.skip(1) // skip `Self` implicit arg
196196
.all(|(arg_index, arg)| {
197+
if [implied_by_generics.host_effect_index, implied_generics.host_effect_index].contains(&Some(arg_index)) {
198+
// skip host effect params in determining whether generics are same
199+
return true;
200+
}
197201
if let Some(ty) = arg.as_type() {
198202
if let &ty::Param(ty::ParamTy { index, .. }) = ty.kind()
199203
// `index == 0` means that it's referring to `Self`,

src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ fn is_ref_iterable<'tcx>(
118118
.liberate_late_bound_regions(fn_id, cx.tcx.fn_sig(fn_id).skip_binder())
119119
&& let &[req_self_ty, req_res_ty] = &**sig.inputs_and_output
120120
&& let param_env = cx.tcx.param_env(fn_id)
121-
&& implements_trait_with_env(cx.tcx, param_env, req_self_ty, trait_id, &[])
121+
&& implements_trait_with_env(cx.tcx, param_env, req_self_ty, trait_id, fn_id, &[])
122122
&& let Some(into_iter_ty) =
123123
make_normalized_projection_with_regions(cx.tcx, param_env, trait_id, sym!(IntoIter), [req_self_ty])
124124
&& let req_res_ty = normalize_with_regions(cx.tcx, param_env, req_res_ty)

0 commit comments

Comments
 (0)