diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs index b6240906611a9..a82b65b19a882 100644 --- a/compiler/rustc_const_eval/src/util/type_name.rs +++ b/compiler/rustc_const_eval/src/util/type_name.rs @@ -120,7 +120,6 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { &mut self, print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>, args: &[GenericArg<'tcx>], - _params: &[ty::GenericParamDef], ) -> Result<(), PrintError> { print_prefix(self)?; let args = diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 0004f16fc4e3f..745c3d195ada7 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -641,7 +641,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { &mut self, print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>, _args: &[GenericArg<'tcx>], - _params: &[ty::GenericParamDef], ) -> Result<(), PrintError> { print_prefix(self) } @@ -1237,9 +1236,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { (&ty::Adt(def1, sub1), &ty::Adt(def2, sub2)) => { let did1 = def1.did(); let did2 = def2.did(); - let (sub_no_defaults_1, _) = + let sub_no_defaults_1 = self.tcx.generics_of(did1).own_args_no_defaults(self.tcx, sub1); - let (sub_no_defaults_2, _) = + let sub_no_defaults_2 = self.tcx.generics_of(did2).own_args_no_defaults(self.tcx, sub2); let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new()); let path1 = self.tcx.def_path_str(did1); diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index b8dc42b73cdf1..8fe6c1b0d86fd 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -757,7 +757,6 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { .tcx .generics_of(def.did()) .own_args_no_defaults(self.tcx, args) - .0 .iter() .map(|&arg| self.arg_cost(arg)) .sum::() @@ -1186,7 +1185,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> { } let args = self.infcx.resolve_vars_if_possible(args); let generic_args = - &generics.own_args_no_defaults(tcx, args).0[generics.own_counts().lifetimes..]; + &generics.own_args_no_defaults(tcx, args)[generics.own_counts().lifetimes..]; let span = match expr.kind { ExprKind::MethodCall(path, ..) => path.ident.span, _ => expr.span, diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index e2e9102a61a7d..b93fe02aaeab0 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -116,7 +116,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // FIXME: extract this logic for use in other diagnostics. let (trait_ref, assoc_args) = proj.trait_ref_and_own_args(tcx); let item_name = tcx.item_name(proj.def_id); - let item_args = self.format_generic_args(proj.def_id, assoc_args); + let item_args = self.format_generic_args(assoc_args); // Here, we try to see if there's an existing // trait implementation that matches the one that @@ -775,7 +775,7 @@ fn foo(&self) -> Self::T { String::new() } let span = Span::new(pos, pos, span.ctxt(), span.parent()); (span, format!(", {} = {}", assoc.ident(tcx), ty)) } else { - let item_args = self.format_generic_args(assoc.def_id, assoc_args); + let item_args = self.format_generic_args(assoc_args); (span.shrink_to_hi(), format!("<{}{} = {}>", assoc.ident(tcx), item_args, ty)) }; diag.span_suggestion_verbose(span, msg(), sugg, MaybeIncorrect); @@ -784,13 +784,9 @@ fn foo(&self) -> Self::T { String::new() } false } - pub fn format_generic_args( - &self, - assoc_def_id: DefId, - args: &[ty::GenericArg<'tcx>], - ) -> String { + pub fn format_generic_args(&self, args: &[ty::GenericArg<'tcx>]) -> String { FmtPrinter::print_string(self.tcx, hir::def::Namespace::TypeNS, |cx| { - cx.path_generic_args(|_| Ok(()), args, &self.infcx.tcx.generics_of(assoc_def_id).params) + cx.path_generic_args(|_| Ok(()), args) }) .expect("could not write to `String`.") } diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index e3bda0828cb41..024e542d4afe4 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -1285,7 +1285,6 @@ impl<'tcx> LateContext<'tcx> { &mut self, print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>, _args: &[GenericArg<'tcx>], - _params: &[ty::GenericParamDef], ) -> Result<(), PrintError> { print_prefix(self) } diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index d376036d83221..4af886a971855 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -336,7 +336,8 @@ impl<'hir> Map<'hir> { /// Returns the `BodyOwnerKind` of this `LocalDefId`. /// /// Panics if `LocalDefId` does not have an associated body. - pub fn body_owner_kind(self, def_id: LocalDefId) -> BodyOwnerKind { + pub fn body_owner_kind(self, def_id: impl Into) -> BodyOwnerKind { + let def_id = def_id.into(); match self.tcx.def_kind(def_id) { DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => { BodyOwnerKind::Const { inline: false } @@ -356,20 +357,17 @@ impl<'hir> Map<'hir> { /// This should only be used for determining the context of a body, a return /// value of `Some` does not always suggest that the owner of the body is `const`, /// just that it has to be checked as if it were. - pub fn body_const_context(self, def_id: LocalDefId) -> Option { + pub fn body_const_context(self, def_id: impl Into) -> Option { + let def_id = def_id.into(); let ccx = match self.body_owner_kind(def_id) { BodyOwnerKind::Const { inline } => ConstContext::Const { inline }, BodyOwnerKind::Static(mt) => ConstContext::Static(mt), - BodyOwnerKind::Fn if self.tcx.is_constructor(def_id.to_def_id()) => return None, - BodyOwnerKind::Fn | BodyOwnerKind::Closure - if self.tcx.is_const_fn_raw(def_id.to_def_id()) => - { - ConstContext::ConstFn - } - BodyOwnerKind::Fn if self.tcx.is_const_default_method(def_id.to_def_id()) => { + BodyOwnerKind::Fn if self.tcx.is_constructor(def_id) => return None, + BodyOwnerKind::Fn | BodyOwnerKind::Closure if self.tcx.is_const_fn_raw(def_id) => { ConstContext::ConstFn } + BodyOwnerKind::Fn if self.tcx.is_const_default_method(def_id) => ConstContext::ConstFn, BodyOwnerKind::Fn | BodyOwnerKind::Closure => return None, }; diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 12294b0a602ce..c3699b114c411 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -320,21 +320,21 @@ impl<'tcx> Generics { &'tcx self, tcx: TyCtxt<'tcx>, args: &'tcx [ty::GenericArg<'tcx>], - ) -> (&'tcx [ty::GenericArg<'tcx>], &'tcx [ty::GenericParamDef]) { - let mut own_args = self.parent_count..self.count(); - let mut own_params = 0..self.params.len(); + ) -> &'tcx [ty::GenericArg<'tcx>] { + let mut own_params = self.parent_count..self.count(); if self.has_self && self.parent.is_none() { - own_args.start = 1; own_params.start = 1; } + let verbose = tcx.sess.verbose(); + // Filter the default arguments. // // This currently uses structural equality instead // of semantic equivalence. While not ideal, that's // good enough for now as this should only be used // for diagnostics anyways. - let num_default_params = self + own_params.end -= self .params .iter() .rev() @@ -342,12 +342,12 @@ impl<'tcx> Generics { param.default_value(tcx).is_some_and(|default| { default.instantiate(tcx, args) == args[param.index as usize] }) + // filter out trailing effect params, if we're not in `-Zverbose`. + || (!verbose && matches!(param.kind, GenericParamDefKind::Const { is_host_effect: true, .. })) }) .count(); - own_params.end -= num_default_params; - own_args.end -= num_default_params; - (&args[own_args], &self.params[own_params]) + &args[own_params] } /// Returns the args corresponding to the generic parameters of this item, excluding `Self`. diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index 948246c64e296..5e09154789a79 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -83,7 +83,6 @@ pub trait Printer<'tcx>: Sized { &mut self, print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>, args: &[GenericArg<'tcx>], - params: &[ty::GenericParamDef], ) -> Result<(), PrintError>; // Defaults (should not be overridden): @@ -142,12 +141,10 @@ pub trait Printer<'tcx>: Sized { // on top of the same path, but without its own generics. _ => { if !generics.params.is_empty() && args.len() >= generics.count() { - let (args, params) = - generics.own_args_no_defaults(self.tcx(), args); + let args = generics.own_args_no_defaults(self.tcx(), args); return self.path_generic_args( |cx| cx.print_def_path(def_id, parent_args), args, - params, ); } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 90358686fefdd..39adfac55cef3 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -965,7 +965,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { define_scoped_cx!(cx); // Get the (single) generic ty (the args) of this FnOnce trait ref. let generics = tcx.generics_of(trait_ref.def_id); - let (own_args, _) = generics.own_args_no_defaults(tcx, trait_ref.args); + let own_args = generics.own_args_no_defaults(tcx, trait_ref.args); match (entry.return_ty, own_args[0].expect_ty()) { // 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 { p!(print(trait_ref.print_only_trait_name())); let generics = tcx.generics_of(trait_ref.def_id); - let (own_args, _) = generics.own_args_no_defaults(tcx, trait_ref.args); + let own_args = generics.own_args_no_defaults(tcx, trait_ref.args); if !own_args.is_empty() || !assoc_items.is_empty() { let mut first = true; @@ -1183,7 +1183,6 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { ) }, &alias_ty.args[1..], - &self.tcx().generics_of(alias_ty.def_id).params, ) } @@ -1232,7 +1231,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { let dummy_cx = Ty::new_fresh(cx.tcx(), 0); let principal = principal.with_self_ty(cx.tcx(), dummy_cx); - let (args, _) = cx + let args = cx .tcx() .generics_of(principal.def_id) .own_args_no_defaults(cx.tcx(), principal.args); @@ -2030,26 +2029,14 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> { &mut self, print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>, args: &[GenericArg<'tcx>], - params: &[ty::GenericParamDef], ) -> Result<(), PrintError> { print_prefix(self)?; - let tcx = self.tcx; - let verbose = tcx.sess.verbose(); - let mut args = args - .iter() - .copied() - .zip(params) - // If -Zverbose is passed, we should print the host parameter instead - // of eating it. - .filter(|(_, param)| verbose || !param.is_host_effect()) - .peekable(); - - if args.peek().is_some() { + if !args.is_empty() { if self.in_value { write!(self, "::")?; } - self.generic_delimiters(|cx| cx.comma_sep(args.map(|(arg, _)| arg))) + self.generic_delimiters(|cx| cx.comma_sep(args.iter().copied())) } else { Ok(()) } @@ -2881,7 +2868,8 @@ define_print_and_forward_display! { TraitPredPrintModifiersAndPath<'tcx> { if let Some(idx) = cx.tcx().generics_of(self.0.trait_ref.def_id).host_effect_index { - if self.0.trait_ref.args.const_at(idx) != cx.tcx().consts.true_ { + let arg = self.0.trait_ref.args.const_at(idx); + if arg != cx.tcx().consts.true_ && !arg.has_infer() { p!("~const "); } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 1da090a7e46ee..8b1d33848eab3 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -782,7 +782,8 @@ impl<'tcx> TyCtxt<'tcx> { || self.extern_crate(key.as_def_id()).is_some_and(|e| e.is_direct()) } - pub fn expected_host_effect_param_for_body(self, def_id: LocalDefId) -> ty::Const<'tcx> { + pub fn expected_host_effect_param_for_body(self, def_id: impl Into) -> ty::Const<'tcx> { + let def_id = def_id.into(); // FIXME(effects): This is suspicious and should probably not be done, // especially now that we enforce host effects and then properly handle // effect vars during fallback. diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 14cd46cb062f6..0178ff53b24a3 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -342,7 +342,6 @@ impl<'tcx> Printer<'tcx> for SymbolPrinter<'tcx> { &mut self, print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>, args: &[GenericArg<'tcx>], - _params: &[ty::GenericParamDef], ) -> Result<(), PrintError> { print_prefix(self)?; diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 112e06a0dc270..e002e345ae689 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -298,7 +298,6 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { ) }, args, - &self.tcx.generics_of(impl_def_id).params, )?; } else { self.push_disambiguator(key.disambiguated_data.disambiguator as u64); @@ -801,7 +800,6 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { &mut self, print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>, args: &[GenericArg<'tcx>], - _params: &[ty::GenericParamDef], ) -> Result<(), PrintError> { // Don't print any regions if they're all erased. let print_regions = args.iter().any(|arg| match arg.unpack() { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 95ffd07e39783..f7e8dc62a625d 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -3628,17 +3628,19 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { is_derivable_trait && // Ensure all fields impl the trait. adt.all_fields().all(|field| { - let field_ty = field.ty(self.tcx, args); + let field_ty = ty::GenericArg::from(field.ty(self.tcx, args)); let trait_args = match diagnostic_name { sym::PartialEq | sym::PartialOrd => { Some(field_ty) } _ => None, }; + // Also add host param, if present + let host = self.tcx.generics_of(trait_pred.def_id()).host_effect_index.map(|idx| trait_pred.skip_binder().trait_ref.args[idx]); let trait_pred = trait_pred.map_bound_ref(|tr| ty::TraitPredicate { trait_ref: ty::TraitRef::new(self.tcx, trait_pred.def_id(), - [field_ty].into_iter().chain(trait_args), + [field_ty].into_iter().chain(trait_args).chain(host), ), ..*tr }); @@ -3659,6 +3661,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { trait_pred.skip_binder().self_ty(), diagnostic_name, ), + // FIXME(effects, const_trait_impl) derive_const as suggestion? format!("#[derive({diagnostic_name})]\n"), Applicability::MaybeIncorrect, ); diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index fadf2fcc9fce6..85246f4f3dc4d 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -224,6 +224,7 @@ use self::Ordering::*; append_const_msg )] #[rustc_diagnostic_item = "PartialEq"] +#[cfg_attr(not(bootstrap), const_trait)] pub trait PartialEq { /// This method tests for `self` and `other` values to be equal, and is used /// by `==`. @@ -1414,12 +1415,23 @@ mod impls { macro_rules! partial_eq_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(bootstrap)] impl PartialEq for $t { #[inline] fn eq(&self, other: &$t) -> bool { (*self) == (*other) } #[inline] fn ne(&self, other: &$t) -> bool { (*self) != (*other) } } + + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + #[cfg(not(bootstrap))] + impl const PartialEq for $t { + #[inline] + fn eq(&self, other: &$t) -> bool { (*self) == (*other) } + #[inline] + fn ne(&self, other: &$t) -> bool { (*self) != (*other) } + } )*) } diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index 61faaa10b8a43..d8abe411030b6 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -450,12 +450,12 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r && let Some(def_id) = trait_ref.trait_def_id() && cx.tcx.is_diagnostic_item(sym::PartialEq, def_id) && let param_env = param_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id) - && !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, &[]) + && !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, adt.did(),&[]) // If all of our fields implement `Eq`, we can implement `Eq` too && adt .all_fields() .map(|f| f.ty(cx.tcx, args)) - .all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, &[])) + .all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, adt.did(), &[])) { span_lint_and_sugg( cx, diff --git a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs index 9a66cbde53c0f..4811691c80d1e 100644 --- a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs +++ b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs @@ -194,6 +194,10 @@ fn is_same_generics<'tcx>( .enumerate() .skip(1) // skip `Self` implicit arg .all(|(arg_index, arg)| { + if [implied_by_generics.host_effect_index, implied_generics.host_effect_index].contains(&Some(arg_index)) { + // skip host effect params in determining whether generics are same + return true; + } if let Some(ty) = arg.as_type() { if let &ty::Param(ty::ParamTy { index, .. }) = ty.kind() // `index == 0` means that it's referring to `Self`, diff --git a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs index 1c2b7a169fc39..c7980060807c3 100644 --- a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs @@ -118,7 +118,7 @@ fn is_ref_iterable<'tcx>( .liberate_late_bound_regions(fn_id, cx.tcx.fn_sig(fn_id).skip_binder()) && let &[req_self_ty, req_res_ty] = &**sig.inputs_and_output && let param_env = cx.tcx.param_env(fn_id) - && implements_trait_with_env(cx.tcx, param_env, req_self_ty, trait_id, &[]) + && implements_trait_with_env(cx.tcx, param_env, req_self_ty, trait_id, fn_id, &[]) && let Some(into_iter_ty) = make_normalized_projection_with_regions(cx.tcx, param_env, trait_id, sym!(IntoIter), [req_self_ty]) && let req_res_ty = normalize_with_regions(cx.tcx, param_env, req_res_ty) diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 27da44812eb1a..2c5c3dcaa7528 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -186,6 +186,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { cx.param_env, ty, t, + None, [Option::>::None], ) }) diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index 1e748a46922cb..868c92f2f54d8 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -214,7 +214,8 @@ pub fn implements_trait<'tcx>( trait_id: DefId, args: &[GenericArg<'tcx>], ) -> bool { - implements_trait_with_env_from_iter(cx.tcx, cx.param_env, ty, trait_id, args.iter().map(|&x| Some(x))) + let callee_id = cx.enclosing_body.map(|body| cx.tcx.hir().body_owner(body).owner.to_def_id()); + implements_trait_with_env_from_iter(cx.tcx, cx.param_env, ty, trait_id, callee_id, args.iter().map(|&x| Some(x))) } /// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context. @@ -223,9 +224,10 @@ pub fn implements_trait_with_env<'tcx>( param_env: ParamEnv<'tcx>, ty: Ty<'tcx>, trait_id: DefId, + callee_id: DefId, args: &[GenericArg<'tcx>], ) -> bool { - implements_trait_with_env_from_iter(tcx, param_env, ty, trait_id, args.iter().map(|&x| Some(x))) + implements_trait_with_env_from_iter(tcx, param_env, ty, trait_id, Some(callee_id), args.iter().map(|&x| Some(x))) } /// Same as `implements_trait_from_env` but takes the arguments as an iterator. @@ -234,6 +236,7 @@ pub fn implements_trait_with_env_from_iter<'tcx>( param_env: ParamEnv<'tcx>, ty: Ty<'tcx>, trait_id: DefId, + callee_id: Option, args: impl IntoIterator>>>, ) -> bool { // Clippy shouldn't have infer types @@ -245,20 +248,29 @@ pub fn implements_trait_with_env_from_iter<'tcx>( } let infcx = tcx.infer_ctxt().build(); + let args = args.into_iter().map(|arg| { + arg.into().unwrap_or_else(|| { + let orig = TypeVariableOrigin { + kind: TypeVariableOriginKind::MiscVariable, + span: DUMMY_SP, + }; + infcx.next_ty_var(orig).into() + }) + }).collect::>(); + + // If an effect arg was not specified, we need to specify it. + let effect_arg = if tcx.generics_of(trait_id).host_effect_index.is_some_and(|x| args.get(x - 1).is_none()) { + Some(GenericArg::from(callee_id.map(|def_id| tcx.expected_host_effect_param_for_body(def_id)).unwrap_or(tcx.consts.true_))) + } else { + None + }; + let trait_ref = TraitRef::new( tcx, trait_id, Some(GenericArg::from(ty)) .into_iter() - .chain(args.into_iter().map(|arg| { - arg.into().unwrap_or_else(|| { - let orig = TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: DUMMY_SP, - }; - infcx.next_ty_var(orig).into() - }) - })), + .chain(args).chain(effect_arg), ); debug_assert_matches!( diff --git a/tests/ui/consts/fn_trait_refs.stderr b/tests/ui/consts/fn_trait_refs.stderr index 3d82837d53040..e5ebe1d852861 100644 --- a/tests/ui/consts/fn_trait_refs.stderr +++ b/tests/ui/consts/fn_trait_refs.stderr @@ -4,12 +4,6 @@ error[E0635]: unknown feature `const_fn_trait_ref_impls` LL | #![feature(const_fn_trait_ref_impls)] | ^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0635]: unknown feature `const_cmp` - --> $DIR/fn_trait_refs.rs:8:12 - | -LL | #![feature(const_cmp)] - | ^^^^^^^^^ - error: ~const can only be applied to `#[const_trait]` traits --> $DIR/fn_trait_refs.rs:15:15 | @@ -80,6 +74,6 @@ LL | T: ~const FnMut<()> + ~const Destruct, | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 12 previous errors +error: aborting due to 11 previous errors For more information about this error, try `rustc --explain E0635`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.rs index 5120e6bfb4117..50c46579086c6 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.rs @@ -1,4 +1,4 @@ -// known-bug: #110395 +// check-pass #![feature(const_trait_impl)] #[const_trait] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.stderr deleted file mode 100644 index 4007fd455f88c..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/call-generic-in-impl.rs:9:16 - | -LL | impl const MyPartialEq for T { - | ^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.rs index 3febb328a83ca..0df370bff8dac 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.rs @@ -1,8 +1,8 @@ //! Basic test for calling methods on generic type parameters in `const fn`. -// known-bug: #110395 +// check-pass -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] struct S; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr deleted file mode 100644 index 37faa3f6bce23..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/call-generic-method-chain.rs:18:32 - | -LL | const fn equals_self(t: &T) -> bool { - | ^^^^^^^^^ - -error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/call-generic-method-chain.rs:22:40 - | -LL | const fn equals_self_wrapper(t: &T) -> bool { - | ^^^^^^^^^ - -error: aborting due to 2 previous errors - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs index e618160d3b6f0..b0d5d06851526 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs @@ -1,6 +1,6 @@ -// known-bug: #110395 +// check-pass -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] struct S; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr deleted file mode 100644 index 90cfe04a9a862..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/call-generic-method-dup-bound.rs:18:44 - | -LL | const fn equals_self(t: &T) -> bool { - | ^^^^^^^^^ - -error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/call-generic-method-dup-bound.rs:25:37 - | -LL | const fn equals_self2(t: &T) -> bool { - | ^^^^^^^^^ - -error: aborting due to 2 previous errors - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.rs index 53778b3af3d4b..043939750a856 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.rs @@ -1,10 +1,9 @@ -// FIXME(effects) -// check-pass #![feature(const_trait_impl, effects)] pub const fn equals_self(t: &T) -> bool { *t == *t - // (remove this) ~^ ERROR can't compare + //~^ ERROR mismatched types + // FIXME(effects): diagnostic } fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.stderr new file mode 100644 index 0000000000000..5074c4a22610b --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/call-generic-method-fail.rs:4:5 + | +LL | *t == *t + | ^^^^^^^^ expected `host`, found `true` + | + = note: expected constant `host` + found constant `true` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs index b9331caaf8efb..76bc738123d39 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs @@ -21,7 +21,6 @@ const fn equals_self(t: &T) -> bool { // it not using the impl. pub const EQ: bool = equals_self(&S); -//~^ ERROR -// FIXME(effects) the diagnostics here isn't ideal, we shouldn't get `` +//~^ ERROR: the trait bound `S: ~const Foo` is not satisfied fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.rs index 09f35a277371e..abd5d2fdb393b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.rs @@ -1,8 +1,8 @@ //! Basic test for calling methods on generic type parameters in `const fn`. -// known-bug: #110395 +// check-pass -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] struct S; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr deleted file mode 100644 index 1f7cf689e9581..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/call-generic-method-pass.rs:18:32 - | -LL | const fn equals_self(t: &T) -> bool { - | ^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.rs index 8e4de57b019da..14d306fc31f6b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.rs @@ -3,6 +3,7 @@ #![feature( associated_type_bounds, const_trait_impl, + effects, const_cmp, )] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr index 4a9090d0b53dd..ddedf8f1d8d27 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr @@ -1,39 +1,28 @@ -error[E0635]: unknown feature `const_cmp` - --> $DIR/const-impl-trait.rs:6:5 +error[E0277]: can't compare `impl PartialEq + Destruct + Copy` with `impl PartialEq + Destruct + Copy` + --> $DIR/const-impl-trait.rs:28:17 | -LL | const_cmp, - | ^^^^^^^^^ - -error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:11:30 - | -LL | const fn cmp(a: &impl ~const PartialEq) -> bool { - | ^^^^^^^^^ - -error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:15:30 - | -LL | const fn wrap(x: impl ~const PartialEq + ~const Destruct) - | ^^^^^^^^^ - -error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:16:20 +LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `impl PartialEq + Destruct + Copy == impl PartialEq + Destruct + Copy` | -LL | -> impl ~const PartialEq + ~const Destruct - | ^^^^^^^^^ - -error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:23:29 + = help: the trait `~const PartialEq` is not implemented for `impl PartialEq + Destruct + Copy` +note: required by a bound in `Foo::{opaque#0}` + --> $DIR/const-impl-trait.rs:24:22 | LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; - | ^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ required by this bound in `Foo::{opaque#0}` -error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:27:29 +error[E0277]: can't drop `impl PartialEq + Destruct + Copy` + --> $DIR/const-impl-trait.rs:28:17 | LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy { - | ^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `impl PartialEq + Destruct + Copy` + | +note: required by a bound in `Foo::{opaque#0}` + --> $DIR/const-impl-trait.rs:24:41 + | +LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; + | ^^^^^^^^^^^^^^^ required by this bound in `Foo::{opaque#0}` -error: aborting due to 6 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0635`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs index 69098542b7e36..42d7283699fae 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs @@ -1,5 +1,6 @@ // known-bug: #110395 -#![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)] + +#![feature(const_trait_impl, const_cmp, const_default_impls, derive_const, effects)] pub struct A; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr index 046dbae0eae7e..c561f80653c9f 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr @@ -1,15 +1,28 @@ -error[E0635]: unknown feature `const_cmp` - --> $DIR/derive-const-use.rs:2:30 - | -LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)] - | ^^^^^^^^^ - error[E0635]: unknown feature `const_default_impls` - --> $DIR/derive-const-use.rs:2:41 + --> $DIR/derive-const-use.rs:3:41 | -LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)] +LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const, effects)] | ^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: const `impl` for trait `Default` which is not marked with `#[const_trait]` + --> $DIR/derive-const-use.rs:7:12 + | +LL | impl const Default for A { + | ^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `Default` which is not marked with `#[const_trait]` + --> $DIR/derive-const-use.rs:15:16 + | +LL | #[derive_const(Default, PartialEq)] + | ^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0635`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.rs index 2a5d0176ba004..b479c967b0dab 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.rs @@ -1,7 +1,7 @@ -// known-bug: #110395 +// check-pass #![feature(derive_const)] -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #[derive_const(PartialEq)] pub struct Reverse(T); diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr deleted file mode 100644 index 3a8c4833414b8..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/derive-const-with-params.rs:6:16 - | -LL | #[derive_const(PartialEq)] - | ^^^^^^^^^ - | - = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 1 previous error - diff --git a/tests/ui/suggestions/invalid-bin-op.stderr b/tests/ui/suggestions/invalid-bin-op.stderr index 018250c8c1b60..2bd745c645a1c 100644 --- a/tests/ui/suggestions/invalid-bin-op.stderr +++ b/tests/ui/suggestions/invalid-bin-op.stderr @@ -16,10 +16,6 @@ help: consider annotating `S` with `#[derive(PartialEq)]` LL + #[derive(PartialEq)] LL | struct S(T); | -help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement - | -LL | pub fn foo(s: S, t: S) where S: PartialEq { - | +++++++++++++++++++++ error: aborting due to 1 previous error