diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index d5f418e1710e3..7e1cbfe66674c 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -172,7 +172,7 @@ impl Qualif for NeedsNonConstDrop { destruct_def_id, [ ty::GenericArg::from(ty), - ty::GenericArg::from(cx.tcx.expected_const_effect_param_for_body(cx.def_id())), + ty::GenericArg::from(cx.tcx.expected_host_effect_param_for_body(cx.def_id())), ], ), ); diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs index a82b65b19a882..b6240906611a9 100644 --- a/compiler/rustc_const_eval/src/util/type_name.rs +++ b/compiler/rustc_const_eval/src/util/type_name.rs @@ -120,6 +120,7 @@ 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_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index a907acba0e030..512946cc5046a 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -780,7 +780,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let generics = tcx.generics_of(callee_did); let Some(host_effect_index) = generics.host_effect_index else { return }; - let effect = tcx.expected_const_effect_param_for_body(self.body_id); + let effect = tcx.expected_host_effect_param_for_body(self.body_id); trace!(?effect, ?generics, ?callee_args); diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 745c3d195ada7..0004f16fc4e3f 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -641,6 +641,7 @@ 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) } @@ -1236,9 +1237,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 8fe6c1b0d86fd..b8dc42b73cdf1 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,6 +757,7 @@ 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::() @@ -1185,7 +1186,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)[generics.own_counts().lifetimes..]; + &generics.own_args_no_defaults(tcx, args).0[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 b93fe02aaeab0..e2e9102a61a7d 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(assoc_args); + let item_args = self.format_generic_args(proj.def_id, 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_args); + let item_args = self.format_generic_args(assoc.def_id, assoc_args); (span.shrink_to_hi(), format!("<{}{} = {}>", assoc.ident(tcx), item_args, ty)) }; diag.span_suggestion_verbose(span, msg(), sugg, MaybeIncorrect); @@ -784,9 +784,13 @@ fn foo(&self) -> Self::T { String::new() } false } - pub fn format_generic_args(&self, args: &[ty::GenericArg<'tcx>]) -> String { + pub fn format_generic_args( + &self, + assoc_def_id: DefId, + args: &[ty::GenericArg<'tcx>], + ) -> String { FmtPrinter::print_string(self.tcx, hir::def::Namespace::TypeNS, |cx| { - cx.path_generic_args(|_| Ok(()), args) + cx.path_generic_args(|_| Ok(()), args, &self.infcx.tcx.generics_of(assoc_def_id).params) }) .expect("could not write to `String`.") } diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 024e542d4afe4..e3bda0828cb41 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -1285,6 +1285,7 @@ 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/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 8316f9c30587f..12294b0a602ce 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -320,9 +320,11 @@ impl<'tcx> Generics { &'tcx self, tcx: TyCtxt<'tcx>, args: &'tcx [ty::GenericArg<'tcx>], - ) -> &'tcx [ty::GenericArg<'tcx>] { - let mut own_params = self.parent_count..self.count(); + ) -> (&'tcx [ty::GenericArg<'tcx>], &'tcx [ty::GenericParamDef]) { + let mut own_args = self.parent_count..self.count(); + let mut own_params = 0..self.params.len(); if self.has_self && self.parent.is_none() { + own_args.start = 1; own_params.start = 1; } @@ -332,7 +334,7 @@ impl<'tcx> Generics { // of semantic equivalence. While not ideal, that's // good enough for now as this should only be used // for diagnostics anyways. - own_params.end -= self + let num_default_params = self .params .iter() .rev() @@ -342,8 +344,10 @@ impl<'tcx> Generics { }) }) .count(); + own_params.end -= num_default_params; + own_args.end -= num_default_params; - &args[own_params] + (&args[own_args], &self.params[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 5e09154789a79..948246c64e296 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -83,6 +83,7 @@ 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): @@ -141,10 +142,12 @@ 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 = generics.own_args_no_defaults(self.tcx(), args); + let (args, params) = + 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 bd9f0fd3ea9c5..fd53111001b7c 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -19,7 +19,6 @@ use rustc_hir::LangItem; use rustc_session::config::TrimmedDefPaths; use rustc_session::cstore::{ExternCrate, ExternCrateSource}; use rustc_session::Limit; -use rustc_span::sym; use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_span::FileNameDisplayPreference; use rustc_target::abi::Size; @@ -967,7 +966,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 @@ -1033,7 +1032,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; @@ -1185,6 +1184,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { ) }, &alias_ty.args[1..], + &self.tcx().generics_of(alias_ty.def_id).params, ) } @@ -1233,7 +1233,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); @@ -2031,40 +2031,26 @@ 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 args = args.iter().copied(); - - let args: Vec<_> = if !tcx.sess.verbose() { - // skip host param as those are printed as `~const` - args.filter(|arg| match arg.unpack() { - // FIXME(effects) there should be a better way than just matching the name - GenericArgKind::Const(c) - if tcx.features().effects - && matches!( - c.kind(), - ty::ConstKind::Param(ty::ParamConst { name: sym::host, .. }) - ) => - { - false - } - _ => true, - }) - .collect() - } else { + 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. - args.collect() - }; + .filter(|(_, param)| verbose || !param.is_host_effect()) + .peekable(); - if !args.is_empty() { + if args.peek().is_some() { if self.in_value { write!(self, "::")?; } - self.generic_delimiters(|cx| cx.comma_sep(args.into_iter())) + self.generic_delimiters(|cx| cx.comma_sep(args.map(|(arg, _)| arg))) } else { Ok(()) } @@ -2894,11 +2880,15 @@ define_print_and_forward_display! { } TraitPredPrintModifiersAndPath<'tcx> { - // FIXME(effects) print `~const` here + 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_ { + p!("~const "); + } + } if let ty::ImplPolarity::Negative = self.0.polarity { p!("!") } - p!(print(self.0.trait_ref.print_only_trait_path())); } @@ -2933,7 +2923,6 @@ define_print_and_forward_display! { p!("~const "); } } - // FIXME(effects) print `~const` here if let ty::ImplPolarity::Negative = self.polarity { p!("!"); } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index b7c3edee9e59e..1da090a7e46ee 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -782,7 +782,7 @@ impl<'tcx> TyCtxt<'tcx> { || self.extern_crate(key.as_def_id()).is_some_and(|e| e.is_direct()) } - pub fn expected_const_effect_param_for_body(self, def_id: LocalDefId) -> ty::Const<'tcx> { + pub fn expected_host_effect_param_for_body(self, def_id: LocalDefId) -> ty::Const<'tcx> { // 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. @@ -817,7 +817,7 @@ impl<'tcx> TyCtxt<'tcx> { } /// Constructs generic args for an item, optionally appending a const effect param type - pub fn with_opt_const_effect_param( + pub fn with_opt_host_effect_param( self, caller_def_id: LocalDefId, callee_def_id: DefId, @@ -826,9 +826,10 @@ impl<'tcx> TyCtxt<'tcx> { let generics = self.generics_of(callee_def_id); assert_eq!(generics.parent, None); - let opt_const_param = generics.host_effect_index.is_some().then(|| { - ty::GenericArg::from(self.expected_const_effect_param_for_body(caller_def_id)) - }); + let opt_const_param = generics + .host_effect_index + .is_some() + .then(|| ty::GenericArg::from(self.expected_host_effect_param_for_body(caller_def_id))); self.mk_args_from_iter(args.into_iter().map(|arg| arg.into()).chain(opt_const_param)) } diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 642ac9b49c8cf..d1952704da3ce 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -500,7 +500,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.tcx, eq_def_id, sym::eq, - self.tcx.with_opt_const_effect_param(self.def_id, eq_def_id, [ty, ty]), + self.tcx.with_opt_host_effect_param(self.def_id, eq_def_id, [ty, ty]), ); let bool_ty = self.tcx.types.bool; diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 4e2c932d6c6a3..391d65b338d55 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -272,7 +272,7 @@ impl<'tcx> ConstToPat<'tcx> { ty::TraitRef::new( tcx, partial_eq_trait_id, - tcx.with_opt_const_effect_param( + tcx.with_opt_host_effect_param( tcx.hir().enclosing_body_owner(self.id), partial_eq_trait_id, [ty, ty], diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 0178ff53b24a3..14cd46cb062f6 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -342,6 +342,7 @@ 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 e002e345ae689..112e06a0dc270 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -298,6 +298,7 @@ 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); @@ -800,6 +801,7 @@ 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/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr index 8d809907a5357..93d520f29ef28 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `u32: ~const Plus` is not satisfied --> $DIR/call-const-trait-method-fail.rs:25:5 | LL | a.plus(b) - | ^ the trait `Plus` is not implemented for `u32` + | ^ the trait `~const Plus` is not implemented for `u32` | = help: the trait `Plus` is implemented for `u32` diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr index 4fe296d4d3fa9..aea9a39b26107 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `S: ~const Foo` is not satisfied +error[E0277]: the trait bound `S: ~const Foo` is not satisfied --> $DIR/call-generic-method-nonconst.rs:23:34 | LL | pub const EQ: bool = equals_self(&S); - | ----------- ^^ the trait `Foo` is not implemented for `S` + | ----------- ^^ the trait `~const Foo` is not implemented for `S` | | | required by a bound introduced by this call | diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr index 111a6a3fc7f81..f39e6dcadbaa6 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satis --> $DIR/const-default-method-bodies.rs:24:18 | LL | NonConstImpl.a(); - | ^ the trait `ConstDefaultFn` is not implemented for `NonConstImpl` + | ^ the trait `~const ConstDefaultFn` is not implemented for `NonConstImpl` | = help: the trait `ConstDefaultFn` is implemented for `NonConstImpl` diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr index ed647aee8c370..f0ac953fd5d20 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrai --> $DIR/cross-crate.rs:17:14 | LL | NonConst.func(); - | ^^^^ the trait `cross_crate::MyTrait` is not implemented for `cross_crate::NonConst` + | ^^^^ the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst` | = help: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst` diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr index d8e2c0ffb813a..29db6109a98c4 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `(): ~const Tr` is not satisfied --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12 | LL | ().a() - | ^ the trait `Tr` is not implemented for `()` + | ^ the trait `~const Tr` is not implemented for `()` | = help: the trait `Tr` is implemented for `()`