From b9754f9e7bfe2d8eed780962b550a25a87118ce4 Mon Sep 17 00:00:00 2001 From: "Celina G. Val" Date: Tue, 25 Feb 2025 13:24:07 -0800 Subject: Enable contracts for const functions Use `const_eval_select!()` macro to enable contract checking only at runtime. The existing contract logic relies on closures, which are not supported in constant functions. This commit also removes one level of indirection for ensures clauses, however, it currently has a spurious warning message when the bottom of the function is unreachable. --- compiler/rustc_hir_analysis/src/check/intrinsic.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'compiler/rustc_hir_analysis/src') diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 42d785c8dd0..290e47b42b5 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -232,15 +232,11 @@ pub fn check_intrinsic_type( }; (n_tps, 0, 0, inputs, output, hir::Safety::Unsafe) } else if intrinsic_name == sym::contract_check_ensures { - // contract_check_ensures::<'a, Ret, C>(&'a Ret, C) - // where C: impl Fn(&'a Ret) -> bool, + // contract_check_ensures::(Ret, C) -> Ret + // where C: for<'a> Fn(&'a Ret) -> bool, // - // so: two type params, one lifetime param, 0 const params, two inputs, no return - - let p = generics.param_at(0, tcx); - let r = ty::Region::new_early_param(tcx, p.to_early_bound_region_data()); - let ref_ret = Ty::new_imm_ref(tcx, r, param(1)); - (2, 1, 0, vec![ref_ret, param(2)], tcx.types.unit, hir::Safety::Safe) + // so: two type params, 0 lifetime param, 0 const params, two inputs, no return + (2, 0, 0, vec![param(0), param(1)], param(0), hir::Safety::Safe) } else { let safety = intrinsic_operation_unsafety(tcx, intrinsic_id); let (n_tps, n_cts, inputs, output) = match intrinsic_name { -- cgit 1.4.1-3-g733a5 From 3feac59b794acf326c0efebaabd500e47fc65ba9 Mon Sep 17 00:00:00 2001 From: "Celina G. Val" Date: Mon, 7 Apr 2025 17:42:08 -0700 Subject: Fix unreachable expression warning Invert the order that we pass the arguments to the `contract_check_ensures` function to avoid the warning when the tail of the function is unreachable. Note that the call itself is also unreachable, but we have already handled that case by ignoring unreachable call for contract calls. --- compiler/rustc_ast_lowering/src/expr.rs | 3 +-- compiler/rustc_ast_lowering/src/item.rs | 9 ++++++++- compiler/rustc_hir_analysis/src/check/intrinsic.rs | 2 +- library/core/src/contracts.rs | 15 ++++++++++----- library/core/src/intrinsics/mod.rs | 11 +++++++++-- .../ui/contracts/contract-attributes-nest.chk_pass.stderr | 13 +------------ tests/ui/contracts/contract-attributes-nest.rs | 1 - .../contract-attributes-nest.unchk_fail_post.stderr | 13 +------------ .../contract-attributes-nest.unchk_fail_pre.stderr | 13 +------------ .../contracts/contract-attributes-nest.unchk_pass.stderr | 13 +------------ .../contract-captures-via-closure-noncopy.stderr | 1 + .../internal_machinery/contract-ast-extensions-nest.rs | 1 - .../contracts/internal_machinery/contract-intrinsics.rs | 4 ++-- .../contracts/internal_machinery/contract-lang-items.rs | 2 +- .../internal_machinery/internal-feature-gating.rs | 2 +- .../internal_machinery/internal-feature-gating.stderr | 2 +- 16 files changed, 39 insertions(+), 66 deletions(-) (limited to 'compiler/rustc_hir_analysis/src') diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 0b7a7630431..c3f57e11183 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -401,11 +401,10 @@ impl<'hir> LoweringContext<'_, 'hir> { cond_hir_id: HirId, ) -> &'hir hir::Expr<'hir> { let cond_fn = self.expr_ident(span, cond_ident, cond_hir_id); - let span = self.mark_span_with_reason(DesugaringKind::Contract, span, None); let call_expr = self.expr_call_lang_item_fn_mut( span, hir::LangItem::ContractCheckEnsures, - arena_vec![self; *expr, *cond_fn], + arena_vec![self; *cond_fn, *expr], ); self.arena.alloc(call_expr) } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 28f596ac092..c89112fc5a3 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1209,8 +1209,13 @@ impl<'hir> LoweringContext<'_, 'hir> { let precond = if let Some(req) = &contract.requires { // Lower the precondition check intrinsic. let lowered_req = this.lower_expr_mut(&req); + let req_span = this.mark_span_with_reason( + DesugaringKind::Contract, + lowered_req.span, + None, + ); let precond = this.expr_call_lang_item_fn_mut( - req.span, + req_span, hir::LangItem::ContractCheckRequires, &*arena_vec![this; lowered_req], ); @@ -1220,6 +1225,8 @@ impl<'hir> LoweringContext<'_, 'hir> { }; let (postcond, body) = if let Some(ens) = &contract.ensures { let ens_span = this.lower_span(ens.span); + let ens_span = + this.mark_span_with_reason(DesugaringKind::Contract, ens_span, None); // Set up the postcondition `let` statement. let check_ident: Ident = Ident::from_str_and_span("__ensures_checker", ens_span); diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 290e47b42b5..e54fa89328c 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -236,7 +236,7 @@ pub fn check_intrinsic_type( // where C: for<'a> Fn(&'a Ret) -> bool, // // so: two type params, 0 lifetime param, 0 const params, two inputs, no return - (2, 0, 0, vec![param(0), param(1)], param(0), hir::Safety::Safe) + (2, 0, 0, vec![param(0), param(1)], param(1), hir::Safety::Safe) } else { let safety = intrinsic_operation_unsafety(tcx, intrinsic_id); let (n_tps, n_cts, inputs, output) = match intrinsic_name { diff --git a/library/core/src/contracts.rs b/library/core/src/contracts.rs index 82922642018..53f459debab 100644 --- a/library/core/src/contracts.rs +++ b/library/core/src/contracts.rs @@ -2,15 +2,20 @@ pub use crate::macros::builtin::{contracts_ensures as ensures, contracts_requires as requires}; -/// Emitted by rustc as a desugaring of `#[ensures(PRED)] fn foo() -> R { ... [return R;] ... }` -/// into: `fn foo() { let _check = build_check_ensures(|ret| PRED) ... [return _check(R);] ... }` -/// (including the implicit return of the tail expression, if any). +/// This is an identity function used as part of the desugaring of the `#[ensures]` attribute. /// -/// This call helps with type inference for the predicate. +/// This is an existing hack to allow users to omit the type of the return value in their ensures +/// attribute. +/// +/// Ideally, rustc should be able to generate the type annotation. +/// The existing lowering logic makes it rather hard to add the explicit type annotation, +/// while the function call is fairly straight forward. #[unstable(feature = "contracts_internals", issue = "128044" /* compiler-team#759 */)] +// Similar to `contract_check_requires`, we need to use the user-facing +// `contracts` feature rather than the perma-unstable `contracts_internals`. +// Const-checking doesn't honor allow internal unstable logic used by contract expansion. #[rustc_const_unstable(feature = "contracts", issue = "128044")] #[lang = "contract_build_check_ensures"] -#[track_caller] pub const fn build_check_ensures(cond: C) -> C where C: Fn(&Ret) -> bool + Copy + 'static, diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 8812cb66526..90f686a6728 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -3453,6 +3453,10 @@ pub const fn contract_checks() -> bool { /// /// Note that this function is a no-op during constant evaluation. #[unstable(feature = "contracts_internals", issue = "128044")] +// Calls to this function get inserted by an AST expansion pass, which uses the equivalent of +// `#[allow_internal_unstable]` to allow using `contracts_internals` functions. Const-checking +// doesn't honor `#[allow_internal_unstable]`, so for the const feature gate we use the user-facing +// `contracts` feature rather than the perma-unstable `contracts_internals` #[rustc_const_unstable(feature = "contracts", issue = "128044")] #[lang = "contract_check_requires"] #[rustc_intrinsic] @@ -3478,12 +3482,15 @@ pub const fn contract_check_requires bool + Copy>(cond: C) { /// Note that this function is a no-op during constant evaluation. #[cfg(not(bootstrap))] #[unstable(feature = "contracts_internals", issue = "128044")] +// Similar to `contract_check_requires`, we need to use the user-facing +// `contracts` feature rather than the perma-unstable `contracts_internals`. +// Const-checking doesn't honor allow internal unstable logic used by contract expansion. #[rustc_const_unstable(feature = "contracts", issue = "128044")] #[lang = "contract_check_ensures"] #[rustc_intrinsic] -pub const fn contract_check_ensures bool + Copy>(ret: Ret, cond: C) -> Ret { +pub const fn contract_check_ensures bool + Copy, Ret>(cond: C, ret: Ret) -> Ret { const_eval_select!( - @capture[Ret, C: Fn(&Ret) -> bool + Copy] { ret: Ret, cond: C } -> Ret : + @capture[C: Fn(&Ret) -> bool + Copy, Ret] { cond: C, ret: Ret } -> Ret : if const { // Do nothing ret diff --git a/tests/ui/contracts/contract-attributes-nest.chk_pass.stderr b/tests/ui/contracts/contract-attributes-nest.chk_pass.stderr index e7c42ad98a5..9ca95b8bb01 100644 --- a/tests/ui/contracts/contract-attributes-nest.chk_pass.stderr +++ b/tests/ui/contracts/contract-attributes-nest.chk_pass.stderr @@ -7,16 +7,5 @@ LL | #![feature(contracts)] = note: see issue #128044 for more information = note: `#[warn(incomplete_features)]` on by default -warning: unreachable expression - --> $DIR/contract-attributes-nest.rs:23:1 - | -LL | #[core::contracts::ensures(|ret| *ret > 100)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable expression -... -LL | return x.baz + 50; - | ----------------- any code following this expression is unreachable - | - = note: `#[warn(unreachable_code)]` on by default - -warning: 2 warnings emitted +warning: 1 warning emitted diff --git a/tests/ui/contracts/contract-attributes-nest.rs b/tests/ui/contracts/contract-attributes-nest.rs index 7c35e54c18b..e1e61b88f28 100644 --- a/tests/ui/contracts/contract-attributes-nest.rs +++ b/tests/ui/contracts/contract-attributes-nest.rs @@ -21,7 +21,6 @@ #[core::contracts::requires(x.baz > 0)] #[core::contracts::ensures(|ret| *ret > 100)] -//~^ WARN unreachable expression [unreachable_code] fn nest(x: Baz) -> i32 { loop { diff --git a/tests/ui/contracts/contract-attributes-nest.unchk_fail_post.stderr b/tests/ui/contracts/contract-attributes-nest.unchk_fail_post.stderr index e7c42ad98a5..9ca95b8bb01 100644 --- a/tests/ui/contracts/contract-attributes-nest.unchk_fail_post.stderr +++ b/tests/ui/contracts/contract-attributes-nest.unchk_fail_post.stderr @@ -7,16 +7,5 @@ LL | #![feature(contracts)] = note: see issue #128044 for more information = note: `#[warn(incomplete_features)]` on by default -warning: unreachable expression - --> $DIR/contract-attributes-nest.rs:23:1 - | -LL | #[core::contracts::ensures(|ret| *ret > 100)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable expression -... -LL | return x.baz + 50; - | ----------------- any code following this expression is unreachable - | - = note: `#[warn(unreachable_code)]` on by default - -warning: 2 warnings emitted +warning: 1 warning emitted diff --git a/tests/ui/contracts/contract-attributes-nest.unchk_fail_pre.stderr b/tests/ui/contracts/contract-attributes-nest.unchk_fail_pre.stderr index e7c42ad98a5..9ca95b8bb01 100644 --- a/tests/ui/contracts/contract-attributes-nest.unchk_fail_pre.stderr +++ b/tests/ui/contracts/contract-attributes-nest.unchk_fail_pre.stderr @@ -7,16 +7,5 @@ LL | #![feature(contracts)] = note: see issue #128044 for more information = note: `#[warn(incomplete_features)]` on by default -warning: unreachable expression - --> $DIR/contract-attributes-nest.rs:23:1 - | -LL | #[core::contracts::ensures(|ret| *ret > 100)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable expression -... -LL | return x.baz + 50; - | ----------------- any code following this expression is unreachable - | - = note: `#[warn(unreachable_code)]` on by default - -warning: 2 warnings emitted +warning: 1 warning emitted diff --git a/tests/ui/contracts/contract-attributes-nest.unchk_pass.stderr b/tests/ui/contracts/contract-attributes-nest.unchk_pass.stderr index e7c42ad98a5..9ca95b8bb01 100644 --- a/tests/ui/contracts/contract-attributes-nest.unchk_pass.stderr +++ b/tests/ui/contracts/contract-attributes-nest.unchk_pass.stderr @@ -7,16 +7,5 @@ LL | #![feature(contracts)] = note: see issue #128044 for more information = note: `#[warn(incomplete_features)]` on by default -warning: unreachable expression - --> $DIR/contract-attributes-nest.rs:23:1 - | -LL | #[core::contracts::ensures(|ret| *ret > 100)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable expression -... -LL | return x.baz + 50; - | ----------------- any code following this expression is unreachable - | - = note: `#[warn(unreachable_code)]` on by default - -warning: 2 warnings emitted +warning: 1 warning emitted diff --git a/tests/ui/contracts/contract-captures-via-closure-noncopy.stderr b/tests/ui/contracts/contract-captures-via-closure-noncopy.stderr index 4a47671fee1..b6f2e014e0a 100644 --- a/tests/ui/contracts/contract-captures-via-closure-noncopy.stderr +++ b/tests/ui/contracts/contract-captures-via-closure-noncopy.stderr @@ -16,6 +16,7 @@ LL | #[core::contracts::ensures({let old = x; move |ret:&Baz| ret.baz == old.baz | | within this `{closure@$DIR/contract-captures-via-closure-noncopy.rs:12:42: 12:57}` | | this tail expression is of type `{closure@contract-captures-via-closure-noncopy.rs:12:42}` | unsatisfied trait bound + | required by a bound introduced by this call | = help: within `{closure@$DIR/contract-captures-via-closure-noncopy.rs:12:42: 12:57}`, the trait `std::marker::Copy` is not implemented for `Baz` note: required because it's used within this closure diff --git a/tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs b/tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs index 7f9c3fe28ce..6d8cd3949ee 100644 --- a/tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs +++ b/tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs @@ -21,7 +21,6 @@ fn nest(x: Baz) -> i32 contract_requires(|| x.baz > 0) contract_ensures(|ret| *ret > 100) - //~^ WARN unreachable expression [unreachable_code] { loop { return x.baz + 50; diff --git a/tests/ui/contracts/internal_machinery/contract-intrinsics.rs b/tests/ui/contracts/internal_machinery/contract-intrinsics.rs index f94dfbde75f..c62b8cca75a 100644 --- a/tests/ui/contracts/internal_machinery/contract-intrinsics.rs +++ b/tests/ui/contracts/internal_machinery/contract-intrinsics.rs @@ -28,9 +28,9 @@ fn main() { let doubles_to_two = { let old = 2; move |ret: &u32 | ret + ret == old }; // Always pass - core::intrinsics::contract_check_ensures(1, doubles_to_two); + core::intrinsics::contract_check_ensures(doubles_to_two, 1); // Fail if enabled #[cfg(any(default, unchk_pass, chk_fail_ensures))] - core::intrinsics::contract_check_ensures(2, doubles_to_two); + core::intrinsics::contract_check_ensures(doubles_to_two, 2); } diff --git a/tests/ui/contracts/internal_machinery/contract-lang-items.rs b/tests/ui/contracts/internal_machinery/contract-lang-items.rs index 26042cf688f..73c59194531 100644 --- a/tests/ui/contracts/internal_machinery/contract-lang-items.rs +++ b/tests/ui/contracts/internal_machinery/contract-lang-items.rs @@ -22,7 +22,7 @@ fn foo(x: Baz) -> i32 { }; let ret = x.baz + 50; - core::intrinsics::contract_check_ensures(ret, injected_checker) + core::intrinsics::contract_check_ensures(injected_checker, ret) } struct Baz { baz: i32 } diff --git a/tests/ui/contracts/internal_machinery/internal-feature-gating.rs b/tests/ui/contracts/internal_machinery/internal-feature-gating.rs index 1b76eef6780..6e5a7a3f950 100644 --- a/tests/ui/contracts/internal_machinery/internal-feature-gating.rs +++ b/tests/ui/contracts/internal_machinery/internal-feature-gating.rs @@ -6,7 +6,7 @@ fn main() { //~^ ERROR use of unstable library feature `contracts_internals` core::intrinsics::contract_check_requires(|| true); //~^ ERROR use of unstable library feature `contracts_internals` - core::intrinsics::contract_check_ensures(&1, |_|true); + core::intrinsics::contract_check_ensures( |_|true, &1); //~^ ERROR use of unstable library feature `contracts_internals` core::contracts::build_check_ensures(|_: &()| true); diff --git a/tests/ui/contracts/internal_machinery/internal-feature-gating.stderr b/tests/ui/contracts/internal_machinery/internal-feature-gating.stderr index 7302694a787..1e39bd62e24 100644 --- a/tests/ui/contracts/internal_machinery/internal-feature-gating.stderr +++ b/tests/ui/contracts/internal_machinery/internal-feature-gating.stderr @@ -41,7 +41,7 @@ LL | core::intrinsics::contract_check_requires(|| true); error[E0658]: use of unstable library feature `contracts_internals` --> $DIR/internal-feature-gating.rs:9:5 | -LL | core::intrinsics::contract_check_ensures(&1, |_|true); +LL | core::intrinsics::contract_check_ensures( |_|true, &1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #128044 for more information -- cgit 1.4.1-3-g733a5 From ce2aa97cd647bdfcb5859489d93526622bb388a0 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 11 Apr 2025 06:28:59 +1000 Subject: Move `has_self` field to `hir::AssocKind::Fn`. `hir::AssocItem` currently has a boolean `fn_has_self_parameter` field, which is misplaced, because it's only relevant for associated fns, not for associated consts or types. This commit moves it (and renames it) to the `AssocKind::Fn` variant, where it belongs. This requires introducing a new C-style enum, `AssocTag`, which is like `AssocKind` but without the fields. This is because `AssocKind` values are passed to various functions like `find_by_ident_and_kind` to indicate what kind of associated item should be searched for, and having to specify `has_self` isn't relevant there. New methods: - Predicates `AssocItem::is_fn` and `AssocItem::is_method`. - `AssocItem::as_tag` which converts `AssocItem::kind` to `AssocTag`. Removed `find_by_name_and_kinds`, which is unused. `AssocItem::descr` can now distinguish between methods and associated functions, which slightly improves some error messages. --- compiler/rustc_ast_lowering/src/delegation.rs | 2 +- .../src/diagnostics/conflict_errors.rs | 2 +- compiler/rustc_codegen_cranelift/src/main_shim.rs | 4 +- compiler/rustc_hir_analysis/src/check/check.rs | 4 +- .../src/check/compare_impl_item.rs | 14 +-- compiler/rustc_hir_analysis/src/check/mod.rs | 8 +- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 6 +- compiler/rustc_hir_analysis/src/collect.rs | 6 +- .../src/collect/resolve_bound_vars.rs | 16 +-- .../src/collect/type_of/opaque.rs | 4 +- .../src/hir_ty_lowering/bounds.rs | 26 ++--- .../src/hir_ty_lowering/errors.rs | 57 +++++----- .../rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 124 ++++++++++++--------- compiler/rustc_hir_analysis/src/impl_wf_check.rs | 2 +- compiler/rustc_hir_typeck/src/demand.rs | 10 +- compiler/rustc_hir_typeck/src/expr.rs | 4 +- compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 5 +- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 2 +- compiler/rustc_hir_typeck/src/method/mod.rs | 2 +- compiler/rustc_hir_typeck/src/method/probe.rs | 15 ++- compiler/rustc_hir_typeck/src/method/suggest.rs | 27 +++-- compiler/rustc_lint/src/context.rs | 7 +- compiler/rustc_metadata/src/rmeta/decoder.rs | 11 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 +- compiler/rustc_middle/src/mir/mod.rs | 4 +- compiler/rustc_middle/src/ty/adjustment.rs | 4 +- compiler/rustc_middle/src/ty/assoc.rs | 62 ++++++----- compiler/rustc_middle/src/ty/instance.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 4 +- .../rustc_mir_build/src/builder/matches/test.rs | 2 +- compiler/rustc_mir_transform/src/shim.rs | 2 +- .../src/mono_checks/move_check.rs | 4 +- compiler/rustc_resolve/src/late/diagnostics.rs | 2 +- .../src/cfi/typeid/itanium_cxx_abi/transform.rs | 2 +- compiler/rustc_smir/src/rustc_smir/convert/ty.rs | 5 +- compiler/rustc_smir/src/stable_mir/mir/pretty.rs | 3 +- compiler/rustc_smir/src/stable_mir/ty.rs | 6 +- .../src/error_reporting/infer/mod.rs | 8 +- .../nice_region_error/trait_impl_difference.rs | 2 +- .../infer/nice_region_error/util.rs | 2 +- .../src/error_reporting/infer/note_and_explain.rs | 2 +- .../src/error_reporting/traits/ambiguity.rs | 2 +- .../src/error_reporting/traits/suggestions.rs | 2 +- .../src/traits/dyn_compatibility.rs | 4 +- .../rustc_trait_selection/src/traits/vtable.rs | 6 +- compiler/rustc_ty_utils/src/assoc.rs | 20 ++-- src/librustdoc/clean/inline.rs | 12 +- src/librustdoc/clean/mod.rs | 4 +- .../clippy_lints/src/bool_assert_comparison.rs | 2 +- src/tools/clippy/clippy_lints/src/len_zero.rs | 11 +- .../clippy_lints/src/methods/needless_collect.rs | 4 +- .../clippy/clippy_lints/src/methods/or_fun_call.rs | 2 +- .../src/needless_borrows_for_generic_args.rs | 2 +- .../clippy/clippy_lints/src/same_name_method.rs | 3 +- .../clippy_lints/src/unconditional_recursion.rs | 4 +- src/tools/clippy/clippy_lints/src/unused_self.rs | 2 +- src/tools/clippy/clippy_utils/src/ty/mod.rs | 6 +- .../ui/generic-associated-types/impl_bounds.stderr | 4 +- .../normalize/normalize-param-env-2.stderr | 4 +- 60 files changed, 288 insertions(+), 284 deletions(-) (limited to 'compiler/rustc_hir_analysis/src') diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 2296b05f69b..93c627f64c9 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -85,7 +85,7 @@ impl<'hir> LoweringContext<'_, 'hir> { .delegation_fn_sigs .get(&local_def_id) .is_some_and(|sig| sig.has_self), - None => self.tcx.associated_item(def_id).fn_has_self_parameter, + None => self.tcx.associated_item(def_id).is_method(), }, _ => span_bug!(span, "unexpected DefKind for delegation item"), } diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 8a8ecc3b96e..fe6dff7ff1b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -647,7 +647,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { && tc.polarity() == ty::PredicatePolarity::Positive && supertrait_def_ids(tcx, tc.def_id()) .flat_map(|trait_did| tcx.associated_items(trait_did).in_definition_order()) - .any(|item| item.fn_has_self_parameter) + .any(|item| item.is_method()) }) }) { return None; diff --git a/compiler/rustc_codegen_cranelift/src/main_shim.rs b/compiler/rustc_codegen_cranelift/src/main_shim.rs index 3b48adb7e91..6eef97c14dd 100644 --- a/compiler/rustc_codegen_cranelift/src/main_shim.rs +++ b/compiler/rustc_codegen_cranelift/src/main_shim.rs @@ -1,6 +1,6 @@ use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use rustc_hir::LangItem; -use rustc_middle::ty::{AssocKind, GenericArg}; +use rustc_middle::ty::{AssocTag, GenericArg}; use rustc_session::config::EntryFnType; use rustc_span::{DUMMY_SP, Ident}; @@ -107,7 +107,7 @@ pub(crate) fn maybe_create_entry_wrapper( .find_by_ident_and_kind( tcx, Ident::from_str("report"), - AssocKind::Fn, + AssocTag::Fn, termination_trait, ) .unwrap(); diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index f50746dd18d..c2706a1d401 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -443,7 +443,7 @@ fn best_definition_site_of_opaque<'tcx>( let impl_def_id = tcx.local_parent(parent); for assoc in tcx.associated_items(impl_def_id).in_definition_order() { match assoc.kind { - ty::AssocKind::Const | ty::AssocKind::Fn => { + ty::AssocKind::Const | ty::AssocKind::Fn { .. } => { if let ControlFlow::Break(span) = locator.check(assoc.def_id.expect_local()) { return Some(span); @@ -942,7 +942,7 @@ fn check_impl_items_against_trait<'tcx>( if res.is_ok() { match ty_impl_item.kind { - ty::AssocKind::Fn => { + ty::AssocKind::Fn { .. } => { compare_impl_item::refine::check_refining_return_position_impl_trait_in_trait( tcx, ty_impl_item, diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 29a9931696f..7dfdf1ae237 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -43,7 +43,7 @@ pub(super) fn compare_impl_item( debug!(?impl_trait_ref); match impl_item.kind { - ty::AssocKind::Fn => compare_impl_method(tcx, impl_item, trait_item, impl_trait_ref), + ty::AssocKind::Fn { .. } => compare_impl_method(tcx, impl_item, trait_item, impl_trait_ref), ty::AssocKind::Type => compare_impl_ty(tcx, impl_item, trait_item, impl_trait_ref), ty::AssocKind::Const => compare_impl_const(tcx, impl_item, trait_item, impl_trait_ref), } @@ -1036,7 +1036,7 @@ fn report_trait_method_mismatch<'tcx>( ); match &terr { TypeError::ArgumentMutability(0) | TypeError::ArgumentSorts(_, 0) - if trait_m.fn_has_self_parameter => + if trait_m.is_method() => { let ty = trait_sig.inputs()[0]; let sugg = get_self_string(ty, |ty| ty == impl_trait_ref.self_ty()); @@ -1255,7 +1255,7 @@ fn compare_self_type<'tcx>( get_self_string(self_arg_ty, can_eq_self) }; - match (trait_m.fn_has_self_parameter, impl_m.fn_has_self_parameter) { + match (trait_m.is_method(), impl_m.is_method()) { (false, false) | (true, true) => {} (false, true) => { @@ -1363,7 +1363,7 @@ fn compare_number_of_generics<'tcx>( let mut err_occurred = None; for (kind, trait_count, impl_count) in matchings { if impl_count != trait_count { - let arg_spans = |kind: ty::AssocKind, generics: &hir::Generics<'_>| { + let arg_spans = |item: &ty::AssocItem, generics: &hir::Generics<'_>| { let mut spans = generics .params .iter() @@ -1373,7 +1373,7 @@ fn compare_number_of_generics<'tcx>( } => { // A fn can have an arbitrary number of extra elided lifetimes for the // same signature. - !matches!(kind, ty::AssocKind::Fn) + !item.is_fn() } _ => true, }) @@ -1386,7 +1386,7 @@ fn compare_number_of_generics<'tcx>( }; let (trait_spans, impl_trait_spans) = if let Some(def_id) = trait_.def_id.as_local() { let trait_item = tcx.hir_expect_trait_item(def_id); - let arg_spans: Vec = arg_spans(trait_.kind, trait_item.generics); + let arg_spans: Vec = arg_spans(&trait_, trait_item.generics); let impl_trait_spans: Vec = trait_item .generics .params @@ -1412,7 +1412,7 @@ fn compare_number_of_generics<'tcx>( _ => None, }) .collect(); - let spans = arg_spans(impl_.kind, impl_item.generics); + let spans = arg_spans(&impl_, impl_item.generics); let span = spans.first().copied(); let mut err = tcx.dcx().struct_span_err( diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 30921b6f055..523db9440a4 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -407,14 +407,14 @@ fn fn_sig_suggestion<'tcx>( .enumerate() .map(|(i, ty)| { Some(match ty.kind() { - ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(), + ty::Param(_) if assoc.is_method() && i == 0 => "self".to_string(), ty::Ref(reg, ref_ty, mutability) if i == 0 => { let reg = format!("{reg} "); let reg = match ®[..] { "'_ " | " " => "", reg => reg, }; - if assoc.fn_has_self_parameter { + if assoc.is_method() { match ref_ty.kind() { ty::Param(param) if param.name == kw::SelfUpper => { format!("&{}{}self", reg, mutability.prefix_str()) @@ -427,7 +427,7 @@ fn fn_sig_suggestion<'tcx>( } } _ => { - if assoc.fn_has_self_parameter && i == 0 { + if assoc.is_method() && i == 0 { format!("self: {ty}") } else { format!("_: {ty}") @@ -489,7 +489,7 @@ fn suggestion_signature<'tcx>( ); match assoc.kind { - ty::AssocKind::Fn => fn_sig_suggestion( + ty::AssocKind::Fn { .. } => fn_sig_suggestion( tcx, tcx.liberate_late_bound_regions( assoc.def_id, diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 6292d03bf6a..af7830fd664 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -432,7 +432,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) { let item_required_bounds = match tcx.associated_item(item_def_id).kind { // In our example, this corresponds to `into_iter` method - ty::AssocKind::Fn => { + ty::AssocKind::Fn { .. } => { // For methods, we check the function signature's return type for any GATs // to constrain. In the `into_iter` case, we see that the return type // `Self::Iter<'a>` is a GAT we want to gather any potential missing bounds from. @@ -1089,7 +1089,7 @@ fn check_associated_item( ); Ok(()) } - ty::AssocKind::Fn => { + ty::AssocKind::Fn { .. } => { let sig = tcx.fn_sig(item.def_id).instantiate_identity(); let hir_sig = sig_if_method.expect("bad signature for method"); check_fn_or_method( @@ -1716,7 +1716,7 @@ fn check_method_receiver<'tcx>( ) -> Result<(), ErrorGuaranteed> { let tcx = wfcx.tcx(); - if !method.fn_has_self_parameter { + if !method.is_method() { return Ok(()); } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index deded6904d4..4520fbe352c 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -44,7 +44,7 @@ use rustc_trait_selection::traits::ObligationCtxt; use tracing::{debug, instrument}; use crate::errors; -use crate::hir_ty_lowering::errors::assoc_kind_str; +use crate::hir_ty_lowering::errors::assoc_tag_str; use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer, RegionInferReason}; pub(crate) mod dump; @@ -450,7 +450,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { item_def_id: DefId, item_segment: &rustc_hir::PathSegment<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tcx>, - kind: ty::AssocKind, + assoc_tag: ty::AssocTag, ) -> Result<(DefId, ty::GenericArgsRef<'tcx>), ErrorGuaranteed> { if let Some(trait_ref) = poly_trait_ref.no_bound_vars() { let item_args = self.lowerer().lower_generic_args_of_assoc_item( @@ -525,7 +525,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { inferred_sugg, bound, mpart_sugg, - what: assoc_kind_str(kind), + what: assoc_tag_str(assoc_tag), })) } } diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 9bcda35ee87..1c477755e5a 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -1811,7 +1811,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { self.tcx, type_def_id, constraint.ident, - ty::AssocKind::Fn, + ty::AssocTag::Fn, ) { bound_vars.extend( self.tcx @@ -1843,7 +1843,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { self.tcx, type_def_id, constraint.ident, - ty::AssocKind::Type, + ty::AssocTag::Type, ) .map(|(bound_vars, _)| bound_vars); self.with(scope, |this| { @@ -1875,13 +1875,13 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { tcx: TyCtxt<'tcx>, def_id: DefId, assoc_ident: Ident, - assoc_kind: ty::AssocKind, + assoc_tag: ty::AssocTag, ) -> Option<(Vec, &'tcx ty::AssocItem)> { let trait_defines_associated_item_named = |trait_def_id: DefId| { tcx.associated_items(trait_def_id).find_by_ident_and_kind( tcx, assoc_ident, - assoc_kind, + assoc_tag, trait_def_id, ) }; @@ -1894,8 +1894,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { let Some((def_id, bound_vars)) = stack.pop() else { break None; }; - // See issue #83753. If someone writes an associated type on a non-trait, just treat it as - // there being no supertrait HRTBs. + // See issue #83753. If someone writes an associated type on a non-trait, just treat it + // as there being no supertrait HRTBs. match tcx.def_kind(def_id) { DefKind::Trait | DefKind::TraitAlias | DefKind::Impl { .. } => {} _ => break None, @@ -2067,7 +2067,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { self.tcx, trait_def_id, item_segment.ident, - ty::AssocKind::Fn, + ty::AssocTag::Fn, ) }); @@ -2112,7 +2112,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { self.tcx, trait_def_id, item_segment.ident, - ty::AssocKind::Fn, + ty::AssocTag::Fn, ) else { return; }; diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index 772197a53ac..f0663644719 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -32,7 +32,9 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type( for &assoc_id in tcx.associated_item_def_ids(impl_def_id) { let assoc = tcx.associated_item(assoc_id); match assoc.kind { - ty::AssocKind::Const | ty::AssocKind::Fn => locator.check(assoc_id.expect_local()), + ty::AssocKind::Const | ty::AssocKind::Fn { .. } => { + locator.check(assoc_id.expect_local()) + } // Associated types don't have bodies, so they can't constrain hidden types ty::AssocKind::Type => {} } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index 24d05b49861..bf91eb1b8fd 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -431,16 +431,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ) -> Result<(), ErrorGuaranteed> { let tcx = self.tcx(); - let assoc_kind = if constraint.gen_args.parenthesized + let assoc_tag = if constraint.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation { - ty::AssocKind::Fn + ty::AssocTag::Fn } else if let hir::AssocItemConstraintKind::Equality { term: hir::Term::Const(_) } = constraint.kind { - ty::AssocKind::Const + ty::AssocTag::Const } else { - ty::AssocKind::Type + ty::AssocTag::Type }; // Given something like `U: Trait`, we want to produce a predicate like @@ -453,7 +453,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // trait SuperTrait { type T; } let candidate = if self.probe_trait_that_defines_assoc_item( trait_ref.def_id(), - assoc_kind, + assoc_tag, constraint.ident, ) { // Simple case: The assoc item is defined in the current trait. @@ -464,7 +464,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self.probe_single_bound_for_assoc_item( || traits::supertraits(tcx, trait_ref), AssocItemQSelf::Trait(trait_ref.def_id()), - assoc_kind, + assoc_tag, constraint.ident, path_span, Some(constraint), @@ -474,7 +474,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let assoc_item = self .probe_assoc_item( constraint.ident, - assoc_kind, + assoc_tag, hir_ref_id, constraint.span, candidate.def_id(), @@ -493,7 +493,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }) .or_insert(constraint.span); - let projection_term = if let ty::AssocKind::Fn = assoc_kind { + let projection_term = if let ty::AssocTag::Fn = assoc_tag { let bound_vars = tcx.late_bound_vars(constraint.hir_id); ty::Binder::bind_with_vars( self.lower_return_type_notation_ty(candidate, assoc_item.def_id, path_span)?.into(), @@ -542,7 +542,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }; match constraint.kind { - hir::AssocItemConstraintKind::Equality { .. } if let ty::AssocKind::Fn = assoc_kind => { + hir::AssocItemConstraintKind::Equality { .. } if let ty::AssocTag::Fn = assoc_tag => { return Err(self.dcx().emit_err(crate::errors::ReturnTypeNotationEqualityBound { span: constraint.span, })); @@ -679,7 +679,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { trait_def_id, hir_ty.span, item_segment, - ty::AssocKind::Type, + ty::AssocTag::Type, ); return Ty::new_error(tcx, guar); }; @@ -771,7 +771,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ) }, AssocItemQSelf::SelfTyAlias, - ty::AssocKind::Fn, + ty::AssocTag::Fn, assoc_ident, span, None, @@ -783,7 +783,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ) => self.probe_single_ty_param_bound_for_assoc_item( param_did.expect_local(), qself.span, - ty::AssocKind::Fn, + ty::AssocTag::Fn, assoc_ident, span, )?, @@ -823,7 +823,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let trait_def_id = bound.def_id(); let assoc_ty = self - .probe_assoc_item(assoc_ident, ty::AssocKind::Fn, qpath_hir_id, span, trait_def_id) + .probe_assoc_item(assoc_ident, ty::AssocTag::Fn, qpath_hir_id, span, trait_def_id) .expect("failed to find associated type"); Ok((bound, assoc_ty.def_id)) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 5a0524d33fd..4f8d5471b6f 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -116,7 +116,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { &self, all_candidates: impl Fn() -> I, qself: AssocItemQSelf, - assoc_kind: ty::AssocKind, + assoc_tag: ty::AssocTag, assoc_ident: Ident, span: Span, constraint: Option<&hir::AssocItemConstraint<'tcx>>, @@ -134,14 +134,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }) { return self.complain_about_assoc_kind_mismatch( assoc_item, - assoc_kind, + assoc_tag, assoc_ident, span, constraint, ); } - let assoc_kind_str = assoc_kind_str(assoc_kind); + let assoc_kind_str = assoc_tag_str(assoc_tag); let qself_str = qself.to_string(tcx); // The fallback span is needed because `assoc_name` might be an `Fn()`'s `Output` without a @@ -168,7 +168,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let all_candidate_names: Vec<_> = all_candidates() .flat_map(|r| tcx.associated_items(r.def_id()).in_definition_order()) .filter_map(|item| { - (!item.is_impl_trait_in_trait() && item.kind == assoc_kind).then_some(item.name) + (!item.is_impl_trait_in_trait() && item.as_tag() == assoc_tag).then_some(item.name) }) .collect(); @@ -200,7 +200,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .iter() .flat_map(|trait_def_id| tcx.associated_items(*trait_def_id).in_definition_order()) .filter_map(|item| { - (!item.is_impl_trait_in_trait() && item.kind == assoc_kind).then_some(item.name) + (!item.is_impl_trait_in_trait() && item.as_tag() == assoc_tag).then_some(item.name) }) .collect(); @@ -213,7 +213,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .filter(|trait_def_id| { tcx.associated_items(trait_def_id) .filter_by_name_unhygienic(suggested_name) - .any(|item| item.kind == assoc_kind) + .any(|item| item.as_tag() == assoc_tag) }) .collect::>()[..] { @@ -330,7 +330,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { fn complain_about_assoc_kind_mismatch( &self, assoc_item: &ty::AssocItem, - assoc_kind: ty::AssocKind, + assoc_tag: ty::AssocTag, ident: Ident, span: Span, constraint: Option<&hir::AssocItemConstraint<'tcx>>, @@ -375,17 +375,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir::Term::Ty(ty) => ty.span, hir::Term::Const(ct) => ct.span(), }; - (span, Some(ident.span), assoc_item.kind, assoc_kind) + (span, Some(ident.span), assoc_item.as_tag(), assoc_tag) } else { - (ident.span, None, assoc_kind, assoc_item.kind) + (ident.span, None, assoc_tag, assoc_item.as_tag()) }; self.dcx().emit_err(errors::AssocKindMismatch { span, - expected: assoc_kind_str(expected), - got: assoc_kind_str(got), + expected: assoc_tag_str(expected), + got: assoc_tag_str(got), expected_because_label, - assoc_kind: assoc_kind_str(assoc_item.kind), + assoc_kind: assoc_tag_str(assoc_item.as_tag()), def_span: tcx.def_span(assoc_item.def_id), bound_on_assoc_const_label, wrap_in_braces_sugg, @@ -398,9 +398,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { types: &[String], traits: &[String], name: Symbol, - kind: ty::AssocKind, + assoc_tag: ty::AssocTag, ) -> ErrorGuaranteed { - let kind_str = assoc_kind_str(kind); + let kind_str = assoc_tag_str(assoc_tag); let mut err = struct_span_code_err!(self.dcx(), span, E0223, "ambiguous associated {kind_str}"); if self @@ -569,7 +569,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { candidates: Vec<(DefId, (DefId, DefId))>, fulfillment_errors: Vec>, span: Span, - kind: ty::AssocKind, + assoc_tag: ty::AssocTag, ) -> ErrorGuaranteed { // FIXME(fmease): This was copied in parts from an old version of `rustc_hir_typeck::method::suggest`. // Either @@ -579,14 +579,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let tcx = self.tcx(); - let kind_str = assoc_kind_str(kind); + let assoc_tag_str = assoc_tag_str(assoc_tag); let adt_did = self_ty.ty_adt_def().map(|def| def.did()); let add_def_label = |err: &mut Diag<'_>| { if let Some(did) = adt_did { err.span_label( tcx.def_span(did), format!( - "associated {kind_str} `{name}` not found for this {}", + "associated {assoc_tag_str} `{name}` not found for this {}", tcx.def_descr(did) ), ); @@ -615,11 +615,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self.dcx(), name.span, E0220, - "associated {kind_str} `{name}` not found for `{self_ty}` in the current scope" + "associated {assoc_tag_str} `{name}` not found for `{self_ty}` in the current scope" ); err.span_label(name.span, format!("associated item not found in `{self_ty}`")); err.note(format!( - "the associated {kind_str} was found for\n{type_candidates}{additional_types}", + "the associated {assoc_tag_str} was found for\n{type_candidates}{additional_types}", )); add_def_label(&mut err); return err.emit(); @@ -700,7 +700,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let mut err = self.dcx().struct_span_err( name.span, - format!("the associated {kind_str} `{name}` exists for `{self_ty}`, but its trait bounds were not satisfied") + format!("the associated {assoc_tag_str} `{name}` exists for `{self_ty}`, but its trait bounds were not satisfied") ); if !bounds.is_empty() { err.note(format!( @@ -710,7 +710,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } err.span_label( name.span, - format!("associated {kind_str} cannot be referenced on `{self_ty}` due to unsatisfied trait bounds") + format!("associated {assoc_tag_str} cannot be referenced on `{self_ty}` due to unsatisfied trait bounds") ); for (span, mut bounds) in bound_spans { @@ -812,7 +812,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let assoc_item = tcx.associated_items(trait_def).find_by_ident_and_kind( tcx, ident, - ty::AssocKind::Type, + ty::AssocTag::Type, trait_def, ); @@ -1022,12 +1022,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .map(|simple_ty| tcx.incoherent_impls(simple_ty)) }) && let name = Symbol::intern(&format!("{ident2}_{ident3}")) - && let Some(ty::AssocItem { kind: ty::AssocKind::Fn, .. }) = inherent_impls + && let Some(item) = inherent_impls .iter() .flat_map(|inherent_impl| { tcx.associated_items(inherent_impl).filter_by_name_unhygienic(name) }) .next() + && item.is_fn() { Err(struct_span_code_err!(self.dcx(), span, E0223, "ambiguous associated type") .with_span_suggestion_verbose( @@ -1629,10 +1630,10 @@ fn generics_args_err_extend<'a>( } } -pub(crate) fn assoc_kind_str(kind: ty::AssocKind) -> &'static str { - match kind { - ty::AssocKind::Fn => "function", - ty::AssocKind::Const => "constant", - ty::AssocKind::Type => "type", +pub(crate) fn assoc_tag_str(assoc_tag: ty::AssocTag) -> &'static str { + match assoc_tag { + ty::AssocTag::Fn => "function", + ty::AssocTag::Const => "constant", + ty::AssocTag::Type => "type", } } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 83aa0d95620..0fb406d9908 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -38,8 +38,8 @@ use rustc_middle::middle::stability::AllowUnstable; use rustc_middle::mir::interpret::LitToConstInput; use rustc_middle::ty::print::PrintPolyTraitRefExt as _; use rustc_middle::ty::{ - self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty, TyCtxt, - TypeVisitableExt, TypingMode, Upcast, fold_regions, + self, AssocTag, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty, + TyCtxt, TypeVisitableExt, TypingMode, Upcast, fold_regions, }; use rustc_middle::{bug, span_bug}; use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; @@ -51,7 +51,7 @@ use rustc_trait_selection::traits::wf::object_region_bounds; use rustc_trait_selection::traits::{self, ObligationCtxt}; use tracing::{debug, instrument}; -use self::errors::assoc_kind_str; +use self::errors::assoc_tag_str; use crate::check::check_abi_fn_ptr; use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, NoVariantNamed}; use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint}; @@ -168,7 +168,7 @@ pub trait HirTyLowerer<'tcx> { item_def_id: DefId, item_segment: &hir::PathSegment<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tcx>, - kind: ty::AssocKind, + assoc_tag: ty::AssocTag, ) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed>; fn lower_fn_sig( @@ -251,10 +251,10 @@ enum LowerAssocMode { } impl LowerAssocMode { - fn kind(self) -> ty::AssocKind { + fn assoc_tag(self) -> ty::AssocTag { match self { - LowerAssocMode::Type { .. } => ty::AssocKind::Type, - LowerAssocMode::Const => ty::AssocKind::Const, + LowerAssocMode::Type { .. } => ty::AssocTag::Type, + LowerAssocMode::Const => ty::AssocTag::Const, } } @@ -268,7 +268,8 @@ impl LowerAssocMode { fn permit_variants(self) -> bool { match self { LowerAssocMode::Type { permit_variants } => permit_variants, - // FIXME(mgca): Support paths like `Option::::None` or `Option::::Some` which resolve to const ctors/fn items respectively + // FIXME(mgca): Support paths like `Option::::None` or `Option::::Some` which + // resolve to const ctors/fn items respectively. LowerAssocMode::Const => false, } } @@ -932,12 +933,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { fn probe_trait_that_defines_assoc_item( &self, trait_def_id: DefId, - assoc_kind: ty::AssocKind, + assoc_tag: AssocTag, assoc_ident: Ident, ) -> bool { self.tcx() .associated_items(trait_def_id) - .find_by_ident_and_kind(self.tcx(), assoc_ident, assoc_kind, trait_def_id) + .find_by_ident_and_kind(self.tcx(), assoc_ident, assoc_tag, trait_def_id) .is_some() } @@ -975,7 +976,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { &self, ty_param_def_id: LocalDefId, ty_param_span: Span, - kind: ty::AssocKind, + assoc_tag: AssocTag, assoc_ident: Ident, span: Span, ) -> Result, ErrorGuaranteed> { @@ -993,7 +994,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { traits::transitive_bounds_that_define_assoc_item(tcx, trait_refs, assoc_ident) }, AssocItemQSelf::TyParam(ty_param_def_id, ty_param_span), - kind, + assoc_tag, assoc_ident, span, None, @@ -1010,7 +1011,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { &self, all_candidates: impl Fn() -> I, qself: AssocItemQSelf, - assoc_kind: ty::AssocKind, + assoc_tag: AssocTag, assoc_ident: Ident, span: Span, constraint: Option<&hir::AssocItemConstraint<'tcx>>, @@ -1021,14 +1022,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let tcx = self.tcx(); let mut matching_candidates = all_candidates().filter(|r| { - self.probe_trait_that_defines_assoc_item(r.def_id(), assoc_kind, assoc_ident) + self.probe_trait_that_defines_assoc_item(r.def_id(), assoc_tag, assoc_ident) }); let Some(bound) = matching_candidates.next() else { let reported = self.complain_about_assoc_item_not_found( all_candidates, qself, - assoc_kind, + assoc_tag, assoc_ident, span, constraint, @@ -1040,7 +1041,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if let Some(bound2) = matching_candidates.next() { debug!(?bound2); - let assoc_kind_str = errors::assoc_kind_str(assoc_kind); + let assoc_kind_str = errors::assoc_tag_str(assoc_tag); let qself_str = qself.to_string(tcx); let mut err = self.dcx().create_err(crate::errors::AmbiguousAssocItem { span, @@ -1059,14 +1060,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }, ); - // FIXME(#97583): Print associated item bindings properly (i.e., not as equality predicates!). + // FIXME(#97583): Print associated item bindings properly (i.e., not as equality + // predicates!). // FIXME: Turn this into a structured, translateable & more actionable suggestion. let mut where_bounds = vec![]; for bound in [bound, bound2].into_iter().chain(matching_candidates) { let bound_id = bound.def_id(); let bound_span = tcx .associated_items(bound_id) - .find_by_ident_and_kind(tcx, assoc_ident, assoc_kind, bound_id) + .find_by_ident_and_kind(tcx, assoc_ident, assoc_tag, bound_id) .and_then(|item| tcx.hir_span_if_local(item.def_id)); if let Some(bound_span) = bound_span { @@ -1265,7 +1267,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { qself_ty, hir_ref_id, span, - mode.kind(), + mode.assoc_tag(), )? { return Ok(LoweredAssoc::Term(did, args)); } @@ -1296,7 +1298,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ) }, AssocItemQSelf::SelfTyAlias, - mode.kind(), + mode.assoc_tag(), assoc_ident, span, None, @@ -1308,12 +1310,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ) => self.probe_single_ty_param_bound_for_assoc_item( param_did.expect_local(), qself.span, - mode.kind(), + mode.assoc_tag(), assoc_ident, span, )?, _ => { - let kind_str = assoc_kind_str(mode.kind()); + let kind_str = assoc_tag_str(mode.assoc_tag()); let reported = if variant_resolution.is_some() { // Variant in type position let msg = format!("expected {kind_str}, found variant `{assoc_ident}`"); @@ -1420,7 +1422,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { &[qself_ty.to_string()], &traits, assoc_ident.name, - mode.kind(), + mode.assoc_tag(), ) }; return Err(reported); @@ -1429,10 +1431,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let trait_did = bound.def_id(); let assoc_item = self - .probe_assoc_item(assoc_ident, mode.kind(), hir_ref_id, span, trait_did) + .probe_assoc_item(assoc_ident, mode.assoc_tag(), hir_ref_id, span, trait_did) .expect("failed to find associated item"); - let (def_id, args) = - self.lower_assoc_shared(span, assoc_item.def_id, assoc_segment, bound, mode.kind())?; + let (def_id, args) = self.lower_assoc_shared( + span, + assoc_item.def_id, + assoc_segment, + bound, + mode.assoc_tag(), + )?; let result = LoweredAssoc::Term(def_id, args); if let Some(variant_def_id) = variant_resolution { @@ -1469,20 +1476,21 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self_ty: Ty<'tcx>, block: HirId, span: Span, - kind: ty::AssocKind, + assoc_tag: ty::AssocTag, ) -> Result)>, ErrorGuaranteed> { let tcx = self.tcx(); if !tcx.features().inherent_associated_types() { - match kind { - // Don't attempt to look up inherent associated types when the feature is not enabled. - // Theoretically it'd be fine to do so since we feature-gate their definition site. - // However, due to current limitations of the implementation (caused by us performing - // selection during HIR ty lowering instead of in the trait solver), IATs can lead to cycle - // errors (#108491) which mask the feature-gate error, needlessly confusing users - // who use IATs by accident (#113265). - ty::AssocKind::Type => return Ok(None), - ty::AssocKind::Const => { + match assoc_tag { + // Don't attempt to look up inherent associated types when the feature is not + // enabled. Theoretically it'd be fine to do so since we feature-gate their + // definition site. However, due to current limitations of the implementation + // (caused by us performing selection during HIR ty lowering instead of in the + // trait solver), IATs can lead to cycle errors (#108491) which mask the + // feature-gate error, needlessly confusing users who use IATs by accident + // (#113265). + ty::AssocTag::Type => return Ok(None), + ty::AssocTag::Const => { // We also gate the mgca codepath for type-level uses of inherent consts // with the inherent_associated_types feature gate since it relies on the // same machinery and has similar rough edges. @@ -1494,7 +1502,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ) .emit()); } - ty::AssocKind::Fn => unreachable!(), + ty::AssocTag::Fn => unreachable!(), } } @@ -1503,7 +1511,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .inherent_impls(adt_did) .iter() .filter_map(|&impl_| { - let (item, scope) = self.probe_assoc_item_unchecked(name, kind, block, impl_)?; + let (item, scope) = + self.probe_assoc_item_unchecked(name, assoc_tag, block, impl_)?; Some((impl_, (item.def_id, scope))) }) .collect(); @@ -1542,7 +1551,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self_ty, |self_ty| { self.select_inherent_assoc_candidates( - infcx, name, span, self_ty, param_env, candidates, kind, + infcx, name, span, self_ty, param_env, candidates, assoc_tag, ) }, )?; @@ -1570,7 +1579,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self_ty: Ty<'tcx>, param_env: ParamEnv<'tcx>, candidates: Vec<(DefId, (DefId, DefId))>, - kind: ty::AssocKind, + assoc_tag: ty::AssocTag, ) -> Result<(DefId, (DefId, DefId)), ErrorGuaranteed> { let tcx = self.tcx(); let mut fulfillment_errors = Vec::new(); @@ -1621,7 +1630,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { candidates, fulfillment_errors, span, - kind, + assoc_tag, )), &[applicable_candidate] => Ok(applicable_candidate), @@ -1640,12 +1649,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { fn probe_assoc_item( &self, ident: Ident, - kind: ty::AssocKind, + assoc_tag: ty::AssocTag, block: HirId, span: Span, scope: DefId, ) -> Option { - let (item, scope) = self.probe_assoc_item_unchecked(ident, kind, block, scope)?; + let (item, scope) = self.probe_assoc_item_unchecked(ident, assoc_tag, block, scope)?; self.check_assoc_item(item.def_id, ident, scope, block, span); Some(item) } @@ -1657,7 +1666,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { fn probe_assoc_item_unchecked( &self, ident: Ident, - kind: ty::AssocKind, + assoc_tag: ty::AssocTag, block: HirId, scope: DefId, ) -> Option<(ty::AssocItem, /*scope*/ DefId)> { @@ -1670,7 +1679,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let item = tcx .associated_items(scope) .filter_by_name_unhygienic(ident.name) - .find(|i| i.kind == kind && i.ident(tcx).normalize_to_macros_2_0() == ident)?; + .find(|i| i.as_tag() == assoc_tag && i.ident(tcx).normalize_to_macros_2_0() == ident)?; Some((*item, def_scope)) } @@ -1770,7 +1779,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { item_def_id, trait_segment, item_segment, - ty::AssocKind::Type, + ty::AssocTag::Type, ) { Ok((item_def_id, item_args)) => { Ty::new_projection_from_args(self.tcx(), item_def_id, item_args) @@ -1795,7 +1804,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { item_def_id, trait_segment, item_segment, - ty::AssocKind::Const, + ty::AssocTag::Const, ) { Ok((item_def_id, item_args)) => { let uv = ty::UnevaluatedConst::new(item_def_id, item_args); @@ -1813,7 +1822,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { item_def_id: DefId, trait_segment: &hir::PathSegment<'tcx>, item_segment: &hir::PathSegment<'tcx>, - kind: ty::AssocKind, + assoc_tag: ty::AssocTag, ) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed> { let tcx = self.tcx(); @@ -1821,7 +1830,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { debug!(?trait_def_id); let Some(self_ty) = opt_self_ty else { - return Err(self.error_missing_qpath_self_ty(trait_def_id, span, item_segment, kind)); + return Err(self.error_missing_qpath_self_ty( + trait_def_id, + span, + item_segment, + assoc_tag, + )); }; debug!(?self_ty); @@ -1840,7 +1854,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { trait_def_id: DefId, span: Span, item_segment: &hir::PathSegment<'tcx>, - kind: ty::AssocKind, + assoc_tag: ty::AssocTag, ) -> ErrorGuaranteed { let tcx = self.tcx(); let path_str = tcx.def_path_str(trait_def_id); @@ -1877,7 +1891,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // FIXME: also look at `tcx.generics_of(self.item_def_id()).params` any that // references the trait. Relevant for the first case in // `src/test/ui/associated-types/associated-types-in-ambiguous-context.rs` - self.report_ambiguous_assoc(span, &type_names, &[path_str], item_segment.ident.name, kind) + self.report_ambiguous_assoc( + span, + &type_names, + &[path_str], + item_segment.ident.name, + assoc_tag, + ) } pub fn prohibit_generic_args<'a>( @@ -2862,7 +2882,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let assoc = tcx.associated_items(trait_ref.def_id).find_by_ident_and_kind( tcx, *ident, - ty::AssocKind::Fn, + ty::AssocTag::Fn, trait_ref.def_id, )?; diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index c30b39dfe76..1ab36ce1dcb 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -119,7 +119,7 @@ pub(crate) fn enforce_impl_lifetime_params_are_constrained( vec![] } } - ty::AssocKind::Fn | ty::AssocKind::Const => vec![], + ty::AssocKind::Fn { .. } | ty::AssocKind::Const => vec![], } }) .collect(); diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index fec45995410..d1bc54ed73e 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -1089,14 +1089,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// This function checks whether the method is not static and does not accept other parameters than `self`. fn has_only_self_parameter(&self, method: &AssocItem) -> bool { - match method.kind { - ty::AssocKind::Fn => { - method.fn_has_self_parameter - && self.tcx.fn_sig(method.def_id).skip_binder().inputs().skip_binder().len() - == 1 - } - _ => false, - } + method.is_method() + && self.tcx.fn_sig(method.def_id).skip_binder().inputs().skip_binder().len() == 1 } /// If the given `HirId` corresponds to a block with a trailing expression, return that expression diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index de2f039cb1c..56c205b6f87 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2588,9 +2588,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .into_iter() .flat_map(|i| self.tcx.associated_items(i).in_definition_order()) // Only assoc fn with no receivers. - .filter(|item| { - matches!(item.kind, ty::AssocKind::Fn) && !item.fn_has_self_parameter - }) + .filter(|item| item.is_fn() && !item.is_method()) .filter_map(|item| { // Only assoc fns that return `Self` let fn_sig = self.tcx.fn_sig(item.def_id).skip_binder(); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 81eb8510785..3a0f3a4a5f0 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -616,7 +616,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some((DefKind::AssocFn, def_id)) = self.typeck_results.borrow().type_dependent_def(call_expr.hir_id) && let Some(assoc) = tcx.opt_associated_item(def_id) - && assoc.fn_has_self_parameter + && assoc.is_method() { Some(*receiver) } else { @@ -642,8 +642,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { TraitsInScope, |mut ctxt| ctxt.probe_for_similar_candidate(), ) - && let ty::AssocKind::Fn = assoc.kind - && assoc.fn_has_self_parameter + && assoc.is_method() { let args = self.infcx.fresh_args_for_item(call_name.span, assoc.def_id); let fn_sig = tcx.fn_sig(assoc.def_id).instantiate(tcx, args); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index e14f1528d2c..74cc8181418 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -314,7 +314,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { item_def_id: DefId, item_segment: &rustc_hir::PathSegment<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tcx>, - _kind: ty::AssocKind, + _assoc_tag: ty::AssocTag, ) -> Result<(DefId, ty::GenericArgsRef<'tcx>), ErrorGuaranteed> { let trait_ref = self.instantiate_binder_with_fresh_vars( span, diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index ddfd27ccf6b..39cb139a199 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -379,7 +379,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let def_id = method_item.def_id; - if method_item.kind != ty::AssocKind::Fn { + if !method_item.is_fn() { span_bug!(tcx.def_span(def_id), "expected `{m_name}` to be an associated function"); } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 0a01ec89a32..d5d85c812b2 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -992,7 +992,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { fn matches_return_type(&self, method: ty::AssocItem, expected: Ty<'tcx>) -> bool { match method.kind { - ty::AssocKind::Fn => self.probe(|_| { + ty::AssocKind::Fn { .. } => self.probe(|_| { let args = self.fresh_args_for_item(self.span, method.def_id); let fty = self.tcx.fn_sig(method.def_id).instantiate(self.tcx, args); let fty = self.instantiate_binder_with_fresh_vars(self.span, infer::FnCall, fty); @@ -1678,7 +1678,6 @@ impl<'tcx> Pick<'tcx> { kind: _, container: _, trait_item_def_id: _, - fn_has_self_parameter: _, opt_rpitit_info: _, }, kind: _, @@ -1712,7 +1711,7 @@ impl<'tcx> Pick<'tcx> { )); match (self.item.kind, self.item.container) { - (ty::AssocKind::Fn, _) => { + (ty::AssocKind::Fn { .. }, _) => { // FIXME: This should be a `span_suggestion` instead of `help` // However `self.span` only // highlights the method name, so we can't use it. Also consider reusing @@ -2252,10 +2251,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // In Path mode (i.e., resolving a value like `T::next`), consider any // associated value (i.e., methods, constants) but not types. match self.mode { - Mode::MethodCall => item.fn_has_self_parameter, + Mode::MethodCall => item.is_method(), Mode::Path => match item.kind { ty::AssocKind::Type => false, - ty::AssocKind::Fn | ty::AssocKind::Const => true, + ty::AssocKind::Fn { .. } | ty::AssocKind::Const => true, }, } // FIXME -- check for types that deref to `Self`, @@ -2277,7 +2276,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { impl_ty: Ty<'tcx>, args: GenericArgsRef<'tcx>, ) -> (Ty<'tcx>, Option>) { - if item.kind == ty::AssocKind::Fn && self.mode == Mode::MethodCall { + if item.is_fn() && self.mode == Mode::MethodCall { let sig = self.xform_method_sig(item.def_id, args); (sig.inputs()[0], Some(sig.output())) } else { @@ -2328,8 +2327,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { /// Determine if the given associated item type is relevant in the current context. fn is_relevant_kind_for_mode(&self, kind: ty::AssocKind) -> bool { match (self.mode, kind) { - (Mode::MethodCall, ty::AssocKind::Fn) => true, - (Mode::Path, ty::AssocKind::Const | ty::AssocKind::Fn) => true, + (Mode::MethodCall, ty::AssocKind::Fn { .. }) => true, + (Mode::Path, ty::AssocKind::Const | ty::AssocKind::Fn { .. }) => true, _ => false, } } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 68f13d654d6..1b9771636a7 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -713,7 +713,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let Some(candidate) = tcx.associated_items(impl_def_id).find_by_ident_and_kind( self.tcx, item_ident, - ty::AssocKind::Type, + ty::AssocTag::Type, impl_def_id, ) && let Some(adt_def) = tcx.type_of(candidate.def_id).skip_binder().ty_adt_def() @@ -1442,7 +1442,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(assoc) = self.associated_value(*def_id, item_ident) { // Check for both mode is the same so we avoid suggesting // incorrect associated item. - match (mode, assoc.fn_has_self_parameter, source) { + match (mode, assoc.is_method(), source) { (Mode::MethodCall, true, SelfSource::MethodCall(_)) => { // We check that the suggest type is actually // different from the received one @@ -1834,7 +1834,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty_args = self.infcx.fresh_args_for_item(span, similar_candidate.def_id); let fn_sig = tcx.fn_sig(similar_candidate.def_id).instantiate(tcx, ty_args); let fn_sig = self.instantiate_binder_with_fresh_vars(span, infer::FnCall, fn_sig); - if similar_candidate.fn_has_self_parameter { + if similar_candidate.is_method() { if let Some(args) = args && fn_sig.inputs()[1..].len() == args.len() { @@ -1902,7 +1902,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { if let Some(candidates) = find_attr!(self.tcx.get_all_attrs(inherent_method.def_id), AttributeKind::Confusables{symbols, ..} => symbols) && candidates.contains(&item_name.name) - && let ty::AssocKind::Fn = inherent_method.kind + && inherent_method.is_fn() { let args = ty::GenericArgs::identity_for_item(self.tcx, inherent_method.def_id) @@ -2116,8 +2116,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Only assoc fn with no receivers and only if // they are resolvable .filter(|item| { - matches!(item.kind, ty::AssocKind::Fn) - && !item.fn_has_self_parameter + matches!(item.kind, ty::AssocKind::Fn { has_self: false }) && self .probe_for_name( Mode::Path, @@ -2261,7 +2260,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let assoc = self.associated_value(assoc_did, item_name)?; - if assoc.kind != ty::AssocKind::Fn { + if !assoc.is_fn() { return None; } @@ -3208,7 +3207,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If this method receives `&self`, then the provided // argument _should_ coerce, so it's valid to suggest // just changing the path. - && pick.item.fn_has_self_parameter + && pick.item.is_method() && let Some(self_ty) = self.tcx.fn_sig(pick.item.def_id).instantiate_identity().inputs().skip_binder().get(0) && self_ty.is_ref() @@ -3560,7 +3559,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { || (("Pin::new" == *pre) && ((sym::as_ref == item_name.name) || !unpin)) || inputs_len.is_some_and(|inputs_len| { - pick.item.kind == ty::AssocKind::Fn + pick.item.is_fn() && self .tcx .fn_sig(pick.item.def_id) @@ -3618,7 +3617,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && pick.autoderefs == 0 // Check that the method of the same name that was found on the new `Pin` // receiver has the same number of arguments that appear in the user's code. - && inputs_len.is_some_and(|inputs_len| pick.item.kind == ty::AssocKind::Fn && self.tcx.fn_sig(pick.item.def_id).skip_binder().skip_binder().inputs().len() == inputs_len) + && inputs_len.is_some_and(|inputs_len| pick.item.is_fn() && self.tcx.fn_sig(pick.item.def_id).skip_binder().skip_binder().inputs().len() == inputs_len) { let indent = self .tcx @@ -3756,7 +3755,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && self .associated_value(info.def_id, item_name) .filter(|item| { - if let ty::AssocKind::Fn = item.kind { + if item.is_fn() { let id = item .def_id .as_local() @@ -4279,13 +4278,13 @@ fn print_disambiguation_help<'tcx>( item: ty::AssocItem, ) -> Option { let trait_impl_type = trait_ref.self_ty().peel_refs(); - let trait_ref = if item.fn_has_self_parameter { + let trait_ref = if item.is_method() { trait_ref.print_only_trait_name().to_string() } else { format!("<{} as {}>", trait_ref.args[0], trait_ref.print_only_trait_name()) }; Some( - if matches!(item.kind, ty::AssocKind::Fn) + if item.is_fn() && let SelfSource::MethodCall(receiver) = source && let Some(args) = args { @@ -4304,7 +4303,7 @@ fn print_disambiguation_help<'tcx>( let args = if let Some(first_arg_type) = first_arg_type && (first_arg_type == tcx.types.self_param || first_arg_type == trait_impl_type - || item.fn_has_self_parameter) + || item.is_method()) { Some(receiver) } else { diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index a2d5ffe256d..dd3c514704a 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -859,12 +859,7 @@ impl<'tcx> LateContext<'tcx> { ) -> Option> { let tcx = self.tcx; tcx.associated_items(trait_id) - .find_by_ident_and_kind( - tcx, - Ident::with_dummy_span(name), - ty::AssocKind::Type, - trait_id, - ) + .find_by_ident_and_kind(tcx, Ident::with_dummy_span(name), ty::AssocTag::Type, trait_id) .and_then(|assoc| { let proj = Ty::new_projection(tcx, assoc.def_id, [self_ty]); tcx.try_normalize_erasing_regions(self.typing_env(), proj).ok() diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 4cc12ca2e0b..cc3b2a241e4 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1337,10 +1337,12 @@ impl<'a> CrateMetadataRef<'a> { } else { self.item_name(id) }; - let (kind, has_self) = match self.def_kind(id) { - DefKind::AssocConst => (ty::AssocKind::Const, false), - DefKind::AssocFn => (ty::AssocKind::Fn, self.get_fn_has_self_parameter(id, sess)), - DefKind::AssocTy => (ty::AssocKind::Type, false), + let kind = match self.def_kind(id) { + DefKind::AssocConst => ty::AssocKind::Const, + DefKind::AssocFn => { + ty::AssocKind::Fn { has_self: self.get_fn_has_self_parameter(id, sess) } + } + DefKind::AssocTy => ty::AssocKind::Type, _ => bug!("cannot get associated-item of `{:?}`", self.def_key(id)), }; let container = self.root.tables.assoc_container.get(self, id).unwrap(); @@ -1353,7 +1355,6 @@ impl<'a> CrateMetadataRef<'a> { def_id: self.local_def_id(id), trait_item_def_id: self.get_trait_item_def_id(id), container, - fn_has_self_parameter: has_self, opt_rpitit_info, } } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 5c8e2888ec9..cc9da16ffdb 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1338,7 +1338,7 @@ fn should_encode_const(def_kind: DefKind) -> bool { fn should_encode_fn_impl_trait_in_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { if let Some(assoc_item) = tcx.opt_associated_item(def_id) && assoc_item.container == ty::AssocItemContainer::Trait - && assoc_item.kind == ty::AssocKind::Fn + && assoc_item.is_fn() { true } else { diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 4dfb362f3a2..db19c858e7c 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1636,8 +1636,8 @@ pub fn find_self_call<'tcx>( &body[block].terminator && let Operand::Constant(box ConstOperand { const_, .. }) = func && let ty::FnDef(def_id, fn_args) = *const_.ty().kind() - && let Some(ty::AssocItem { fn_has_self_parameter: true, .. }) = - tcx.opt_associated_item(def_id) + && let Some(item) = tcx.opt_associated_item(def_id) + && item.is_method() && let [Spanned { node: Operand::Move(self_place) | Operand::Copy(self_place), .. }, ..] = **args { diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index f8ab555305f..3425da48559 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -5,7 +5,7 @@ use rustc_hir::lang_items::LangItem; use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_span::Span; -use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::{Ty, TyCtxt}; #[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)] pub enum PointerCoercion { @@ -133,7 +133,7 @@ impl OverloadedDeref { }; tcx.associated_items(trait_def_id) .in_definition_order() - .find(|m| m.kind == ty::AssocKind::Fn) + .find(|item| item.is_fn()) .unwrap() .def_id } diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index bbaf735fbdb..3c1e5ed9e11 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -26,10 +26,6 @@ pub struct AssocItem { /// the associated item on the trait that this implements. pub trait_item_def_id: Option, - /// Whether this is a method with an explicit self - /// as its first parameter, allowing method calls. - pub fn_has_self_parameter: bool, - /// `Some` if the associated item (an associated type) comes from the /// return-position `impl Trait` in trait desugaring. The `ImplTraitInTraitData` /// provides additional information about its source. @@ -78,7 +74,7 @@ impl AssocItem { pub fn signature(&self, tcx: TyCtxt<'_>) -> String { match self.kind { - ty::AssocKind::Fn => { + ty::AssocKind::Fn { .. } => { // We skip the binder here because the binder would deanonymize all // late-bound regions, and we don't want method signatures to show up // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound @@ -99,12 +95,28 @@ impl AssocItem { pub fn descr(&self) -> &'static str { match self.kind { ty::AssocKind::Const => "associated const", - ty::AssocKind::Fn if self.fn_has_self_parameter => "method", - ty::AssocKind::Fn => "associated function", + ty::AssocKind::Fn { has_self: true } => "method", + ty::AssocKind::Fn { has_self: false } => "associated function", ty::AssocKind::Type => "associated type", } } + pub fn is_fn(&self) -> bool { + matches!(self.kind, ty::AssocKind::Fn { .. }) + } + + pub fn is_method(&self) -> bool { + matches!(self.kind, ty::AssocKind::Fn { has_self: true }) + } + + pub fn as_tag(&self) -> AssocTag { + match self.kind { + AssocKind::Const => AssocTag::Const, + AssocKind::Fn { .. } => AssocTag::Fn, + AssocKind::Type => AssocTag::Type, + } + } + pub fn is_impl_trait_in_trait(&self) -> bool { self.opt_rpitit_info.is_some() } @@ -131,7 +143,7 @@ impl AssocItem { #[derive(Copy, Clone, PartialEq, Debug, HashStable, Eq, Hash, Encodable, Decodable)] pub enum AssocKind { Const, - Fn, + Fn { has_self: bool }, Type, } @@ -139,14 +151,14 @@ impl AssocKind { pub fn namespace(&self) -> Namespace { match *self { ty::AssocKind::Type => Namespace::TypeNS, - ty::AssocKind::Const | ty::AssocKind::Fn => Namespace::ValueNS, + ty::AssocKind::Const | ty::AssocKind::Fn { .. } => Namespace::ValueNS, } } pub fn as_def_kind(&self) -> DefKind { match self { AssocKind::Const => DefKind::AssocConst, - AssocKind::Fn => DefKind::AssocFn, + AssocKind::Fn { .. } => DefKind::AssocFn, AssocKind::Type => DefKind::AssocTy, } } @@ -155,15 +167,22 @@ impl AssocKind { impl std::fmt::Display for AssocKind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - // FIXME: fails to distinguish between "associated function" and - // "method" because `has_self` isn't known here. - AssocKind::Fn => write!(f, "method"), + AssocKind::Fn { has_self: true } => write!(f, "method"), + AssocKind::Fn { has_self: false } => write!(f, "associated function"), AssocKind::Const => write!(f, "associated const"), AssocKind::Type => write!(f, "associated type"), } } } +// Like `AssocKind`, but just the tag, no fields. Used in various kinds of matching. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum AssocTag { + Const, + Fn, + Type, +} + /// A list of `ty::AssocItem`s in definition order that allows for efficient lookup by name. /// /// When doing lookup by name, we try to postpone hygienic comparison for as long as possible since @@ -207,27 +226,14 @@ impl AssocItems { &self, tcx: TyCtxt<'_>, ident: Ident, - kind: AssocKind, + assoc_tag: AssocTag, parent_def_id: DefId, ) -> Option<&ty::AssocItem> { self.filter_by_name_unhygienic(ident.name) - .filter(|item| item.kind == kind) + .filter(|item| item.as_tag() == assoc_tag) .find(|item| tcx.hygienic_eq(ident, item.ident(tcx), parent_def_id)) } - /// Returns the associated item with the given identifier and any of `AssocKind`, if one - /// exists. The identifier is matched hygienically. - pub fn find_by_ident_and_kinds( - &self, - tcx: TyCtxt<'_>, - ident: Ident, - // Sorted in order of what kinds to look at - kinds: &[AssocKind], - parent_def_id: DefId, - ) -> Option<&ty::AssocItem> { - kinds.iter().find_map(|kind| self.find_by_ident_and_kind(tcx, ident, *kind, parent_def_id)) - } - /// Returns the associated item with the given identifier in the given `Namespace`, if one /// exists. The identifier is matched hygienically. pub fn find_by_ident_and_namespace( diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 07f2a602f2b..faad0a82acb 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -746,7 +746,7 @@ impl<'tcx> Instance<'tcx> { let call_once = tcx .associated_items(fn_once) .in_definition_order() - .find(|it| it.kind == ty::AssocKind::Fn) + .find(|it| it.is_fn()) .unwrap() .def_id; let track_caller = diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index a2b3acac3f2..30c889c39d9 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1464,7 +1464,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn provided_trait_methods(self, id: DefId) -> impl 'tcx + Iterator { self.associated_items(id) .in_definition_order() - .filter(move |item| item.kind == AssocKind::Fn && item.defaultness(self).has_value()) + .filter(move |item| item.is_fn() && item.defaultness(self).has_value()) } pub fn repr_options_of_def(self, did: LocalDefId) -> ReprOptions { diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 857b462b9eb..dfc11de283d 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -819,7 +819,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Get an English description for the item's kind. pub fn def_kind_descr(self, def_kind: DefKind, def_id: DefId) -> &'static str { match def_kind { - DefKind::AssocFn if self.associated_item(def_id).fn_has_self_parameter => "method", + DefKind::AssocFn if self.associated_item(def_id).is_method() => "method", DefKind::Closure if let Some(coroutine_kind) = self.coroutine_kind(def_id) => { match coroutine_kind { hir::CoroutineKind::Desugared( @@ -873,7 +873,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Gets an English article for the [`TyCtxt::def_kind_descr`]. pub fn def_kind_descr_article(self, def_kind: DefKind, def_id: DefId) -> &'static str { match def_kind { - DefKind::AssocFn if self.associated_item(def_id).fn_has_self_parameter => "a", + DefKind::AssocFn if self.associated_item(def_id).is_method() => "a", DefKind::Closure if let Some(coroutine_kind) = self.coroutine_kind(def_id) => { match coroutine_kind { hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, ..) => "an", diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index d1f9d4c34fe..16da6092998 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -715,7 +715,7 @@ fn trait_method<'tcx>( let item = tcx .associated_items(trait_def_id) .filter_by_name_unhygienic(method_name) - .find(|item| item.kind == ty::AssocKind::Fn) + .find(|item| item.is_fn()) .expect("trait method not found"); let method_ty = Ty::new_fn_def(tcx, item.def_id, args); diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index c9771467e49..c13ffae3649 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -66,7 +66,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< let call_mut = tcx .associated_items(fn_mut) .in_definition_order() - .find(|it| it.kind == ty::AssocKind::Fn) + .find(|it| it.is_fn()) .unwrap() .def_id; diff --git a/compiler/rustc_monomorphize/src/mono_checks/move_check.rs b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs index 55d52d5075d..7251ef478c6 100644 --- a/compiler/rustc_monomorphize/src/mono_checks/move_check.rs +++ b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs @@ -3,7 +3,7 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_hir::def_id::DefId; use rustc_middle::mir::visit::Visitor as MirVisitor; use rustc_middle::mir::{self, Location, traversal}; -use rustc_middle::ty::{self, AssocKind, Instance, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, AssocTag, Instance, Ty, TyCtxt, TypeFoldable}; use rustc_session::Limit; use rustc_session::lint::builtin::LARGE_ASSIGNMENTS; use rustc_span::source_map::Spanned; @@ -194,7 +194,7 @@ fn assoc_fn_of_type<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fn_ident: Ident) -> if let Some(new) = tcx.associated_items(impl_def_id).find_by_ident_and_kind( tcx, fn_ident, - AssocKind::Fn, + AssocTag::Fn, def_id, ) { return Some(new.def_id); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index c2761bd2717..ae81021e0be 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1994,7 +1994,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { .iter() .flat_map(|i| self.r.tcx.associated_items(i).in_definition_order()) // Only assoc fn with no receivers. - .filter(|item| matches!(item.kind, ty::AssocKind::Fn) && !item.fn_has_self_parameter) + .filter(|item| item.is_fn() && !item.is_method()) .filter_map(|item| { // Only assoc fns that return `Self` let fn_sig = self.r.tcx.fn_sig(item.def_id).skip_binder(); diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index 129a32c6edd..718b9a4fa3b 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -446,7 +446,7 @@ pub(crate) fn transform_instance<'tcx>( let call = tcx .associated_items(trait_id) .in_definition_order() - .find(|it| it.kind == ty::AssocKind::Fn) + .find(|it| it.is_fn()) .expect("No call-family function on closure-like Fn trait?") .def_id; diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index 28fc68d5e49..94f3be9fef7 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -896,9 +896,9 @@ impl<'tcx> Stable<'tcx> for ty::AssocKind { fn stable(&self, _tables: &mut Tables<'_>) -> Self::T { use stable_mir::ty::AssocKind; - match self { + match *self { ty::AssocKind::Const => AssocKind::Const, - ty::AssocKind::Fn => AssocKind::Fn, + ty::AssocKind::Fn { has_self } => AssocKind::Fn { has_self }, ty::AssocKind::Type => AssocKind::Type, } } @@ -926,7 +926,6 @@ impl<'tcx> Stable<'tcx> for ty::AssocItem { kind: self.kind.stable(tables), container: self.container.stable(tables), trait_item_def_id: self.trait_item_def_id.map(|did| tables.assoc_def(did)), - fn_has_self_parameter: self.fn_has_self_parameter, opt_rpitit_info: self.opt_rpitit_info.map(|rpitit| rpitit.stable(tables)), } } diff --git a/compiler/rustc_smir/src/stable_mir/mir/pretty.rs b/compiler/rustc_smir/src/stable_mir/mir/pretty.rs index 439ebe978e5..60d9e122940 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/pretty.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/pretty.rs @@ -22,7 +22,8 @@ impl Display for Ty { impl Display for AssocKind { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { - AssocKind::Fn => write!(f, "method"), + AssocKind::Fn { has_self: true } => write!(f, "method"), + AssocKind::Fn { has_self: false } => write!(f, "associated function"), AssocKind::Const => write!(f, "associated const"), AssocKind::Type => write!(f, "associated type"), } diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs index 3fcbbb0e138..63ce756162a 100644 --- a/compiler/rustc_smir/src/stable_mir/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/ty.rs @@ -1586,10 +1586,6 @@ pub struct AssocItem { /// the associated item on the trait that this implements. pub trait_item_def_id: Option, - /// Whether this is a method with an explicit self - /// as its first parameter, allowing method calls. - pub fn_has_self_parameter: bool, - /// `Some` if the associated item (an associated type) comes from the /// return-position `impl Trait` in trait desugaring. The `ImplTraitInTraitData` /// provides additional information about its source. @@ -1599,7 +1595,7 @@ pub struct AssocItem { #[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum AssocKind { Const, - Fn, + Fn { has_self: bool }, Type, } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 40f8af1f691..cbadb46c17d 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -2334,7 +2334,7 @@ impl<'tcx> ObligationCause<'tcx> { subdiags: Vec, ) -> ObligationCauseFailureCode { match self.code() { - ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Fn, .. } => { + ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Fn { .. }, .. } => { ObligationCauseFailureCode::MethodCompat { span, subdiags } } ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Type, .. } => { @@ -2398,7 +2398,7 @@ impl<'tcx> ObligationCause<'tcx> { fn as_requirement_str(&self) -> &'static str { match self.code() { - ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Fn, .. } => { + ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Fn { .. }, .. } => { "method type is compatible with trait" } ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Type, .. } => { @@ -2422,7 +2422,9 @@ pub struct ObligationCauseAsDiagArg<'tcx>(pub ObligationCause<'tcx>); impl IntoDiagArg for ObligationCauseAsDiagArg<'_> { fn into_diag_arg(self, _: &mut Option) -> rustc_errors::DiagArgValue { let kind = match self.0.code() { - ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Fn, .. } => "method_compat", + ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Fn { .. }, .. } => { + "method_compat" + } ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Type, .. } => "type_compat", ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Const, .. } => { "const_compat" diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs index 74205922851..b66bd2c6ab7 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs @@ -98,7 +98,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let assoc_item = self.tcx().associated_item(trait_item_def_id); let mut visitor = TypeParamSpanVisitor { tcx: self.tcx(), types: vec![] }; match assoc_item.kind { - ty::AssocKind::Fn => { + ty::AssocKind::Fn { .. } => { if let Some(hir_id) = assoc_item.def_id.as_local().map(|id| self.tcx().local_def_id_to_hir_id(id)) { diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs index fd2d2fa7210..4a71ab4e06a 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs @@ -158,6 +158,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { && self .tcx() .opt_associated_item(scope_def_id.to_def_id()) - .is_some_and(|i| i.fn_has_self_parameter) + .is_some_and(|i| i.is_method()) } } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs index 5583deda99a..02f21b5465c 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs @@ -782,7 +782,7 @@ fn foo(&self) -> Self::T { String::new() } let methods: Vec<(Span, String)> = items .in_definition_order() .filter(|item| { - ty::AssocKind::Fn == item.kind + item.is_fn() && Some(item.name) != current_method_ident && !tcx.is_doc_hidden(item.def_id) }) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index 59c93db9c8f..e3e1583a48f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -349,7 +349,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { { let (verb, noun) = match self.tcx.associated_item(item_id).kind { ty::AssocKind::Const => ("refer to the", "constant"), - ty::AssocKind::Fn => ("call", "function"), + ty::AssocKind::Fn { .. } => ("call", "function"), // This is already covered by E0223, but this following single match // arm doesn't hurt here. ty::AssocKind::Type => ("refer to the", "type"), diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index b963e4a2c7c..38aac8e70b5 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -5411,7 +5411,7 @@ fn point_at_assoc_type_restriction( tcx.associated_items(data.impl_or_alias_def_id).find_by_ident_and_kind( tcx, Ident::with_dummy_span(name), - ty::AssocKind::Type, + ty::AssocTag::Type, data.impl_or_alias_def_id, ) { diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index bf9fcb0915a..76892db9ef7 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -301,7 +301,7 @@ pub fn dyn_compatibility_violations_for_assoc_item( ty::AssocKind::Const => { vec![DynCompatibilityViolation::AssocConst(item.name, item.ident(tcx).span)] } - ty::AssocKind::Fn => virtual_call_violations_for_method(tcx, trait_def_id, item) + ty::AssocKind::Fn { .. } => virtual_call_violations_for_method(tcx, trait_def_id, item) .into_iter() .map(|v| { let node = tcx.hir_get_if_local(item.def_id); @@ -344,7 +344,7 @@ fn virtual_call_violations_for_method<'tcx>( let sig = tcx.fn_sig(method.def_id).instantiate_identity(); // The method's first parameter must be named `self` - if !method.fn_has_self_parameter { + if !method.is_method() { let sugg = if let Some(hir::Node::TraitItem(hir::TraitItem { generics, kind: hir::TraitItemKind::Fn(sig, _), diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index 165174c0bcc..3565c11249a 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -197,10 +197,8 @@ fn own_existential_vtable_entries_iter( tcx: TyCtxt<'_>, trait_def_id: DefId, ) -> impl Iterator { - let trait_methods = tcx - .associated_items(trait_def_id) - .in_definition_order() - .filter(|item| item.kind == ty::AssocKind::Fn); + let trait_methods = + tcx.associated_items(trait_def_id).in_definition_order().filter(|item| item.is_fn()); // Now list each method's DefId (for within its trait). let own_entries = trait_methods.filter_map(move |&trait_method| { diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 9520d948f51..79de071b687 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -129,10 +129,10 @@ fn associated_item(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AssocItem { fn associated_item_from_trait_item_ref(trait_item_ref: &hir::TraitItemRef) -> ty::AssocItem { let owner_id = trait_item_ref.id.owner_id; - let (kind, has_self) = match trait_item_ref.kind { - hir::AssocItemKind::Const => (ty::AssocKind::Const, false), - hir::AssocItemKind::Fn { has_self } => (ty::AssocKind::Fn, has_self), - hir::AssocItemKind::Type => (ty::AssocKind::Type, false), + let kind = match trait_item_ref.kind { + hir::AssocItemKind::Const => ty::AssocKind::Const, + hir::AssocItemKind::Fn { has_self } => ty::AssocKind::Fn { has_self }, + hir::AssocItemKind::Type => ty::AssocKind::Type, }; ty::AssocItem { @@ -141,17 +141,16 @@ fn associated_item_from_trait_item_ref(trait_item_ref: &hir::TraitItemRef) -> ty def_id: owner_id.to_def_id(), trait_item_def_id: Some(owner_id.to_def_id()), container: ty::AssocItemContainer::Trait, - fn_has_self_parameter: has_self, opt_rpitit_info: None, } } fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::AssocItem { let def_id = impl_item_ref.id.owner_id; - let (kind, has_self) = match impl_item_ref.kind { - hir::AssocItemKind::Const => (ty::AssocKind::Const, false), - hir::AssocItemKind::Fn { has_self } => (ty::AssocKind::Fn, has_self), - hir::AssocItemKind::Type => (ty::AssocKind::Type, false), + let kind = match impl_item_ref.kind { + hir::AssocItemKind::Const => ty::AssocKind::Const, + hir::AssocItemKind::Fn { has_self } => ty::AssocKind::Fn { has_self }, + hir::AssocItemKind::Type => ty::AssocKind::Type, }; ty::AssocItem { @@ -160,7 +159,6 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A def_id: def_id.to_def_id(), trait_item_def_id: impl_item_ref.trait_item_def_id, container: ty::AssocItemContainer::Impl, - fn_has_self_parameter: has_self, opt_rpitit_info: None, } } @@ -269,7 +267,6 @@ fn associated_type_for_impl_trait_in_trait( def_id, trait_item_def_id: None, container: ty::AssocItemContainer::Trait, - fn_has_self_parameter: false, opt_rpitit_info: Some(ImplTraitInTraitData::Trait { fn_def_id: fn_def_id.to_def_id(), opaque_def_id: opaque_ty_def_id.to_def_id(), @@ -322,7 +319,6 @@ fn associated_type_for_impl_trait_in_impl( def_id, trait_item_def_id: Some(trait_assoc_def_id), container: ty::AssocItemContainer::Impl, - fn_has_self_parameter: false, opt_rpitit_info: Some(ImplTraitInTraitData::Impl { fn_def_id: impl_fn_def_id.to_def_id() }), }); diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 3a2b6974681..2f6870e3c36 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -490,17 +490,17 @@ pub(crate) fn build_impl( return true; } if let Some(associated_trait) = associated_trait { - let assoc_kind = match item.kind { - hir::ImplItemKind::Const(..) => ty::AssocKind::Const, - hir::ImplItemKind::Fn(..) => ty::AssocKind::Fn, - hir::ImplItemKind::Type(..) => ty::AssocKind::Type, + let assoc_tag = match item.kind { + hir::ImplItemKind::Const(..) => ty::AssocTag::Const, + hir::ImplItemKind::Fn(..) => ty::AssocTag::Fn, + hir::ImplItemKind::Type(..) => ty::AssocTag::Type, }; let trait_item = tcx .associated_items(associated_trait.def_id) .find_by_ident_and_kind( tcx, item.ident, - assoc_kind, + assoc_tag, associated_trait.def_id, ) .unwrap(); // SAFETY: For all impl items there exists trait item that has the same name. @@ -527,7 +527,7 @@ pub(crate) fn build_impl( .find_by_ident_and_kind( tcx, item.ident(tcx), - item.kind, + item.as_tag(), associated_trait.def_id, ) .unwrap(); // corresponding associated item has to exist diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 45a915719e9..7cfd204aa13 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1374,10 +1374,10 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo } } } - ty::AssocKind::Fn => { + ty::AssocKind::Fn { has_self } => { let mut item = inline::build_function(cx, assoc_item.def_id); - if assoc_item.fn_has_self_parameter { + if has_self { let self_ty = match assoc_item.container { ty::AssocItemContainer::Impl => { tcx.type_of(assoc_item.container_id(tcx)).instantiate_identity() diff --git a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs index ad18c7039ee..4a876b85416 100644 --- a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs +++ b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs @@ -56,7 +56,7 @@ fn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) - cx.tcx.associated_items(trait_id).find_by_ident_and_kind( cx.tcx, Ident::from_str("Output"), - ty::AssocKind::Type, + ty::AssocTag::Type, trait_id, ) }) diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs index b01929747d6..77085d52a32 100644 --- a/src/tools/clippy/clippy_lints/src/len_zero.rs +++ b/src/tools/clippy/clippy_lints/src/len_zero.rs @@ -13,7 +13,7 @@ use rustc_hir::{ QPath, TraitItemRef, TyKind, }; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::{self, AssocKind, FnSig, Ty}; +use rustc_middle::ty::{self, FnSig, Ty}; use rustc_session::declare_lint_pass; use rustc_span::source_map::Spanned; use rustc_span::symbol::sym; @@ -288,8 +288,7 @@ fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, ident: Iden .items() .flat_map(|&i| cx.tcx.associated_items(i).filter_by_name_unhygienic(is_empty)) .any(|i| { - i.kind == AssocKind::Fn - && i.fn_has_self_parameter + i.is_method() && cx.tcx.fn_sig(i.def_id).skip_binder().inputs().skip_binder().len() == 1 }); @@ -466,7 +465,7 @@ fn check_for_is_empty( .inherent_impls(impl_ty) .iter() .flat_map(|&id| cx.tcx.associated_items(id).filter_by_name_unhygienic(is_empty)) - .find(|item| item.kind == AssocKind::Fn); + .find(|item| item.is_fn()); let (msg, is_empty_span, self_kind) = match is_empty { None => ( @@ -486,7 +485,7 @@ fn check_for_is_empty( None, ), Some(is_empty) - if !(is_empty.fn_has_self_parameter + if !(is_empty.is_method() && check_is_empty_sig( cx, cx.tcx.fn_sig(is_empty.def_id).instantiate_identity().skip_binder(), @@ -608,7 +607,7 @@ fn is_empty_array(expr: &Expr<'_>) -> bool { fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { /// Gets an `AssocItem` and return true if it matches `is_empty(self)`. fn is_is_empty(cx: &LateContext<'_>, item: &ty::AssocItem) -> bool { - if item.kind == AssocKind::Fn { + if item.is_fn() { let sig = cx.tcx.fn_sig(item.def_id).skip_binder(); let ty = sig.skip_binder(); ty.inputs().len() == 1 diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs index 239ee6c729f..e4a29b6560e 100644 --- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs @@ -17,7 +17,7 @@ use rustc_hir::{ }; use rustc_lint::LateContext; use rustc_middle::hir::nested_filter; -use rustc_middle::ty::{self, AssocKind, ClauseKind, EarlyBinder, GenericArg, GenericArgKind, Ty}; +use rustc_middle::ty::{self, AssocTag, ClauseKind, EarlyBinder, GenericArg, GenericArgKind, Ty}; use rustc_span::symbol::Ident; use rustc_span::{Span, sym}; @@ -241,7 +241,7 @@ fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) - && let Some(iter_item) = cx.tcx.associated_items(iter_trait).find_by_ident_and_kind( cx.tcx, Ident::with_dummy_span(sym::Item), - AssocKind::Type, + AssocTag::Type, iter_trait, ) && let args = cx.tcx.mk_args(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))]) diff --git a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs index c03420a5143..6eeeea5d77c 100644 --- a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs +++ b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs @@ -78,7 +78,7 @@ pub(super) fn check<'tcx>( .iter() .flat_map(|impl_id| cx.tcx.associated_items(impl_id).filter_by_name_unhygienic(sugg)) .find_map(|assoc| { - if assoc.fn_has_self_parameter + if assoc.is_method() && cx.tcx.fn_sig(assoc.def_id).skip_binder().inputs().skip_binder().len() == 1 { Some(assoc.def_id) diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs index f686cc912dd..e579dd5947d 100644 --- a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs +++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs @@ -299,7 +299,7 @@ fn has_ref_mut_self_method(cx: &LateContext<'_>, trait_def_id: DefId) -> bool { .associated_items(trait_def_id) .in_definition_order() .any(|assoc_item| { - if assoc_item.fn_has_self_parameter { + if assoc_item.is_method() { let self_ty = cx .tcx .fn_sig(assoc_item.def_id) diff --git a/src/tools/clippy/clippy_lints/src/same_name_method.rs b/src/tools/clippy/clippy_lints/src/same_name_method.rs index 552135b15fd..ae677e110af 100644 --- a/src/tools/clippy/clippy_lints/src/same_name_method.rs +++ b/src/tools/clippy/clippy_lints/src/same_name_method.rs @@ -3,7 +3,6 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::{DefKind, Res}; use rustc_hir::{HirId, Impl, ItemKind, Node, Path, QPath, TraitRef, TyKind}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::AssocKind; use rustc_session::declare_lint_pass; use rustc_span::Span; use rustc_span::symbol::Symbol; @@ -85,7 +84,7 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod { cx.tcx .associated_items(did) .in_definition_order() - .filter(|assoc_item| matches!(assoc_item.kind, AssocKind::Fn)) + .filter(|assoc_item| assoc_item.is_fn()) .map(|assoc_item| assoc_item.name) .collect() } else { diff --git a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs index 51c7d6fce31..2104eb302ab 100644 --- a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs @@ -10,7 +10,7 @@ use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, Item, ItemKind, Node, QPath use rustc_hir_analysis::lower_ty; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; -use rustc_middle::ty::{self, AssocKind, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::impl_lint_pass; use rustc_span::symbol::{Ident, kw}; use rustc_span::{Span, sym}; @@ -322,7 +322,7 @@ impl UnconditionalRecursion { .in_definition_order() // We're not interested in foreign implementations of the `Default` trait. .find(|item| { - item.kind == AssocKind::Fn && item.def_id.is_local() && item.name == kw::Default + item.is_fn() && item.def_id.is_local() && item.name == kw::Default }) && let Some(body_node) = cx.tcx.hir_get_if_local(assoc_item.def_id) && let Some(body_id) = body_node.body_id() diff --git a/src/tools/clippy/clippy_lints/src/unused_self.rs b/src/tools/clippy/clippy_lints/src/unused_self.rs index 582aa6e6001..d0067b1a65e 100644 --- a/src/tools/clippy/clippy_lints/src/unused_self.rs +++ b/src/tools/clippy/clippy_lints/src/unused_self.rs @@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedSelf { .is_some() }; if let ItemKind::Impl(Impl { of_trait: None, .. }) = parent_item.kind - && assoc_item.fn_has_self_parameter + && assoc_item.is_method() && let ImplItemKind::Fn(.., body_id) = &impl_item.kind && (!cx.effective_visibilities.is_exported(impl_item.owner_id.def_id) || !self.avoid_breaking_exported_api) && let body = cx.tcx.hir_body(*body_id) diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs index 3779e2f3062..d33e59342a5 100644 --- a/src/tools/clippy/clippy_utils/src/ty/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs @@ -19,7 +19,7 @@ use rustc_middle::mir::interpret::Scalar; use rustc_middle::traits::EvaluationResult; use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::{ - self, AdtDef, AliasTy, AssocItem, AssocKind, Binder, BoundRegion, FnSig, GenericArg, GenericArgKind, + self, AdtDef, AliasTy, AssocItem, AssocTag, Binder, BoundRegion, FnSig, GenericArg, GenericArgKind, GenericArgsRef, GenericParamDefKind, IntTy, ParamEnv, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr, }; @@ -1112,7 +1112,7 @@ pub fn make_projection<'tcx>( let Some(assoc_item) = tcx.associated_items(container_id).find_by_ident_and_kind( tcx, Ident::with_dummy_span(assoc_ty), - AssocKind::Type, + AssocTag::Type, container_id, ) else { debug_assert!(false, "type `{assoc_ty}` not found in `{container_id:?}`"); @@ -1345,7 +1345,7 @@ pub fn get_adt_inherent_method<'a>(cx: &'a LateContext<'_>, ty: Ty<'_>, method_n .associated_items(did) .filter_by_name_unhygienic(method_name) .next() - .filter(|item| item.kind == AssocKind::Fn) + .filter(|item| item.as_tag() == AssocTag::Fn) }) } else { None diff --git a/tests/ui/generic-associated-types/impl_bounds.stderr b/tests/ui/generic-associated-types/impl_bounds.stderr index 231c0dd89c5..7847bbd813c 100644 --- a/tests/ui/generic-associated-types/impl_bounds.stderr +++ b/tests/ui/generic-associated-types/impl_bounds.stderr @@ -57,14 +57,14 @@ note: required for `Fooy` to implement `Copy` | LL | #[derive(Copy, Clone)] | ^^^^ unsatisfied trait bound introduced in this `derive` macro -note: the requirement `Fooy: Copy` appears on the `impl`'s method `d` but not on the corresponding trait's method +note: the requirement `Fooy: Copy` appears on the `impl`'s associated function `d` but not on the corresponding trait's associated function --> $DIR/impl_bounds.rs:7:8 | LL | trait Foo { | --- in this trait ... LL | fn d() where Self: Clone; - | ^ this trait's method doesn't have the requirement `Fooy: Copy` + | ^ this trait's associated function doesn't have the requirement `Fooy: Copy` help: consider restricting type parameter `T` with trait `Copy` | LL | impl Foo for Fooy { diff --git a/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr b/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr index 74a0a90885d..d179c805962 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr +++ b/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr @@ -4,14 +4,14 @@ error[E0275]: overflow evaluating the requirement `<() as A>::Assoc: A` LL | Self::Assoc: A, | ^^^^ | -note: the requirement `<() as A>::Assoc: A` appears on the `impl`'s method `f` but not on the corresponding trait's method +note: the requirement `<() as A>::Assoc: A` appears on the `impl`'s associated function `f` but not on the corresponding trait's associated function --> $DIR/normalize-param-env-2.rs:12:8 | LL | trait A { | - in this trait ... LL | fn f() - | ^ this trait's method doesn't have the requirement `<() as A>::Assoc: A` + | ^ this trait's associated function doesn't have the requirement `<() as A>::Assoc: A` error[E0275]: overflow evaluating the requirement `<() as A>::Assoc: A` --> $DIR/normalize-param-env-2.rs:24:22 -- cgit 1.4.1-3-g733a5 From b26f3d4347ca589305a19d10c6e651b071849716 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 11 Apr 2025 16:50:20 +1000 Subject: Move `opt_rpitit_info` field to `hir::AssocKind::Type`. From `hir::AssocItem`. --- compiler/rustc_hir_analysis/src/check/check.rs | 6 ++-- .../src/check/compare_impl_item.rs | 19 +++++++----- compiler/rustc_hir_analysis/src/check/mod.rs | 2 +- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 6 ++-- .../src/collect/type_of/opaque.rs | 2 +- .../src/errors/wrong_number_of_generic_args.rs | 4 +-- .../src/hir_ty_lowering/dyn_compatibility.rs | 2 +- .../rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 2 +- compiler/rustc_hir_analysis/src/impl_wf_check.rs | 2 +- compiler/rustc_hir_typeck/src/method/probe.rs | 12 ++------ compiler/rustc_metadata/src/rmeta/decoder.rs | 12 +++++--- compiler/rustc_metadata/src/rmeta/encoder.rs | 4 +-- compiler/rustc_middle/src/ty/assoc.rs | 34 +++++++++++++--------- compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 6 ++-- compiler/rustc_middle/src/ty/sty.rs | 2 +- .../src/cfi/typeid/itanium_cxx_abi/transform.rs | 2 +- compiler/rustc_smir/src/rustc_smir/convert/ty.rs | 7 +++-- compiler/rustc_smir/src/stable_mir/mir/pretty.rs | 2 +- compiler/rustc_smir/src/stable_mir/ty.rs | 18 +++++++----- .../src/error_reporting/infer/mod.rs | 8 +++-- .../src/error_reporting/traits/ambiguity.rs | 2 +- .../src/error_reporting/traits/suggestions.rs | 2 +- .../src/traits/dyn_compatibility.rs | 4 +-- .../src/traits/select/confirmation.rs | 4 +-- compiler/rustc_ty_utils/src/assoc.rs | 24 ++++++++------- src/librustdoc/clean/mod.rs | 2 +- .../clippy_lints/src/implied_bounds_in_impls.rs | 2 +- 28 files changed, 103 insertions(+), 91 deletions(-) (limited to 'compiler/rustc_hir_analysis/src') diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index c2706a1d401..12c36e0f4c2 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -449,7 +449,7 @@ fn best_definition_site_of_opaque<'tcx>( return Some(span); } } - ty::AssocKind::Type => {} + ty::AssocKind::Type { .. } => {} } } @@ -740,7 +740,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { for &assoc_item in assoc_items.in_definition_order() { match assoc_item.kind { - ty::AssocKind::Type if assoc_item.defaultness(tcx).has_value() => { + ty::AssocKind::Type { .. } if assoc_item.defaultness(tcx).has_value() => { let trait_args = GenericArgs::identity_for_item(tcx, def_id); let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds( tcx, @@ -953,7 +953,7 @@ fn check_impl_items_against_trait<'tcx>( ); } ty::AssocKind::Const => {} - ty::AssocKind::Type => {} + ty::AssocKind::Type { .. } => {} } } diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 7dfdf1ae237..d208aa71971 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -44,7 +44,7 @@ pub(super) fn compare_impl_item( match impl_item.kind { ty::AssocKind::Fn { .. } => compare_impl_method(tcx, impl_item, trait_item, impl_trait_ref), - ty::AssocKind::Type => compare_impl_ty(tcx, impl_item, trait_item, impl_trait_ref), + ty::AssocKind::Type { .. } => compare_impl_ty(tcx, impl_item, trait_item, impl_trait_ref), ty::AssocKind::Const => compare_impl_const(tcx, impl_item, trait_item, impl_trait_ref), } } @@ -1703,7 +1703,7 @@ fn compare_generic_param_kinds<'tcx>( trait_item: ty::AssocItem, delay: bool, ) -> Result<(), ErrorGuaranteed> { - assert_eq!(impl_item.kind, trait_item.kind); + assert_eq!(impl_item.as_tag(), trait_item.as_tag()); let ty_const_params_of = |def_id| { tcx.generics_of(def_id).own_params.iter().filter(|param| { @@ -2235,16 +2235,19 @@ fn param_env_with_gat_bounds<'tcx>( // of the RPITITs associated with the same body. This is because checking // the item bounds of RPITITs often involves nested RPITITs having to prove // bounds about themselves. - let impl_tys_to_install = match impl_ty.opt_rpitit_info { - None => vec![impl_ty], - Some( - ty::ImplTraitInTraitData::Impl { fn_def_id } - | ty::ImplTraitInTraitData::Trait { fn_def_id, .. }, - ) => tcx + let impl_tys_to_install = match impl_ty.kind { + ty::AssocKind::Type { + opt_rpitit_info: + Some( + ty::ImplTraitInTraitData::Impl { fn_def_id } + | ty::ImplTraitInTraitData::Trait { fn_def_id, .. }, + ), + } => tcx .associated_types_for_impl_traits_in_associated_fn(fn_def_id) .iter() .map(|def_id| tcx.associated_item(*def_id)) .collect(), + _ => vec![impl_ty], }; for impl_ty in impl_tys_to_install { diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 523db9440a4..ec934b1f620 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -499,7 +499,7 @@ fn suggestion_signature<'tcx>( tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args), assoc, ), - ty::AssocKind::Type => { + ty::AssocKind::Type { .. } => { let (generics, where_clauses) = bounds_from_generic_predicates( tcx, tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args), diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index af7830fd664..c6c370c4a84 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -408,7 +408,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) { let gat_def_id = gat_item.def_id.expect_local(); let gat_item = tcx.associated_item(gat_def_id); // If this item is not an assoc ty, or has no args, then it's not a GAT - if gat_item.kind != ty::AssocKind::Type { + if !gat_item.is_type() { continue; } let gat_generics = tcx.generics_of(gat_def_id); @@ -453,7 +453,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) { ) } // In our example, this corresponds to the `Iter` and `Item` associated types - ty::AssocKind::Type => { + ty::AssocKind::Type { .. } => { // If our associated item is a GAT with missing bounds, add them to // the param-env here. This allows this GAT to propagate missing bounds // to other GATs. @@ -1101,7 +1101,7 @@ fn check_associated_item( ); check_method_receiver(wfcx, hir_sig, item, self_ty) } - ty::AssocKind::Type => { + ty::AssocKind::Type { .. } => { if let ty::AssocItemContainer::Trait = item.container { check_associated_type_bounds(wfcx, item, span) } diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index f0663644719..653adc6b3ba 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -36,7 +36,7 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type( locator.check(assoc_id.expect_local()) } // Associated types don't have bodies, so they can't constrain hidden types - ty::AssocKind::Type => {} + ty::AssocKind::Type { .. } => {} } } diff --git a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs index 610b293a114..70d60bfcf2d 100644 --- a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs @@ -4,7 +4,7 @@ use GenericArgsInfo::*; use rustc_errors::codes::*; use rustc_errors::{Applicability, Diag, Diagnostic, EmissionGuarantee, MultiSpan, pluralize}; use rustc_hir as hir; -use rustc_middle::ty::{self as ty, AssocItems, AssocKind, TyCtxt}; +use rustc_middle::ty::{self as ty, AssocItems, TyCtxt}; use rustc_span::def_id::DefId; use tracing::debug; @@ -486,7 +486,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { let items: &AssocItems = self.tcx.associated_items(self.def_id); items .in_definition_order() - .filter(|item| item.kind == AssocKind::Type) + .filter(|item| item.is_type()) .filter(|item| { !self .gen_args diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs index e64cd8ec302..2e39beed8ae 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs @@ -201,7 +201,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { tcx.associated_items(pred.trait_ref.def_id) .in_definition_order() // We only care about associated types. - .filter(|item| item.kind == ty::AssocKind::Type) + .filter(|item| item.is_type()) // No RPITITs -- they're not dyn-compatible for now. .filter(|item| !item.is_impl_trait_in_trait()) // If the associated type has a `where Self: Sized` bound, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 0fb406d9908..0394dd20e28 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1733,7 +1733,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .any(|i| { i.kind.namespace() == Namespace::TypeNS && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident - && matches!(i.kind, ty::AssocKind::Type) + && i.is_type() }) // Consider only accessible traits && tcx.visibility(*trait_def_id) diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 1ab36ce1dcb..127ca846b9f 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -112,7 +112,7 @@ pub(crate) fn enforce_impl_lifetime_params_are_constrained( .flat_map(|def_id| { let item = tcx.associated_item(def_id); match item.kind { - ty::AssocKind::Type => { + ty::AssocKind::Type { .. } => { if item.defaultness(tcx).has_value() { cgp::parameters_for(tcx, tcx.type_of(def_id).instantiate_identity(), true) } else { diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index d5d85c812b2..07cb8c2a5bb 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1671,15 +1671,7 @@ impl<'tcx> Pick<'tcx> { /// Do not use for type checking. pub(crate) fn differs_from(&self, other: &Self) -> bool { let Self { - item: - AssocItem { - def_id, - name: _, - kind: _, - container: _, - trait_item_def_id: _, - opt_rpitit_info: _, - }, + item: AssocItem { def_id, name: _, kind: _, container: _, trait_item_def_id: _ }, kind: _, import_ids: _, autoderefs: _, @@ -2253,7 +2245,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { match self.mode { Mode::MethodCall => item.is_method(), Mode::Path => match item.kind { - ty::AssocKind::Type => false, + ty::AssocKind::Type { .. } => false, ty::AssocKind::Fn { .. } | ty::AssocKind::Const => true, }, } diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index cc3b2a241e4..3cbe09280f6 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1342,12 +1342,17 @@ impl<'a> CrateMetadataRef<'a> { DefKind::AssocFn => { ty::AssocKind::Fn { has_self: self.get_fn_has_self_parameter(id, sess) } } - DefKind::AssocTy => ty::AssocKind::Type, + DefKind::AssocTy => ty::AssocKind::Type { + opt_rpitit_info: self + .root + .tables + .opt_rpitit_info + .get(self, id) + .map(|d| d.decode(self)), + }, _ => bug!("cannot get associated-item of `{:?}`", self.def_key(id)), }; let container = self.root.tables.assoc_container.get(self, id).unwrap(); - let opt_rpitit_info = - self.root.tables.opt_rpitit_info.get(self, id).map(|d| d.decode(self)); ty::AssocItem { name, @@ -1355,7 +1360,6 @@ impl<'a> CrateMetadataRef<'a> { def_id: self.local_def_id(id), trait_item_def_id: self.get_trait_item_def_id(id), container, - opt_rpitit_info, } } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index cc9da16ffdb..b900100c3c0 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1691,7 +1691,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { match item.container { AssocItemContainer::Trait => { - if let ty::AssocKind::Type = item.kind { + if item.is_type() { self.encode_explicit_item_bounds(def_id); self.encode_explicit_item_self_bounds(def_id); if tcx.is_conditionally_const(def_id) { @@ -1706,7 +1706,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } } - if let Some(rpitit_info) = item.opt_rpitit_info { + if let ty::AssocKind::Type { opt_rpitit_info: Some(rpitit_info) } = item.kind { record!(self.tables.opt_rpitit_info[def_id] <- rpitit_info); if matches!(rpitit_info, ty::ImplTraitInTraitData::Trait { .. }) { record_array!( diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index 3c1e5ed9e11..eac8f04f84f 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -25,11 +25,6 @@ pub struct AssocItem { /// If this is an item in an impl of a trait then this is the `DefId` of /// the associated item on the trait that this implements. pub trait_item_def_id: Option, - - /// `Some` if the associated item (an associated type) comes from the - /// return-position `impl Trait` in trait desugaring. The `ImplTraitInTraitData` - /// provides additional information about its source. - pub opt_rpitit_info: Option, } impl AssocItem { @@ -81,7 +76,7 @@ impl AssocItem { // regions just fine, showing `fn(&MyType)`. tcx.fn_sig(self.def_id).instantiate_identity().skip_binder().to_string() } - ty::AssocKind::Type => format!("type {};", self.name), + ty::AssocKind::Type { .. } => format!("type {};", self.name), ty::AssocKind::Const => { format!( "const {}: {:?};", @@ -97,10 +92,14 @@ impl AssocItem { ty::AssocKind::Const => "associated const", ty::AssocKind::Fn { has_self: true } => "method", ty::AssocKind::Fn { has_self: false } => "associated function", - ty::AssocKind::Type => "associated type", + ty::AssocKind::Type { .. } => "associated type", } } + pub fn is_type(&self) -> bool { + matches!(self.kind, ty::AssocKind::Type { .. }) + } + pub fn is_fn(&self) -> bool { matches!(self.kind, ty::AssocKind::Fn { .. }) } @@ -113,12 +112,12 @@ impl AssocItem { match self.kind { AssocKind::Const => AssocTag::Const, AssocKind::Fn { .. } => AssocTag::Fn, - AssocKind::Type => AssocTag::Type, + AssocKind::Type { .. } => AssocTag::Type, } } pub fn is_impl_trait_in_trait(&self) -> bool { - self.opt_rpitit_info.is_some() + matches!(self.kind, AssocKind::Type { opt_rpitit_info: Some(_) }) } /// Returns true if: @@ -143,14 +142,21 @@ impl AssocItem { #[derive(Copy, Clone, PartialEq, Debug, HashStable, Eq, Hash, Encodable, Decodable)] pub enum AssocKind { Const, - Fn { has_self: bool }, - Type, + Fn { + has_self: bool, + }, + Type { + /// `Some` if the associated type comes from an RPITIT. The + /// `ImplTraitInTraitData` provides additional information about its + /// source. + opt_rpitit_info: Option, + }, } impl AssocKind { pub fn namespace(&self) -> Namespace { match *self { - ty::AssocKind::Type => Namespace::TypeNS, + ty::AssocKind::Type { .. } => Namespace::TypeNS, ty::AssocKind::Const | ty::AssocKind::Fn { .. } => Namespace::ValueNS, } } @@ -159,7 +165,7 @@ impl AssocKind { match self { AssocKind::Const => DefKind::AssocConst, AssocKind::Fn { .. } => DefKind::AssocFn, - AssocKind::Type => DefKind::AssocTy, + AssocKind::Type { .. } => DefKind::AssocTy, } } } @@ -170,7 +176,7 @@ impl std::fmt::Display for AssocKind { AssocKind::Fn { has_self: true } => write!(f, "method"), AssocKind::Fn { has_self: false } => write!(f, "associated function"), AssocKind::Const => write!(f, "associated const"), - AssocKind::Type => write!(f, "associated type"), + AssocKind::Type { .. } => write!(f, "associated type"), } } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index abf6cbbcd87..fb25b8e130b 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -464,7 +464,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator { self.associated_items(def_id) .in_definition_order() - .filter(|assoc_item| matches!(assoc_item.kind, ty::AssocKind::Type)) + .filter(|assoc_item| assoc_item.is_type()) .map(|assoc_item| assoc_item.def_id) } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 30c889c39d9..395d2ec4814 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1610,8 +1610,10 @@ impl<'tcx> TyCtxt<'tcx> { /// return-position `impl Trait` from a trait, then provide the source info /// about where that RPITIT came from. pub fn opt_rpitit_info(self, def_id: DefId) -> Option { - if let DefKind::AssocTy = self.def_kind(def_id) { - self.associated_item(def_id).opt_rpitit_info + if let DefKind::AssocTy = self.def_kind(def_id) + && let AssocKind::Type { opt_rpitit_info } = self.associated_item(def_id).kind + { + opt_rpitit_info } else { None } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 27ee363f1c1..bb178fe4253 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -734,7 +734,7 @@ impl<'tcx> Ty<'tcx> { .map(|principal| { tcx.associated_items(principal.def_id()) .in_definition_order() - .filter(|item| item.kind == ty::AssocKind::Type) + .filter(|item| item.is_type()) .filter(|item| !item.is_impl_trait_in_trait()) .filter(|item| !tcx.generics_require_sized_self(item.def_id)) .count() diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index 718b9a4fa3b..d2917478e4e 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -240,7 +240,7 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc .flat_map(|super_poly_trait_ref| { tcx.associated_items(super_poly_trait_ref.def_id()) .in_definition_order() - .filter(|item| item.kind == ty::AssocKind::Type) + .filter(|item| item.is_type()) .filter(|item| !tcx.generics_require_sized_self(item.def_id)) .map(move |assoc_ty| { super_poly_trait_ref.map_bound(|super_trait_ref| { diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index 94f3be9fef7..55f698b8f21 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -894,12 +894,14 @@ impl<'tcx> Stable<'tcx> for rustc_session::cstore::ForeignModule { impl<'tcx> Stable<'tcx> for ty::AssocKind { type T = stable_mir::ty::AssocKind; - fn stable(&self, _tables: &mut Tables<'_>) -> Self::T { + fn stable(&self, tables: &mut Tables<'_>) -> Self::T { use stable_mir::ty::AssocKind; match *self { ty::AssocKind::Const => AssocKind::Const, ty::AssocKind::Fn { has_self } => AssocKind::Fn { has_self }, - ty::AssocKind::Type => AssocKind::Type, + ty::AssocKind::Type { opt_rpitit_info } => AssocKind::Type { + opt_rpitit_info: opt_rpitit_info.map(|rpitit| rpitit.stable(tables)), + }, } } } @@ -926,7 +928,6 @@ impl<'tcx> Stable<'tcx> for ty::AssocItem { kind: self.kind.stable(tables), container: self.container.stable(tables), trait_item_def_id: self.trait_item_def_id.map(|did| tables.assoc_def(did)), - opt_rpitit_info: self.opt_rpitit_info.map(|rpitit| rpitit.stable(tables)), } } } diff --git a/compiler/rustc_smir/src/stable_mir/mir/pretty.rs b/compiler/rustc_smir/src/stable_mir/mir/pretty.rs index 60d9e122940..9fa97763907 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/pretty.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/pretty.rs @@ -25,7 +25,7 @@ impl Display for AssocKind { AssocKind::Fn { has_self: true } => write!(f, "method"), AssocKind::Fn { has_self: false } => write!(f, "associated function"), AssocKind::Const => write!(f, "associated const"), - AssocKind::Type => write!(f, "associated type"), + AssocKind::Type { .. } => write!(f, "associated type"), } } } diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs index 63ce756162a..6eac0885d76 100644 --- a/compiler/rustc_smir/src/stable_mir/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/ty.rs @@ -1585,18 +1585,20 @@ pub struct AssocItem { /// If this is an item in an impl of a trait then this is the `DefId` of /// the associated item on the trait that this implements. pub trait_item_def_id: Option, - - /// `Some` if the associated item (an associated type) comes from the - /// return-position `impl Trait` in trait desugaring. The `ImplTraitInTraitData` - /// provides additional information about its source. - pub opt_rpitit_info: Option, } #[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum AssocKind { Const, - Fn { has_self: bool }, - Type, + Fn { + has_self: bool, + }, + Type { + /// `Some` if the associated type comes from an RPITIT. The + /// `ImplTraitInTraitData` provides additional information about its + /// source. + opt_rpitit_info: Option, + }, } #[derive(Clone, Debug, Eq, PartialEq, Serialize)] @@ -1613,6 +1615,6 @@ pub enum ImplTraitInTraitData { impl AssocItem { pub fn is_impl_trait_in_trait(&self) -> bool { - self.opt_rpitit_info.is_some() + matches!(self.kind, AssocKind::Type { opt_rpitit_info: Some(_) }) } } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index cbadb46c17d..1c71fe028d4 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -2337,7 +2337,7 @@ impl<'tcx> ObligationCause<'tcx> { ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Fn { .. }, .. } => { ObligationCauseFailureCode::MethodCompat { span, subdiags } } - ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Type, .. } => { + ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Type { .. }, .. } => { ObligationCauseFailureCode::TypeCompat { span, subdiags } } ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Const, .. } => { @@ -2401,7 +2401,7 @@ impl<'tcx> ObligationCause<'tcx> { ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Fn { .. }, .. } => { "method type is compatible with trait" } - ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Type, .. } => { + ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Type { .. }, .. } => { "associated type is compatible with trait" } ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Const, .. } => { @@ -2425,7 +2425,9 @@ impl IntoDiagArg for ObligationCauseAsDiagArg<'_> { ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Fn { .. }, .. } => { "method_compat" } - ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Type, .. } => "type_compat", + ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Type { .. }, .. } => { + "type_compat" + } ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Const, .. } => { "const_compat" } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index e3e1583a48f..c4b0ca9cf8f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -352,7 +352,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ty::AssocKind::Fn { .. } => ("call", "function"), // This is already covered by E0223, but this following single match // arm doesn't hurt here. - ty::AssocKind::Type => ("refer to the", "type"), + ty::AssocKind::Type { .. } => ("refer to the", "type"), }; // Replace the more general E0283 with a more specific error diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 38aac8e70b5..084942cd8af 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -2112,7 +2112,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { trait_ref: DefId, ) { if let Some(assoc_item) = self.tcx.opt_associated_item(item_def_id) { - if let ty::AssocKind::Const | ty::AssocKind::Type = assoc_item.kind { + if let ty::AssocKind::Const | ty::AssocKind::Type { .. } = assoc_item.kind { err.note(format!( "{}s cannot be accessed directly on a `trait`, they can only be \ accessed through a specific `impl`", diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index 76892db9ef7..1ef16f34702 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -188,7 +188,7 @@ fn bounds_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span tcx.associated_items(trait_def_id) .in_definition_order() // We're only looking at associated type bounds - .filter(|item| item.kind == ty::AssocKind::Type) + .filter(|item| item.is_type()) // Ignore GATs with `Self: Sized` .filter(|item| !tcx.generics_require_sized_self(item.def_id)) .flat_map(|item| tcx.explicit_item_bounds(item.def_id).iter_identity_copied()) @@ -320,7 +320,7 @@ pub fn dyn_compatibility_violations_for_assoc_item( }) .collect(), // Associated types can only be dyn-compatible if they have `Self: Sized` bounds. - ty::AssocKind::Type => { + ty::AssocKind::Type { .. } => { if !tcx.generics_of(item.def_id).is_own_empty() && !item.is_impl_trait_in_trait() { vec![DynCompatibilityViolation::GAT(item.name, item.ident(tcx).span)] } else { diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 69e7b2a43ff..d71d1e9ae0f 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -594,9 +594,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Associated types that require `Self: Sized` do not show up in the built-in // implementation of `Trait for dyn Trait`, and can be dropped here. .filter(|item| !tcx.generics_require_sized_self(item.def_id)) - .filter_map( - |item| if item.kind == ty::AssocKind::Type { Some(item.def_id) } else { None }, - ) + .filter_map(|item| if item.is_type() { Some(item.def_id) } else { None }) .collect(); for assoc_type in assoc_types { diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 79de071b687..2275fbb9792 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -132,7 +132,7 @@ fn associated_item_from_trait_item_ref(trait_item_ref: &hir::TraitItemRef) -> ty let kind = match trait_item_ref.kind { hir::AssocItemKind::Const => ty::AssocKind::Const, hir::AssocItemKind::Fn { has_self } => ty::AssocKind::Fn { has_self }, - hir::AssocItemKind::Type => ty::AssocKind::Type, + hir::AssocItemKind::Type => ty::AssocKind::Type { opt_rpitit_info: None }, }; ty::AssocItem { @@ -141,7 +141,6 @@ fn associated_item_from_trait_item_ref(trait_item_ref: &hir::TraitItemRef) -> ty def_id: owner_id.to_def_id(), trait_item_def_id: Some(owner_id.to_def_id()), container: ty::AssocItemContainer::Trait, - opt_rpitit_info: None, } } @@ -150,7 +149,7 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A let kind = match impl_item_ref.kind { hir::AssocItemKind::Const => ty::AssocKind::Const, hir::AssocItemKind::Fn { has_self } => ty::AssocKind::Fn { has_self }, - hir::AssocItemKind::Type => ty::AssocKind::Type, + hir::AssocItemKind::Type => ty::AssocKind::Type { opt_rpitit_info: None }, }; ty::AssocItem { @@ -159,7 +158,6 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A def_id: def_id.to_def_id(), trait_item_def_id: impl_item_ref.trait_item_def_id, container: ty::AssocItemContainer::Impl, - opt_rpitit_info: None, } } @@ -263,14 +261,15 @@ fn associated_type_for_impl_trait_in_trait( trait_assoc_ty.associated_item(ty::AssocItem { name: kw::Empty, - kind: ty::AssocKind::Type, + kind: ty::AssocKind::Type { + opt_rpitit_info: Some(ImplTraitInTraitData::Trait { + fn_def_id: fn_def_id.to_def_id(), + opaque_def_id: opaque_ty_def_id.to_def_id(), + }), + }, def_id, trait_item_def_id: None, container: ty::AssocItemContainer::Trait, - opt_rpitit_info: Some(ImplTraitInTraitData::Trait { - fn_def_id: fn_def_id.to_def_id(), - opaque_def_id: opaque_ty_def_id.to_def_id(), - }), }); // Copy visility of the containing function. @@ -315,11 +314,14 @@ fn associated_type_for_impl_trait_in_impl( impl_assoc_ty.associated_item(ty::AssocItem { name: kw::Empty, - kind: ty::AssocKind::Type, + kind: ty::AssocKind::Type { + opt_rpitit_info: Some(ImplTraitInTraitData::Impl { + fn_def_id: impl_fn_def_id.to_def_id(), + }), + }, def_id, trait_item_def_id: Some(trait_assoc_def_id), container: ty::AssocItemContainer::Impl, - opt_rpitit_info: Some(ImplTraitInTraitData::Impl { fn_def_id: impl_fn_def_id.to_def_id() }), }); // Copy visility of the containing function. diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 7cfd204aa13..74dbc7d0600 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1412,7 +1412,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo RequiredMethodItem(item) } } - ty::AssocKind::Type => { + ty::AssocKind::Type { .. } => { let my_name = assoc_item.name; fn param_eq_arg(param: &GenericParamDef, arg: &GenericArg) -> bool { 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 d02d9b2102b..430f2411183 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 @@ -315,7 +315,7 @@ fn check<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds<'tcx>) { assocs .filter_by_name_unhygienic(constraint.ident.name) .next() - .is_some_and(|assoc| assoc.kind == ty::AssocKind::Type) + .is_some_and(|assoc| assoc.is_type()) }) { emit_lint(cx, poly_trait, bounds, index, implied_constraints, bound); -- cgit 1.4.1-3-g733a5 From 89e93a51c81b521a9601b365e3325d31e44e9198 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 14 Apr 2025 15:39:47 +1000 Subject: Move two methods from `AssocKind` to `AssocItem`. Because all the other similar methods are on `AssocItem`. --- .../src/coherence/inherent_impls_overlap.rs | 2 +- .../rustc_hir_analysis/src/hir_ty_lowering/lint.rs | 2 +- .../rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 2 +- compiler/rustc_hir_typeck/src/method/mod.rs | 2 +- compiler/rustc_hir_typeck/src/method/probe.rs | 4 +-- compiler/rustc_hir_typeck/src/method/suggest.rs | 4 +-- compiler/rustc_middle/src/ty/assoc.rs | 33 ++++++++++------------ .../src/error_reporting/traits/suggestions.rs | 2 +- src/librustdoc/passes/collect_intra_doc_links.rs | 4 +-- 9 files changed, 26 insertions(+), 29 deletions(-) (limited to 'compiler/rustc_hir_analysis/src') diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs index dc616576c9c..cbfad1f6883 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs @@ -64,7 +64,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> { fn compare_hygienically(&self, item1: ty::AssocItem, item2: ty::AssocItem) -> bool { // Symbols and namespace match, compare hygienically. - item1.kind.namespace() == item2.kind.namespace() + item1.namespace() == item2.namespace() && item1.ident(self.tcx).normalize_to_macros_2_0() == item2.ident(self.tcx).normalize_to_macros_2_0() } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index 8e62dce2191..49fd55b03a2 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -501,7 +501,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let names: Vec<_> = tcx .associated_items(trait_def_id) .in_definition_order() - .filter(|assoc| assoc.kind.namespace() == Namespace::ValueNS) + .filter(|assoc| assoc.namespace() == Namespace::ValueNS) .map(|cand| cand.name) .collect(); if let Some(typo) = find_best_match_for_name(&names, segment.ident.name, None) { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 0394dd20e28..7605c6c6a42 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1731,7 +1731,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { tcx.associated_items(*trait_def_id) .in_definition_order() .any(|i| { - i.kind.namespace() == Namespace::TypeNS + i.namespace() == Namespace::TypeNS && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident && i.is_type() }) diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index 39cb139a199..1b67e2306aa 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -529,7 +529,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - let def_kind = pick.item.kind.as_def_kind(); + let def_kind = pick.item.as_def_kind(); tcx.check_stability(pick.item.def_id, Some(expr_id), span, Some(method_name.span)); Ok((def_kind, pick.item.def_id)) } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 07cb8c2a5bb..c14b7823e37 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1583,7 +1583,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { }, None, ) { - self.private_candidate.set(Some((pick.item.kind.as_def_kind(), pick.item.def_id))); + self.private_candidate.set(Some((pick.item.as_def_kind(), pick.item.def_id))); } } None @@ -1694,7 +1694,7 @@ impl<'tcx> Pick<'tcx> { if self.unstable_candidates.is_empty() { return; } - let def_kind = self.item.kind.as_def_kind(); + let def_kind = self.item.as_def_kind(); tcx.node_span_lint(lint::builtin::UNSTABLE_NAME_COLLISIONS, scope_expr_id, span, |lint| { lint.primary_message(format!( "{} {} with this name may be added to the standard library in the future", diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 1b9771636a7..962871ed2d1 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1819,7 +1819,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { mode: Mode, ) { let tcx = self.tcx; - let def_kind = similar_candidate.kind.as_def_kind(); + let def_kind = similar_candidate.as_def_kind(); let an = self.tcx.def_kind_descr_article(def_kind, similar_candidate.def_id); let msg = format!( "there is {an} {} `{}` with a similar name", @@ -4288,7 +4288,7 @@ fn print_disambiguation_help<'tcx>( && let SelfSource::MethodCall(receiver) = source && let Some(args) = args { - let def_kind_descr = tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id); + let def_kind_descr = tcx.def_kind_descr(item.as_def_kind(), item.def_id); let item_name = item.ident(tcx); let first_input = tcx.fn_sig(item.def_id).instantiate_identity().skip_binder().inputs().get(0); diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index eac8f04f84f..6138157d836 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -96,6 +96,20 @@ impl AssocItem { } } + pub fn namespace(&self) -> Namespace { + match self.kind { + ty::AssocKind::Type { .. } => Namespace::TypeNS, + ty::AssocKind::Const | ty::AssocKind::Fn { .. } => Namespace::ValueNS, + } + } + + pub fn as_def_kind(&self) -> DefKind { + match self.kind { + AssocKind::Const => DefKind::AssocConst, + AssocKind::Fn { .. } => DefKind::AssocFn, + AssocKind::Type { .. } => DefKind::AssocTy, + } + } pub fn is_type(&self) -> bool { matches!(self.kind, ty::AssocKind::Type { .. }) } @@ -153,23 +167,6 @@ pub enum AssocKind { }, } -impl AssocKind { - pub fn namespace(&self) -> Namespace { - match *self { - ty::AssocKind::Type { .. } => Namespace::TypeNS, - ty::AssocKind::Const | ty::AssocKind::Fn { .. } => Namespace::ValueNS, - } - } - - pub fn as_def_kind(&self) -> DefKind { - match self { - AssocKind::Const => DefKind::AssocConst, - AssocKind::Fn { .. } => DefKind::AssocFn, - AssocKind::Type { .. } => DefKind::AssocTy, - } - } -} - impl std::fmt::Display for AssocKind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { @@ -250,7 +247,7 @@ impl AssocItems { parent_def_id: DefId, ) -> Option<&ty::AssocItem> { self.filter_by_name_unhygienic(ident.name) - .filter(|item| item.kind.namespace() == ns) + .filter(|item| item.namespace() == ns) .find(|item| tcx.hygienic_eq(ident, item.ident(tcx), parent_def_id)) } } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 084942cd8af..08b95b45058 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -2116,7 +2116,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err.note(format!( "{}s cannot be accessed directly on a `trait`, they can only be \ accessed through a specific `impl`", - self.tcx.def_kind_descr(assoc_item.kind.as_def_kind(), item_def_id) + self.tcx.def_kind_descr(assoc_item.as_def_kind(), item_def_id) )); err.span_suggestion( span, diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index fdbb792d25d..297597b3dea 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -60,7 +60,7 @@ fn filter_assoc_items_by_name_and_namespace( ns: Namespace, ) -> impl Iterator { tcx.associated_items(assoc_items_of).filter_by_name_unhygienic(ident.name).filter(move |item| { - item.kind.namespace() == ns && tcx.hygienic_eq(ident, item.ident(tcx), assoc_items_of) + item.namespace() == ns && tcx.hygienic_eq(ident, item.ident(tcx), assoc_items_of) }) } @@ -743,7 +743,7 @@ impl<'tcx> LinkCollector<'_, 'tcx> { ns, ) .map(|item| { - let res = Res::Def(item.kind.as_def_kind(), item.def_id); + let res = Res::Def(item.as_def_kind(), item.def_id); (res, item.def_id) }) .collect::>(), -- cgit 1.4.1-3-g733a5 From 78599d83e7ab9f8cd4cbb9e982ddf12f258d6b18 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 14 Apr 2025 13:15:01 +1000 Subject: Move `name` field from `AssocItem` to `AssocKind` variants. To accurately reflect that RPITIT assoc items don't have a name. This avoids the use of `kw::Empty` to mean "no name", which is error prone. Helps with #137978. --- compiler/rustc_hir_analysis/src/check/check.rs | 4 +- .../src/check/compare_impl_item.rs | 32 ++++--- compiler/rustc_hir_analysis/src/check/mod.rs | 10 +- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 4 +- .../src/coherence/inherent_impls_overlap.rs | 8 +- .../src/collect/type_of/opaque.rs | 2 +- .../src/errors/wrong_number_of_generic_args.rs | 2 +- .../src/hir_ty_lowering/errors.rs | 38 ++++---- .../rustc_hir_analysis/src/hir_ty_lowering/lint.rs | 2 +- compiler/rustc_hir_analysis/src/impl_wf_check.rs | 2 +- compiler/rustc_hir_typeck/src/expr.rs | 5 +- compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 9 +- .../rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 11 ++- compiler/rustc_hir_typeck/src/lib.rs | 2 +- compiler/rustc_hir_typeck/src/method/probe.rs | 25 +++-- compiler/rustc_hir_typeck/src/method/suggest.rs | 27 +++--- compiler/rustc_hir_typeck/src/op.rs | 2 +- compiler/rustc_metadata/src/rmeta/decoder.rs | 30 +++--- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 +- compiler/rustc_middle/src/ty/assoc.rs | 101 ++++++++++++++------- compiler/rustc_middle/src/ty/mod.rs | 5 +- compiler/rustc_middle/src/ty/print/pretty.rs | 6 +- .../src/check_undefined_transmutes.rs | 2 +- compiler/rustc_resolve/src/late/diagnostics.rs | 5 +- compiler/rustc_smir/src/rustc_smir/convert/ty.rs | 18 ++-- compiler/rustc_smir/src/stable_mir/mir/pretty.rs | 6 +- compiler/rustc_smir/src/stable_mir/ty.rs | 25 ++--- compiler/rustc_symbol_mangling/src/v0.rs | 2 +- .../src/error_reporting/infer/mod.rs | 6 +- .../src/error_reporting/infer/note_and_explain.rs | 2 +- .../src/error_reporting/infer/region.rs | 2 +- .../src/error_reporting/traits/ambiguity.rs | 2 +- .../src/error_reporting/traits/suggestions.rs | 8 +- .../src/traits/dyn_compatibility.rs | 42 +++++---- .../rustc_trait_selection/src/traits/project.rs | 9 +- compiler/rustc_ty_utils/src/assoc.rs | 23 ++--- src/librustdoc/clean/mod.rs | 12 +-- src/librustdoc/clean/types.rs | 2 +- .../clippy/clippy_lints/src/assigning_clones.rs | 4 +- .../src/methods/double_ended_iterator_last.rs | 2 +- .../clippy_lints/src/missing_trait_methods.rs | 2 +- .../clippy/clippy_lints/src/same_name_method.rs | 2 +- .../clippy_lints/src/unconditional_recursion.rs | 2 +- 43 files changed, 276 insertions(+), 231 deletions(-) (limited to 'compiler/rustc_hir_analysis/src') diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 12c36e0f4c2..4f338c6a19e 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -443,7 +443,7 @@ fn best_definition_site_of_opaque<'tcx>( let impl_def_id = tcx.local_parent(parent); for assoc in tcx.associated_items(impl_def_id).in_definition_order() { match assoc.kind { - ty::AssocKind::Const | ty::AssocKind::Fn { .. } => { + ty::AssocKind::Const { .. } | ty::AssocKind::Fn { .. } => { if let ControlFlow::Break(span) = locator.check(assoc.def_id.expect_local()) { return Some(span); @@ -952,7 +952,7 @@ fn check_impl_items_against_trait<'tcx>( .instantiate_identity(), ); } - ty::AssocKind::Const => {} + ty::AssocKind::Const { .. } => {} ty::AssocKind::Type { .. } => {} } } diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index d208aa71971..af26d2ee00c 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -45,7 +45,9 @@ pub(super) fn compare_impl_item( match impl_item.kind { ty::AssocKind::Fn { .. } => compare_impl_method(tcx, impl_item, trait_item, impl_trait_ref), ty::AssocKind::Type { .. } => compare_impl_ty(tcx, impl_item, trait_item, impl_trait_ref), - ty::AssocKind::Const => compare_impl_const(tcx, impl_item, trait_item, impl_trait_ref), + ty::AssocKind::Const { .. } => { + compare_impl_const(tcx, impl_item, trait_item, impl_trait_ref) + } } } @@ -654,7 +656,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( cause.span, E0053, "method `{}` has an incompatible return type for trait", - trait_m.name + trait_m.name() ); infcx.err_ctxt().note_type_err( &mut diag, @@ -1032,7 +1034,7 @@ fn report_trait_method_mismatch<'tcx>( impl_err_span, E0053, "method `{}` has an incompatible type for trait", - trait_m.name + trait_m.name() ); match &terr { TypeError::ArgumentMutability(0) | TypeError::ArgumentSorts(_, 0) @@ -1266,14 +1268,14 @@ fn compare_self_type<'tcx>( impl_m_span, E0185, "method `{}` has a `{}` declaration in the impl, but not in the trait", - trait_m.name, + trait_m.name(), self_descr ); err.span_label(impl_m_span, format!("`{self_descr}` used in impl")); if let Some(span) = tcx.hir_span_if_local(trait_m.def_id) { err.span_label(span, format!("trait method declared without `{self_descr}`")); } else { - err.note_trait_signature(trait_m.name, trait_m.signature(tcx)); + err.note_trait_signature(trait_m.name(), trait_m.signature(tcx)); } return Err(err.emit_unless(delay)); } @@ -1286,14 +1288,14 @@ fn compare_self_type<'tcx>( impl_m_span, E0186, "method `{}` has a `{}` declaration in the trait, but not in the impl", - trait_m.name, + trait_m.name(), self_descr ); err.span_label(impl_m_span, format!("expected `{self_descr}` in impl")); if let Some(span) = tcx.hir_span_if_local(trait_m.def_id) { err.span_label(span, format!("`{self_descr}` used in trait")); } else { - err.note_trait_signature(trait_m.name, trait_m.signature(tcx)); + err.note_trait_signature(trait_m.name(), trait_m.signature(tcx)); } return Err(err.emit_unless(delay)); @@ -1421,7 +1423,7 @@ fn compare_number_of_generics<'tcx>( "{} `{}` has {} {kind} parameter{} but its trait \ declaration has {} {kind} parameter{}", item_kind, - trait_.name, + trait_.name(), impl_count, pluralize!(impl_count), trait_count, @@ -1512,7 +1514,7 @@ fn compare_number_of_method_arguments<'tcx>( impl_span, E0050, "method `{}` has {} but the declaration in trait `{}` has {}", - trait_m.name, + trait_m.name(), potentially_plural_count(impl_number_args, "parameter"), tcx.def_path_str(trait_m.def_id), trait_number_args @@ -1527,7 +1529,7 @@ fn compare_number_of_method_arguments<'tcx>( ), ); } else { - err.note_trait_signature(trait_m.name, trait_m.signature(tcx)); + err.note_trait_signature(trait_m.name(), trait_m.signature(tcx)); } err.span_label( @@ -1581,7 +1583,7 @@ fn compare_synthetic_generics<'tcx>( impl_span, E0643, "method `{}` has incompatible signature for trait", - trait_m.name + trait_m.name() ); err.span_label(trait_span, "declaration in trait here"); if impl_synthetic { @@ -1741,7 +1743,7 @@ fn compare_generic_param_kinds<'tcx>( E0053, "{} `{}` has an incompatible generic parameter for trait `{}`", impl_item.descr(), - trait_item.name, + trait_item.name(), &tcx.def_path_str(tcx.parent(trait_item.def_id)) ); @@ -1877,7 +1879,7 @@ fn compare_const_predicate_entailment<'tcx>( cause.span, E0326, "implemented const `{}` has an incompatible type for trait", - trait_ct.name + trait_ct.name() ); let trait_c_span = trait_ct.def_id.as_local().map(|trait_ct_def_id| { @@ -2237,8 +2239,8 @@ fn param_env_with_gat_bounds<'tcx>( // bounds about themselves. let impl_tys_to_install = match impl_ty.kind { ty::AssocKind::Type { - opt_rpitit_info: - Some( + data: + ty::AssocTypeData::Rpitit( ty::ImplTraitInTraitData::Impl { fn_def_id } | ty::ImplTraitInTraitData::Trait { fn_def_id, .. }, ), diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index ec934b1f620..5fbd771976b 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -205,7 +205,7 @@ fn missing_items_err( let missing_items_msg = missing_items .clone() - .map(|trait_item| trait_item.name.to_string()) + .map(|trait_item| trait_item.name().to_string()) .collect::>() .join("`, `"); @@ -236,7 +236,7 @@ fn missing_items_err( let code = format!("{padding}{snippet}\n{padding}"); if let Some(span) = tcx.hir_span_if_local(trait_item.def_id) { missing_trait_item_label - .push(errors::MissingTraitItemLabel { span, item: trait_item.name }); + .push(errors::MissingTraitItemLabel { span, item: trait_item.name() }); missing_trait_item.push(errors::MissingTraitItemSuggestion { span: sugg_sp, code, @@ -504,9 +504,9 @@ fn suggestion_signature<'tcx>( tcx, tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args), ); - format!("type {}{generics} = /* Type */{where_clauses};", assoc.name) + format!("type {}{generics} = /* Type */{where_clauses};", assoc.name()) } - ty::AssocKind::Const => { + ty::AssocKind::Const { name } => { let ty = tcx.type_of(assoc.def_id).instantiate_identity(); let val = tcx .infer_ctxt() @@ -514,7 +514,7 @@ fn suggestion_signature<'tcx>( .err_ctxt() .ty_kind_suggestion(tcx.param_env(assoc.def_id), ty) .unwrap_or_else(|| "value".to_string()); - format!("const {}: {} = {};", assoc.name, ty, val) + format!("const {}: {} = {};", name, ty, val) } } } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index c6c370c4a84..33d5a86beb3 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -474,7 +474,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) { gat_generics, ) } - ty::AssocKind::Const => None, + ty::AssocKind::Const { .. } => None, }; if let Some(item_required_bounds) = item_required_bounds { @@ -1076,7 +1076,7 @@ fn check_associated_item( }; match item.kind { - ty::AssocKind::Const => { + ty::AssocKind::Const { .. } => { let ty = tcx.type_of(item.def_id).instantiate_identity(); let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty); wfcx.register_wf_obligation(span, loc, ty.into()); diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs index cbfad1f6883..242639125b1 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs @@ -51,7 +51,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> { for &item1 in impl_items1.in_definition_order() { let collision = impl_items2 - .filter_by_name_unhygienic(item1.name) + .filter_by_name_unhygienic(item1.name()) .any(|&item2| self.compare_hygienically(item1, item2)); if collision { @@ -113,7 +113,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> { let mut res = Ok(()); for &item1 in impl_items1.in_definition_order() { let collision = impl_items2 - .filter_by_name_unhygienic(item1.name) + .filter_by_name_unhygienic(item1.name()) .find(|&&item2| self.compare_hygienically(item1, item2)); if let Some(item2) = collision { @@ -230,11 +230,11 @@ impl<'tcx> InherentOverlapChecker<'tcx> { let mut ids = impl_items .in_definition_order() .filter_map(|item| { - let entry = connected_region_ids.entry(item.name); + let entry = connected_region_ids.entry(item.name()); if let IndexEntry::Occupied(e) = &entry { Some(*e.get()) } else { - idents_to_add.push(item.name); + idents_to_add.push(item.name()); None } }) diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index 653adc6b3ba..50e20a19eda 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -32,7 +32,7 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type( for &assoc_id in tcx.associated_item_def_ids(impl_def_id) { let assoc = tcx.associated_item(assoc_id); match assoc.kind { - ty::AssocKind::Const | ty::AssocKind::Fn { .. } => { + ty::AssocKind::Const { .. } | ty::AssocKind::Fn { .. } => { locator.check(assoc_id.expect_local()) } // Associated types don't have bodies, so they can't constrain hidden types diff --git a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs index 70d60bfcf2d..526ee30209c 100644 --- a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs @@ -492,7 +492,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { .gen_args .constraints .iter() - .any(|constraint| constraint.ident.name == item.name) + .any(|constraint| constraint.ident.name == item.name()) }) .filter(|item| !item.is_impl_trait_in_trait()) .map(|item| self.tcx.item_ident(item.def_id).to_string()) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 4f8d5471b6f..72f219bfeb8 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -168,7 +168,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let all_candidate_names: Vec<_> = all_candidates() .flat_map(|r| tcx.associated_items(r.def_id()).in_definition_order()) .filter_map(|item| { - (!item.is_impl_trait_in_trait() && item.as_tag() == assoc_tag).then_some(item.name) + if !item.is_impl_trait_in_trait() && item.as_tag() == assoc_tag { + item.opt_name() + } else { + None + } }) .collect(); @@ -200,7 +204,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .iter() .flat_map(|trait_def_id| tcx.associated_items(*trait_def_id).in_definition_order()) .filter_map(|item| { - (!item.is_impl_trait_in_trait() && item.as_tag() == assoc_tag).then_some(item.name) + (!item.is_impl_trait_in_trait() && item.as_tag() == assoc_tag) + .then_some(item.name()) }) .collect(); @@ -337,7 +342,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ) -> ErrorGuaranteed { let tcx = self.tcx(); - let bound_on_assoc_const_label = if let ty::AssocKind::Const = assoc_item.kind + let bound_on_assoc_const_label = if let ty::AssocKind::Const { .. } = assoc_item.kind && let Some(constraint) = constraint && let hir::AssocItemConstraintKind::Bound { .. } = constraint.kind { @@ -761,7 +766,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // `issue-22560.rs`. let mut dyn_compatibility_violations = Ok(()); for (assoc_item, trait_ref) in &missing_assoc_types { - names.entry(trait_ref).or_default().push(assoc_item.name); + names.entry(trait_ref).or_default().push(assoc_item.name()); names_len += 1; let violations = @@ -852,16 +857,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let mut names: UnordMap<_, usize> = Default::default(); for (item, _) in &missing_assoc_types { types_count += 1; - *names.entry(item.name).or_insert(0) += 1; + *names.entry(item.name()).or_insert(0) += 1; } let mut dupes = false; let mut shadows = false; for (item, trait_ref) in &missing_assoc_types { - let prefix = if names[&item.name] > 1 { + let name = item.name(); + let prefix = if names[&name] > 1 { let trait_def_id = trait_ref.def_id(); dupes = true; format!("{}::", tcx.def_path_str(trait_def_id)) - } else if bound_names.get(&item.name).is_some_and(|x| *x != item) { + } else if bound_names.get(&name).is_some_and(|x| *x != item) { let trait_def_id = trait_ref.def_id(); shadows = true; format!("{}::", tcx.def_path_str(trait_def_id)) @@ -871,7 +877,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let mut is_shadowed = false; - if let Some(assoc_item) = bound_names.get(&item.name) + if let Some(assoc_item) = bound_names.get(&name) && *assoc_item != item { is_shadowed = true; @@ -880,17 +886,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if assoc_item.def_id.is_local() { ", consider renaming it" } else { "" }; err.span_label( tcx.def_span(assoc_item.def_id), - format!("`{}{}` shadowed here{}", prefix, item.name, rename_message), + format!("`{}{}` shadowed here{}", prefix, name, rename_message), ); } let rename_message = if is_shadowed { ", consider renaming it" } else { "" }; if let Some(sp) = tcx.hir_span_if_local(item.def_id) { - err.span_label( - sp, - format!("`{}{}` defined here{}", prefix, item.name, rename_message), - ); + err.span_label(sp, format!("`{}{}` defined here{}", prefix, name, rename_message)); } } if potential_assoc_types.len() == missing_assoc_types.len() { @@ -903,7 +906,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { { let types: Vec<_> = missing_assoc_types .iter() - .map(|(item, _)| format!("{} = Type", item.name)) + .map(|(item, _)| format!("{} = Type", item.name())) .collect(); let code = if let Some(snippet) = snippet.strip_suffix('>') { // The user wrote `Trait<'a>` or similar and we don't have a type we can @@ -938,16 +941,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let mut names: FxIndexMap<_, usize> = FxIndexMap::default(); for (item, _) in &missing_assoc_types { types_count += 1; - *names.entry(item.name).or_insert(0) += 1; + *names.entry(item.name()).or_insert(0) += 1; } let mut label = vec![]; for (item, trait_ref) in &missing_assoc_types { - let postfix = if names[&item.name] > 1 { + let name = item.name(); + let postfix = if names[&name] > 1 { format!(" (from trait `{}`)", trait_ref.print_trait_sugared()) } else { String::new() }; - label.push(format!("`{}`{}", item.name, postfix)); + label.push(format!("`{}`{}", name, postfix)); } if !label.is_empty() { err.span_label( diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index 49fd55b03a2..483b61add33 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -502,7 +502,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .associated_items(trait_def_id) .in_definition_order() .filter(|assoc| assoc.namespace() == Namespace::ValueNS) - .map(|cand| cand.name) + .map(|cand| cand.name()) .collect(); if let Some(typo) = find_best_match_for_name(&names, segment.ident.name, None) { diag.span_suggestion_verbose( diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 127ca846b9f..cbdc501291b 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -119,7 +119,7 @@ pub(crate) fn enforce_impl_lifetime_params_are_constrained( vec![] } } - ty::AssocKind::Fn { .. } | ty::AssocKind::Const => vec![], + ty::AssocKind::Fn { .. } | ty::AssocKind::Const { .. } => vec![], } }) .collect(); diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 56c205b6f87..532c5092a4e 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2601,8 +2601,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return None; } let input_len = fn_sig.inputs().skip_binder().len(); - let order = !item.name.as_str().starts_with("new"); - Some((order, item.name, input_len)) + let name = item.name(); + let order = !name.as_str().starts_with("new"); + Some((order, name, input_len)) }) .collect::>(); items.sort_by_key(|(order, _, _)| *order); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 3a0f3a4a5f0..da0e8e362d6 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -683,10 +683,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .all(|(expected, found)| self.may_coerce(*expected, *found)) && fn_sig.inputs()[1..].len() == input_types.len() { + let assoc_name = assoc.name(); err.span_suggestion_verbose( call_name.span, - format!("you might have meant to use `{}`", assoc.name), - assoc.name, + format!("you might have meant to use `{}`", assoc_name), + assoc_name, Applicability::MaybeIncorrect, ); return; @@ -706,7 +707,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { tcx.def_span(assoc.def_id), format!( "there's is a method with similar name `{}`, but the arguments don't match", - assoc.name, + assoc.name(), ), ); return; @@ -718,7 +719,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!( "there's is a method with similar name `{}`, but their argument count \ doesn't match", - assoc.name, + assoc.name(), ), ); return; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 912098c4e2d..91eb1989864 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -381,9 +381,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut suggestions = methods .iter() .filter_map(|conversion_method| { + let conversion_method_name = conversion_method.name(); let receiver_method_ident = expr.method_ident(); if let Some(method_ident) = receiver_method_ident - && method_ident.name == conversion_method.name + && method_ident.name == conversion_method_name { return None; // do not suggest code that is already there (#53348) } @@ -391,20 +392,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let method_call_list = [sym::to_vec, sym::to_string]; let mut sugg = if let ExprKind::MethodCall(receiver_method, ..) = expr.kind && receiver_method.ident.name == sym::clone - && method_call_list.contains(&conversion_method.name) + && method_call_list.contains(&conversion_method_name) // If receiver is `.clone()` and found type has one of those methods, // we guess that the user wants to convert from a slice type (`&[]` or `&str`) // to an owned type (`Vec` or `String`). These conversions clone internally, // so we remove the user's `clone` call. { - vec![(receiver_method.ident.span, conversion_method.name.to_string())] + vec![(receiver_method.ident.span, conversion_method_name.to_string())] } else if expr.precedence() < ExprPrecedence::Unambiguous { vec![ (expr.span.shrink_to_lo(), "(".to_string()), - (expr.span.shrink_to_hi(), format!(").{}()", conversion_method.name)), + (expr.span.shrink_to_hi(), format!(").{}()", conversion_method_name)), ] } else { - vec![(expr.span.shrink_to_hi(), format!(".{}()", conversion_method.name))] + vec![(expr.span.shrink_to_hi(), format!(".{}()", conversion_method_name))] }; let struct_pat_shorthand_field = self.tcx.hir_maybe_get_struct_pattern_shorthand_field(expr); diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 1d86ff14471..0c6240d1f74 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -266,7 +266,7 @@ fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Opti let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer(()), span, .. }) = node.ty() { if let Some(item) = tcx.opt_associated_item(def_id.into()) - && let ty::AssocKind::Const = item.kind + && let ty::AssocKind::Const { .. } = item.kind && let ty::AssocItemContainer::Impl = item.container && let Some(trait_item_def_id) = item.trait_item_def_id { diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index c14b7823e37..ba4396a5ab3 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1671,7 +1671,7 @@ impl<'tcx> Pick<'tcx> { /// Do not use for type checking. pub(crate) fn differs_from(&self, other: &Self) -> bool { let Self { - item: AssocItem { def_id, name: _, kind: _, container: _, trait_item_def_id: _ }, + item: AssocItem { def_id, kind: _, container: _, trait_item_def_id: _ }, kind: _, import_ids: _, autoderefs: _, @@ -1714,17 +1714,12 @@ impl<'tcx> Pick<'tcx> { tcx.def_path_str(self.item.def_id), )); } - (ty::AssocKind::Const, ty::AssocItemContainer::Trait) => { + (ty::AssocKind::Const { name }, ty::AssocItemContainer::Trait) => { let def_id = self.item.container_id(tcx); lint.span_suggestion( span, "use the fully qualified path to the associated const", - format!( - "<{} as {}>::{}", - self.self_ty, - tcx.def_path_str(def_id), - self.item.name - ), + format!("<{} as {}>::{}", self.self_ty, tcx.def_path_str(def_id), name), Applicability::MachineApplicable, ); } @@ -2213,7 +2208,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let best_name = { let names = applicable_close_candidates .iter() - .map(|cand| cand.name) + .map(|cand| cand.name()) .collect::>(); find_best_match_for_name_with_substrings( &names, @@ -2225,10 +2220,12 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { applicable_close_candidates .iter() .find(|cand| self.matches_by_doc_alias(cand.def_id)) - .map(|cand| cand.name) + .map(|cand| cand.name()) }); Ok(best_name.and_then(|best_name| { - applicable_close_candidates.into_iter().find(|method| method.name == best_name) + applicable_close_candidates + .into_iter() + .find(|method| method.name() == best_name) })) } }) @@ -2246,7 +2243,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { Mode::MethodCall => item.is_method(), Mode::Path => match item.kind { ty::AssocKind::Type { .. } => false, - ty::AssocKind::Fn { .. } | ty::AssocKind::Const => true, + ty::AssocKind::Fn { .. } | ty::AssocKind::Const { .. } => true, }, } // FIXME -- check for types that deref to `Self`, @@ -2320,7 +2317,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { fn is_relevant_kind_for_mode(&self, kind: ty::AssocKind) -> bool { match (self.mode, kind) { (Mode::MethodCall, ty::AssocKind::Fn { .. }) => true, - (Mode::Path, ty::AssocKind::Const | ty::AssocKind::Fn { .. }) => true, + (Mode::Path, ty::AssocKind::Const { .. } | ty::AssocKind::Fn { .. }) => true, _ => false, } } @@ -2402,7 +2399,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } match edit_distance_with_substrings( name.as_str(), - x.name.as_str(), + x.name().as_str(), max_dist, ) { Some(d) => d > 0, diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 962871ed2d1..6a9fd7cdd48 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1722,7 +1722,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // that had unsatisfied trait bounds if unsatisfied_predicates.is_empty() // ...or if we already suggested that name because of `rustc_confusable` annotation. - && Some(similar_candidate.name) != confusable_suggested + && Some(similar_candidate.name()) != confusable_suggested { self.find_likely_intended_associated_item( &mut err, @@ -1821,10 +1821,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let tcx = self.tcx; let def_kind = similar_candidate.as_def_kind(); let an = self.tcx.def_kind_descr_article(def_kind, similar_candidate.def_id); + let similar_candidate_name = similar_candidate.name(); let msg = format!( "there is {an} {} `{}` with a similar name", self.tcx.def_kind_descr(def_kind, similar_candidate.def_id), - similar_candidate.name, + similar_candidate_name, ); // Methods are defined within the context of a struct and their first parameter // is always `self`, which represents the instance of the struct the method is @@ -1843,7 +1844,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion_verbose( span, msg, - similar_candidate.name, + similar_candidate_name, Applicability::MaybeIncorrect, ); } else { @@ -1865,7 +1866,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion_verbose( span, msg, - similar_candidate.name, + similar_candidate_name, Applicability::MaybeIncorrect, ); } else { @@ -1878,7 +1879,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion_verbose( span, msg, - similar_candidate.name, + similar_candidate_name, Applicability::MaybeIncorrect, ); } else { @@ -1918,6 +1919,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { infer::FnCall, fn_sig, ); + let name = inherent_method.name(); if let Some(ref args) = call_args && fn_sig.inputs()[1..] .iter() @@ -1927,20 +1929,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { err.span_suggestion_verbose( item_name.span, - format!("you might have meant to use `{}`", inherent_method.name), - inherent_method.name, + format!("you might have meant to use `{}`", name), + name, Applicability::MaybeIncorrect, ); - return Some(inherent_method.name); + return Some(name); } else if let None = call_args { err.span_note( self.tcx.def_span(inherent_method.def_id), - format!( - "you might have meant to use method `{}`", - inherent_method.name, - ), + format!("you might have meant to use method `{}`", name), ); - return Some(inherent_method.name); + return Some(name); } } } @@ -2116,7 +2115,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Only assoc fn with no receivers and only if // they are resolvable .filter(|item| { - matches!(item.kind, ty::AssocKind::Fn { has_self: false }) + matches!(item.kind, ty::AssocKind::Fn { has_self: false, .. }) && self .probe_for_name( Mode::Path, diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index 93f77b8409f..0e42a84ca32 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -372,7 +372,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .associated_item_def_ids(def_id) .iter() .find(|item_def_id| { - self.tcx.associated_item(*item_def_id).name == sym::Output + self.tcx.associated_item(*item_def_id).name() == sym::Output }) .cloned() }); diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 3cbe09280f6..3c2245347f9 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1332,30 +1332,26 @@ impl<'a> CrateMetadataRef<'a> { } fn get_associated_item(self, id: DefIndex, sess: &'a Session) -> ty::AssocItem { - let name = if self.root.tables.opt_rpitit_info.get(self, id).is_some() { - kw::Empty - } else { - self.item_name(id) - }; let kind = match self.def_kind(id) { - DefKind::AssocConst => ty::AssocKind::Const, - DefKind::AssocFn => { - ty::AssocKind::Fn { has_self: self.get_fn_has_self_parameter(id, sess) } - } - DefKind::AssocTy => ty::AssocKind::Type { - opt_rpitit_info: self - .root - .tables - .opt_rpitit_info - .get(self, id) - .map(|d| d.decode(self)), + DefKind::AssocConst => ty::AssocKind::Const { name: self.item_name(id) }, + DefKind::AssocFn => ty::AssocKind::Fn { + name: self.item_name(id), + has_self: self.get_fn_has_self_parameter(id, sess), }, + DefKind::AssocTy => { + let data = if let Some(rpitit_info) = self.root.tables.opt_rpitit_info.get(self, id) + { + ty::AssocTypeData::Rpitit(rpitit_info.decode(self)) + } else { + ty::AssocTypeData::Normal(self.item_name(id)) + }; + ty::AssocKind::Type { data } + } _ => bug!("cannot get associated-item of `{:?}`", self.def_key(id)), }; let container = self.root.tables.assoc_container.get(self, id).unwrap(); ty::AssocItem { - name, kind, def_id: self.local_def_id(id), trait_item_def_id: self.get_trait_item_def_id(id), diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index b900100c3c0..177318bfe15 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1706,7 +1706,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } } - if let ty::AssocKind::Type { opt_rpitit_info: Some(rpitit_info) } = item.kind { + if let ty::AssocKind::Type { data: ty::AssocTypeData::Rpitit(rpitit_info) } = item.kind { record!(self.tables.opt_rpitit_info[def_id] <- rpitit_info); if matches!(rpitit_info, ty::ImplTraitInTraitData::Trait { .. }) { record_array!( diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index 6138157d836..0c44fd2758d 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -18,7 +18,6 @@ pub enum AssocItemContainer { #[derive(Copy, Clone, Debug, PartialEq, HashStable, Eq, Hash, Encodable, Decodable)] pub struct AssocItem { pub def_id: DefId, - pub name: Symbol, pub kind: AssocKind, pub container: AssocItemContainer, @@ -28,8 +27,24 @@ pub struct AssocItem { } impl AssocItem { + // Gets the identifier, if it has one. + pub fn opt_name(&self) -> Option { + match self.kind { + ty::AssocKind::Type { data: AssocTypeData::Normal(name) } => Some(name), + ty::AssocKind::Type { data: AssocTypeData::Rpitit(_) } => None, + ty::AssocKind::Const { name } => Some(name), + ty::AssocKind::Fn { name, .. } => Some(name), + } + } + + // Gets the identifier name. Aborts if it lacks one, i.e. is an RPITIT + // associated type. + pub fn name(&self) -> Symbol { + self.opt_name().expect("name of non-Rpitit assoc item") + } + pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident { - Ident::new(self.name, tcx.def_ident_span(self.def_id).unwrap()) + Ident::new(self.name(), tcx.def_ident_span(self.def_id).unwrap()) } /// Gets the defaultness of the associated item. @@ -76,22 +91,18 @@ impl AssocItem { // regions just fine, showing `fn(&MyType)`. tcx.fn_sig(self.def_id).instantiate_identity().skip_binder().to_string() } - ty::AssocKind::Type { .. } => format!("type {};", self.name), - ty::AssocKind::Const => { - format!( - "const {}: {:?};", - self.name, - tcx.type_of(self.def_id).instantiate_identity() - ) + ty::AssocKind::Type { .. } => format!("type {};", self.name()), + ty::AssocKind::Const { name } => { + format!("const {}: {:?};", name, tcx.type_of(self.def_id).instantiate_identity()) } } } pub fn descr(&self) -> &'static str { match self.kind { - ty::AssocKind::Const => "associated const", - ty::AssocKind::Fn { has_self: true } => "method", - ty::AssocKind::Fn { has_self: false } => "associated function", + ty::AssocKind::Const { .. } => "associated const", + ty::AssocKind::Fn { has_self: true, .. } => "method", + ty::AssocKind::Fn { has_self: false, .. } => "associated function", ty::AssocKind::Type { .. } => "associated type", } } @@ -99,13 +110,13 @@ impl AssocItem { pub fn namespace(&self) -> Namespace { match self.kind { ty::AssocKind::Type { .. } => Namespace::TypeNS, - ty::AssocKind::Const | ty::AssocKind::Fn { .. } => Namespace::ValueNS, + ty::AssocKind::Const { .. } | ty::AssocKind::Fn { .. } => Namespace::ValueNS, } } pub fn as_def_kind(&self) -> DefKind { match self.kind { - AssocKind::Const => DefKind::AssocConst, + AssocKind::Const { .. } => DefKind::AssocConst, AssocKind::Fn { .. } => DefKind::AssocFn, AssocKind::Type { .. } => DefKind::AssocTy, } @@ -119,19 +130,19 @@ impl AssocItem { } pub fn is_method(&self) -> bool { - matches!(self.kind, ty::AssocKind::Fn { has_self: true }) + matches!(self.kind, ty::AssocKind::Fn { has_self: true, .. }) } pub fn as_tag(&self) -> AssocTag { match self.kind { - AssocKind::Const => AssocTag::Const, + AssocKind::Const { .. } => AssocTag::Const, AssocKind::Fn { .. } => AssocTag::Fn, AssocKind::Type { .. } => AssocTag::Type, } } pub fn is_impl_trait_in_trait(&self) -> bool { - matches!(self.kind, AssocKind::Type { opt_rpitit_info: Some(_) }) + matches!(self.kind, AssocKind::Type { data: AssocTypeData::Rpitit(_) }) } /// Returns true if: @@ -139,7 +150,7 @@ impl AssocItem { /// - If it is in a trait impl, the item from the original trait has this attribute, or /// - It is an inherent assoc const. pub fn is_type_const_capable(&self, tcx: TyCtxt<'_>) -> bool { - if self.kind != ty::AssocKind::Const { + if !matches!(self.kind, ty::AssocKind::Const { .. }) { return false; } @@ -153,26 +164,45 @@ impl AssocItem { } } +#[derive(Copy, Clone, PartialEq, Debug, HashStable, Eq, Hash, Encodable, Decodable)] +pub enum AssocTypeData { + Normal(Symbol), + /// The associated type comes from an RPITIT. It has no name, and the + /// `ImplTraitInTraitData` provides additional information about its + /// source. + Rpitit(ty::ImplTraitInTraitData), +} + #[derive(Copy, Clone, PartialEq, Debug, HashStable, Eq, Hash, Encodable, Decodable)] pub enum AssocKind { - Const, - Fn { - has_self: bool, - }, - Type { - /// `Some` if the associated type comes from an RPITIT. The - /// `ImplTraitInTraitData` provides additional information about its - /// source. - opt_rpitit_info: Option, - }, + Const { name: Symbol }, + Fn { name: Symbol, has_self: bool }, + Type { data: AssocTypeData }, +} + +impl AssocKind { + pub fn namespace(&self) -> Namespace { + match *self { + ty::AssocKind::Type { .. } => Namespace::TypeNS, + ty::AssocKind::Const { .. } | ty::AssocKind::Fn { .. } => Namespace::ValueNS, + } + } + + pub fn as_def_kind(&self) -> DefKind { + match self { + AssocKind::Const { .. } => DefKind::AssocConst, + AssocKind::Fn { .. } => DefKind::AssocFn, + AssocKind::Type { .. } => DefKind::AssocTy, + } + } } impl std::fmt::Display for AssocKind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - AssocKind::Fn { has_self: true } => write!(f, "method"), - AssocKind::Fn { has_self: false } => write!(f, "associated function"), - AssocKind::Const => write!(f, "associated const"), + AssocKind::Fn { has_self: true, .. } => write!(f, "method"), + AssocKind::Fn { has_self: false, .. } => write!(f, "associated function"), + AssocKind::Const { .. } => write!(f, "associated const"), AssocKind::Type { .. } => write!(f, "associated type"), } } @@ -193,17 +223,17 @@ pub enum AssocTag { /// done only on items with the same name. #[derive(Debug, Clone, PartialEq, HashStable)] pub struct AssocItems { - items: SortedIndexMultiMap, + items: SortedIndexMultiMap, ty::AssocItem>, } impl AssocItems { /// Constructs an `AssociatedItems` map from a series of `ty::AssocItem`s in definition order. pub fn new(items_in_def_order: impl IntoIterator) -> Self { - let items = items_in_def_order.into_iter().map(|item| (item.name, item)).collect(); + let items = items_in_def_order.into_iter().map(|item| (item.opt_name(), item)).collect(); AssocItems { items } } - /// Returns a slice of associated items in the order they were defined. + /// Returns an iterator over associated items in the order they were defined. /// /// New code should avoid relying on definition order. If you need a particular associated item /// for a known trait, make that trait a lang item instead of indexing this array. @@ -220,7 +250,8 @@ impl AssocItems { &self, name: Symbol, ) -> impl '_ + Iterator { - self.items.get_by_key(name) + assert!(!name.is_empty()); + self.items.get_by_key(Some(name)) } /// Returns the associated item with the given identifier and `AssocKind`, if one exists. diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 395d2ec4814..1945538b1c2 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1611,9 +1611,10 @@ impl<'tcx> TyCtxt<'tcx> { /// about where that RPITIT came from. pub fn opt_rpitit_info(self, def_id: DefId) -> Option { if let DefKind::AssocTy = self.def_kind(def_id) - && let AssocKind::Type { opt_rpitit_info } = self.associated_item(def_id).kind + && let AssocKind::Type { data: AssocTypeData::Rpitit(rpitit_info) } = + self.associated_item(def_id).kind { - opt_rpitit_info + Some(rpitit_info) } else { None } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 2f93197bcef..d739218af5e 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1214,7 +1214,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { && assoc .trait_container(tcx) .is_some_and(|def_id| tcx.is_lang_item(def_id, LangItem::Coroutine)) - && assoc.name == rustc_span::sym::Return + && assoc.opt_name() == Some(rustc_span::sym::Return) { if let ty::Coroutine(_, args) = args.type_at(0).kind() { let return_ty = args.as_coroutine().return_ty(); @@ -1237,7 +1237,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { p!(", "); } - p!(write("{} = ", tcx.associated_item(assoc_item_def_id).name)); + p!(write("{} = ", tcx.associated_item(assoc_item_def_id).name())); match term.unpack() { TermKind::Ty(ty) => p!(print(ty)), @@ -3291,7 +3291,7 @@ define_print! { } ty::ExistentialProjection<'tcx> { - let name = cx.tcx().associated_item(self.def_id).name; + let name = cx.tcx().associated_item(self.def_id).name(); // The args don't contain the self ty (as it has been erased) but the corresp. // generics do as the trait always has a self ty param. We need to offset. let args = &self.args[cx.tcx().generics_of(self.def_id).parent_count - 1..]; diff --git a/compiler/rustc_mir_transform/src/check_undefined_transmutes.rs b/compiler/rustc_mir_transform/src/check_undefined_transmutes.rs index ed3b1ae4f42..daddb5dedbc 100644 --- a/compiler/rustc_mir_transform/src/check_undefined_transmutes.rs +++ b/compiler/rustc_mir_transform/src/check_undefined_transmutes.rs @@ -42,7 +42,7 @@ impl<'a, 'tcx> UndefinedTransmutesChecker<'a, 'tcx> { if self.tcx.is_const_fn(def_id) || matches!( self.tcx.opt_associated_item(def_id), - Some(AssocItem { kind: AssocKind::Const, .. }) + Some(AssocItem { kind: AssocKind::Const { .. }, .. }) ) { let fn_sig = function.ty(self.body, self.tcx).fn_sig(self.tcx).skip_binder(); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index ae81021e0be..d4fe446cc9f 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -2007,8 +2007,9 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { if def.did() != def_id { return None; } - let order = !item.name.as_str().starts_with("new"); - Some((order, item.name, input_len)) + let name = item.name(); + let order = !name.as_str().starts_with("new"); + Some((order, name, input_len)) }) .collect::>(); items.sort_by_key(|(order, _, _)| *order); diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index 55f698b8f21..a757329bcf2 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -895,12 +895,19 @@ impl<'tcx> Stable<'tcx> for ty::AssocKind { type T = stable_mir::ty::AssocKind; fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - use stable_mir::ty::AssocKind; + use stable_mir::ty::{AssocKind, AssocTypeData}; match *self { - ty::AssocKind::Const => AssocKind::Const, - ty::AssocKind::Fn { has_self } => AssocKind::Fn { has_self }, - ty::AssocKind::Type { opt_rpitit_info } => AssocKind::Type { - opt_rpitit_info: opt_rpitit_info.map(|rpitit| rpitit.stable(tables)), + ty::AssocKind::Const { name } => AssocKind::Const { name: name.to_string() }, + ty::AssocKind::Fn { name, has_self } => { + AssocKind::Fn { name: name.to_string(), has_self } + } + ty::AssocKind::Type { data } => AssocKind::Type { + data: match data { + ty::AssocTypeData::Normal(name) => AssocTypeData::Normal(name.to_string()), + ty::AssocTypeData::Rpitit(rpitit) => { + AssocTypeData::Rpitit(rpitit.stable(tables)) + } + }, }, } } @@ -924,7 +931,6 @@ impl<'tcx> Stable<'tcx> for ty::AssocItem { fn stable(&self, tables: &mut Tables<'_>) -> Self::T { stable_mir::ty::AssocItem { def_id: tables.assoc_def(self.def_id), - name: self.name.to_string(), kind: self.kind.stable(tables), container: self.container.stable(tables), trait_item_def_id: self.trait_item_def_id.map(|did| tables.assoc_def(did)), diff --git a/compiler/rustc_smir/src/stable_mir/mir/pretty.rs b/compiler/rustc_smir/src/stable_mir/mir/pretty.rs index 9fa97763907..8a6be0cd37a 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/pretty.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/pretty.rs @@ -22,9 +22,9 @@ impl Display for Ty { impl Display for AssocKind { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { - AssocKind::Fn { has_self: true } => write!(f, "method"), - AssocKind::Fn { has_self: false } => write!(f, "associated function"), - AssocKind::Const => write!(f, "associated const"), + AssocKind::Fn { has_self: true, .. } => write!(f, "method"), + AssocKind::Fn { has_self: false, .. } => write!(f, "associated function"), + AssocKind::Const { .. } => write!(f, "associated const"), AssocKind::Type { .. } => write!(f, "associated type"), } } diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs index 6eac0885d76..4b153007bd8 100644 --- a/compiler/rustc_smir/src/stable_mir/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/ty.rs @@ -1578,7 +1578,6 @@ crate_def! { #[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct AssocItem { pub def_id: AssocDef, - pub name: Symbol, pub kind: AssocKind, pub container: AssocItemContainer, @@ -1587,18 +1586,20 @@ pub struct AssocItem { pub trait_item_def_id: Option, } +#[derive(Clone, PartialEq, Debug, Eq, Serialize)] +pub enum AssocTypeData { + Normal(Symbol), + /// The associated type comes from an RPITIT. It has no name, and the + /// `ImplTraitInTraitData` provides additional information about its + /// source. + Rpitit(ImplTraitInTraitData), +} + #[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum AssocKind { - Const, - Fn { - has_self: bool, - }, - Type { - /// `Some` if the associated type comes from an RPITIT. The - /// `ImplTraitInTraitData` provides additional information about its - /// source. - opt_rpitit_info: Option, - }, + Const { name: Symbol }, + Fn { name: Symbol, has_self: bool }, + Type { data: AssocTypeData }, } #[derive(Clone, Debug, Eq, PartialEq, Serialize)] @@ -1615,6 +1616,6 @@ pub enum ImplTraitInTraitData { impl AssocItem { pub fn is_impl_trait_in_trait(&self) -> bool { - matches!(self.kind, AssocKind::Type { opt_rpitit_info: Some(_) }) + matches!(self.kind, AssocKind::Type { data: AssocTypeData::Rpitit(_) }) } } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index d28f10ba9e3..a4e1266e764 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -615,7 +615,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { cx.print_def_path(trait_ref.def_id, trait_ref.args)?; } ty::ExistentialPredicate::Projection(projection) => { - let name = cx.tcx.associated_item(projection.def_id).name; + let name = cx.tcx.associated_item(projection.def_id).name(); cx.push("p"); cx.push_ident(name.as_str()); match projection.term.unpack() { diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 1c71fe028d4..fdd547448f0 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -2340,7 +2340,7 @@ impl<'tcx> ObligationCause<'tcx> { ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Type { .. }, .. } => { ObligationCauseFailureCode::TypeCompat { span, subdiags } } - ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Const, .. } => { + ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Const { .. }, .. } => { ObligationCauseFailureCode::ConstCompat { span, subdiags } } ObligationCauseCode::BlockTailExpression(.., hir::MatchSource::TryDesugar(_)) => { @@ -2404,7 +2404,7 @@ impl<'tcx> ObligationCause<'tcx> { ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Type { .. }, .. } => { "associated type is compatible with trait" } - ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Const, .. } => { + ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Const { .. }, .. } => { "const is compatible with trait" } ObligationCauseCode::MainFunctionType => "`main` function has the correct type", @@ -2428,7 +2428,7 @@ impl IntoDiagArg for ObligationCauseAsDiagArg<'_> { ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Type { .. }, .. } => { "type_compat" } - ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Const, .. } => { + ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Const { .. }, .. } => { "const_compat" } ObligationCauseCode::MainFunctionType => "fn_main_correct_type", diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs index 02f21b5465c..be508c8cee1 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs @@ -783,7 +783,7 @@ fn foo(&self) -> Self::T { String::new() } .in_definition_order() .filter(|item| { item.is_fn() - && Some(item.name) != current_method_ident + && Some(item.name()) != current_method_ident && !tcx.is_doc_hidden(item.def_id) }) .filter_map(|item| { diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index 49c6acedcfa..df3cce880dd 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -1017,7 +1017,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { infer::BoundRegion(_, br, infer::AssocTypeProjection(def_id)) => format!( " for lifetime parameter {}in trait containing associated type `{}`", br_string(br), - self.tcx.associated_item(def_id).name + self.tcx.associated_item(def_id).name() ), infer::RegionParameterDefinition(_, name) => { format!(" for lifetime parameter `{name}`") diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index c4b0ca9cf8f..54b50851b74 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -348,7 +348,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { && let None = self.tainted_by_errors() { let (verb, noun) = match self.tcx.associated_item(item_id).kind { - ty::AssocKind::Const => ("refer to the", "constant"), + ty::AssocKind::Const { .. } => ("refer to the", "constant"), ty::AssocKind::Fn { .. } => ("call", "function"), // This is already covered by E0223, but this following single match // arm doesn't hurt here. diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 08b95b45058..7d95a7b3fed 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -2112,7 +2112,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { trait_ref: DefId, ) { if let Some(assoc_item) = self.tcx.opt_associated_item(item_def_id) { - if let ty::AssocKind::Const | ty::AssocKind::Type { .. } = assoc_item.kind { + if let ty::AssocKind::Const { .. } | ty::AssocKind::Type { .. } = assoc_item.kind { err.note(format!( "{}s cannot be accessed directly on a `trait`, they can only be \ accessed through a specific `impl`", @@ -2121,7 +2121,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err.span_suggestion( span, "use the fully qualified path to an implementation", - format!("::{}", self.tcx.def_path_str(trait_ref), assoc_item.name), + format!( + "::{}", + self.tcx.def_path_str(trait_ref), + assoc_item.name() + ), Applicability::HasPlaceholders, ); } diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index 1ef16f34702..519394685a8 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -298,31 +298,33 @@ pub fn dyn_compatibility_violations_for_assoc_item( match item.kind { // Associated consts are never dyn-compatible, as they can't have `where` bounds yet at all, // and associated const bounds in trait objects aren't a thing yet either. - ty::AssocKind::Const => { - vec![DynCompatibilityViolation::AssocConst(item.name, item.ident(tcx).span)] + ty::AssocKind::Const { name } => { + vec![DynCompatibilityViolation::AssocConst(name, item.ident(tcx).span)] } - ty::AssocKind::Fn { .. } => virtual_call_violations_for_method(tcx, trait_def_id, item) - .into_iter() - .map(|v| { - let node = tcx.hir_get_if_local(item.def_id); - // Get an accurate span depending on the violation. - let span = match (&v, node) { - (MethodViolationCode::ReferencesSelfInput(Some(span)), _) => *span, - (MethodViolationCode::UndispatchableReceiver(Some(span)), _) => *span, - (MethodViolationCode::ReferencesImplTraitInTrait(span), _) => *span, - (MethodViolationCode::ReferencesSelfOutput, Some(node)) => { - node.fn_decl().map_or(item.ident(tcx).span, |decl| decl.output.span()) - } - _ => item.ident(tcx).span, - }; + ty::AssocKind::Fn { name, .. } => { + virtual_call_violations_for_method(tcx, trait_def_id, item) + .into_iter() + .map(|v| { + let node = tcx.hir_get_if_local(item.def_id); + // Get an accurate span depending on the violation. + let span = match (&v, node) { + (MethodViolationCode::ReferencesSelfInput(Some(span)), _) => *span, + (MethodViolationCode::UndispatchableReceiver(Some(span)), _) => *span, + (MethodViolationCode::ReferencesImplTraitInTrait(span), _) => *span, + (MethodViolationCode::ReferencesSelfOutput, Some(node)) => { + node.fn_decl().map_or(item.ident(tcx).span, |decl| decl.output.span()) + } + _ => item.ident(tcx).span, + }; - DynCompatibilityViolation::Method(item.name, v, span) - }) - .collect(), + DynCompatibilityViolation::Method(name, v, span) + }) + .collect() + } // Associated types can only be dyn-compatible if they have `Self: Sized` bounds. ty::AssocKind::Type { .. } => { if !tcx.generics_of(item.def_id).is_own_empty() && !item.is_impl_trait_in_trait() { - vec![DynCompatibilityViolation::GAT(item.name, item.ident(tcx).span)] + vec![DynCompatibilityViolation::GAT(item.name(), item.ident(tcx).span)] } else { // We will permit associated types if they are explicitly mentioned in the trait object. // We can't check this here, as here we only check if it is guaranteed to not be possible. diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 83591219b14..0dce504903c 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1393,7 +1393,7 @@ fn confirm_future_candidate<'cx, 'tcx>( coroutine_sig, ); - debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name, sym::Output); + debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name(), sym::Output); let predicate = ty::ProjectionPredicate { projection_term: ty::AliasTerm::new_from_args( @@ -1439,7 +1439,7 @@ fn confirm_iterator_candidate<'cx, 'tcx>( gen_sig, ); - debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name, sym::Item); + debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name(), sym::Item); let predicate = ty::ProjectionPredicate { projection_term: ty::AliasTerm::new_from_args( @@ -1485,7 +1485,7 @@ fn confirm_async_iterator_candidate<'cx, 'tcx>( gen_sig, ); - debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name, sym::Item); + debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name(), sym::Item); let ty::Adt(_poll_adt, args) = *yield_ty.kind() else { bug!(); @@ -2005,7 +2005,8 @@ fn confirm_impl_candidate<'cx, 'tcx>( if !assoc_ty.item.defaultness(tcx).has_value() { debug!( "confirm_impl_candidate: no associated type {:?} for {:?}", - assoc_ty.item.name, obligation.predicate + assoc_ty.item.name(), + obligation.predicate ); if tcx.impl_self_is_guaranteed_unsized(impl_def_id) { // We treat this projection as rigid here, which is represented via diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 2275fbb9792..6cb9fdc6f93 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -6,7 +6,6 @@ use rustc_hir::{self as hir, AmbigArg}; use rustc_middle::query::Providers; use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt}; use rustc_middle::{bug, span_bug}; -use rustc_span::kw; pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { @@ -129,14 +128,14 @@ fn associated_item(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AssocItem { fn associated_item_from_trait_item_ref(trait_item_ref: &hir::TraitItemRef) -> ty::AssocItem { let owner_id = trait_item_ref.id.owner_id; + let name = trait_item_ref.ident.name; let kind = match trait_item_ref.kind { - hir::AssocItemKind::Const => ty::AssocKind::Const, - hir::AssocItemKind::Fn { has_self } => ty::AssocKind::Fn { has_self }, - hir::AssocItemKind::Type => ty::AssocKind::Type { opt_rpitit_info: None }, + hir::AssocItemKind::Const => ty::AssocKind::Const { name }, + hir::AssocItemKind::Fn { has_self } => ty::AssocKind::Fn { name, has_self }, + hir::AssocItemKind::Type => ty::AssocKind::Type { data: ty::AssocTypeData::Normal(name) }, }; ty::AssocItem { - name: trait_item_ref.ident.name, kind, def_id: owner_id.to_def_id(), trait_item_def_id: Some(owner_id.to_def_id()), @@ -146,14 +145,14 @@ fn associated_item_from_trait_item_ref(trait_item_ref: &hir::TraitItemRef) -> ty fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::AssocItem { let def_id = impl_item_ref.id.owner_id; + let name = impl_item_ref.ident.name; let kind = match impl_item_ref.kind { - hir::AssocItemKind::Const => ty::AssocKind::Const, - hir::AssocItemKind::Fn { has_self } => ty::AssocKind::Fn { has_self }, - hir::AssocItemKind::Type => ty::AssocKind::Type { opt_rpitit_info: None }, + hir::AssocItemKind::Const => ty::AssocKind::Const { name }, + hir::AssocItemKind::Fn { has_self } => ty::AssocKind::Fn { name, has_self }, + hir::AssocItemKind::Type => ty::AssocKind::Type { data: ty::AssocTypeData::Normal(name) }, }; ty::AssocItem { - name: impl_item_ref.ident.name, kind, def_id: def_id.to_def_id(), trait_item_def_id: impl_item_ref.trait_item_def_id, @@ -260,9 +259,8 @@ fn associated_type_for_impl_trait_in_trait( trait_assoc_ty.def_ident_span(Some(span)); trait_assoc_ty.associated_item(ty::AssocItem { - name: kw::Empty, kind: ty::AssocKind::Type { - opt_rpitit_info: Some(ImplTraitInTraitData::Trait { + data: ty::AssocTypeData::Rpitit(ImplTraitInTraitData::Trait { fn_def_id: fn_def_id.to_def_id(), opaque_def_id: opaque_ty_def_id.to_def_id(), }), @@ -313,9 +311,8 @@ fn associated_type_for_impl_trait_in_impl( impl_assoc_ty.def_ident_span(Some(span)); impl_assoc_ty.associated_item(ty::AssocItem { - name: kw::Empty, kind: ty::AssocKind::Type { - opt_rpitit_info: Some(ImplTraitInTraitData::Impl { + data: ty::AssocTypeData::Rpitit(ImplTraitInTraitData::Impl { fn_def_id: impl_fn_def_id.to_def_id(), }), }, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 74dbc7d0600..2a95acc622e 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -521,7 +521,7 @@ fn projection_to_path_segment<'tcx>( let item = cx.tcx.associated_item(def_id); let generics = cx.tcx.generics_of(def_id); PathSegment { - name: item.name, + name: item.name(), args: GenericArgs::AngleBracketed { args: clean_middle_generic_args( cx, @@ -1340,7 +1340,7 @@ pub(crate) fn clean_impl_item<'tcx>( pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocContext<'_>) -> Item { let tcx = cx.tcx; let kind = match assoc_item.kind { - ty::AssocKind::Const => { + ty::AssocKind::Const { .. } => { let ty = clean_middle_ty( ty::Binder::dummy(tcx.type_of(assoc_item.def_id).instantiate_identity()), cx, @@ -1374,7 +1374,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo } } } - ty::AssocKind::Fn { has_self } => { + ty::AssocKind::Fn { has_self, .. } => { let mut item = inline::build_function(cx, assoc_item.def_id); if has_self { @@ -1413,7 +1413,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo } } ty::AssocKind::Type { .. } => { - let my_name = assoc_item.name; + let my_name = assoc_item.name(); fn param_eq_arg(param: &GenericParamDef, arg: &GenericArg) -> bool { match (¶m.kind, arg) { @@ -1554,7 +1554,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo } }; - Item::from_def_id_and_parts(assoc_item.def_id, Some(assoc_item.name), kind, cx) + Item::from_def_id_and_parts(assoc_item.def_id, Some(assoc_item.name()), kind, cx) } fn first_non_private_clean_path<'tcx>( @@ -2223,7 +2223,7 @@ pub(crate) fn clean_middle_ty<'tcx>( Type::QPath(Box::new(QPathData { assoc: PathSegment { - name: cx.tcx.associated_item(def_id).name, + name: cx.tcx.associated_item(def_id).name(), args: GenericArgs::AngleBracketed { args: clean_middle_generic_args( cx, diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 06e75fe1764..7786b216112 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -2504,7 +2504,7 @@ impl Impl { self.trait_ .as_ref() .map(|t| t.def_id()) - .map(|did| tcx.provided_trait_methods(did).map(|meth| meth.name).collect()) + .map(|did| tcx.provided_trait_methods(did).map(|meth| meth.name()).collect()) .unwrap_or_default() } diff --git a/src/tools/clippy/clippy_lints/src/assigning_clones.rs b/src/tools/clippy/clippy_lints/src/assigning_clones.rs index ab34af7c317..e5439a6d401 100644 --- a/src/tools/clippy/clippy_lints/src/assigning_clones.rs +++ b/src/tools/clippy/clippy_lints/src/assigning_clones.rs @@ -111,8 +111,8 @@ impl<'tcx> LateLintPass<'tcx> for AssigningClones { // Only suggest if `clone_from`/`clone_into` is explicitly implemented && resolved_assoc_items.in_definition_order().any(|assoc| match which_trait { - CloneTrait::Clone => assoc.name == sym::clone_from, - CloneTrait::ToOwned => assoc.name.as_str() == "clone_into", + CloneTrait::Clone => assoc.name() == sym::clone_from, + CloneTrait::ToOwned => assoc.name().as_str() == "clone_into", } ) && !clone_source_borrows_from_dest(cx, lhs, rhs.span) diff --git a/src/tools/clippy/clippy_lints/src/methods/double_ended_iterator_last.rs b/src/tools/clippy/clippy_lints/src/methods/double_ended_iterator_last.rs index e82211bbf3e..b5adc69e9a7 100644 --- a/src/tools/clippy/clippy_lints/src/methods/double_ended_iterator_last.rs +++ b/src/tools/clippy/clippy_lints/src/methods/double_ended_iterator_last.rs @@ -24,7 +24,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, self_expr: &'_ Exp && let Ok(Some(fn_def)) = Instance::try_resolve(cx.tcx, cx.typing_env(), id, args) // find the provided definition of Iterator::last && let Some(item) = cx.tcx.get_diagnostic_item(sym::Iterator) - && let Some(last_def) = cx.tcx.provided_trait_methods(item).find(|m| m.name.as_str() == "last") + && let Some(last_def) = cx.tcx.provided_trait_methods(item).find(|m| m.name().as_str() == "last") // if the resolved method is the same as the provided definition && fn_def.def_id() == last_def.def_id { diff --git a/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs b/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs index 7ee746365d1..e266c36b6e7 100644 --- a/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs +++ b/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs @@ -81,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingTraitMethods { cx, MISSING_TRAIT_METHODS, cx.tcx.def_span(item.owner_id), - format!("missing trait method provided by default: `{}`", assoc.name), + format!("missing trait method provided by default: `{}`", assoc.name()), |diag| { diag.span_help(cx.tcx.def_span(assoc.def_id), "implement the method"); }, diff --git a/src/tools/clippy/clippy_lints/src/same_name_method.rs b/src/tools/clippy/clippy_lints/src/same_name_method.rs index ae677e110af..33815cc3bac 100644 --- a/src/tools/clippy/clippy_lints/src/same_name_method.rs +++ b/src/tools/clippy/clippy_lints/src/same_name_method.rs @@ -85,7 +85,7 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod { .associated_items(did) .in_definition_order() .filter(|assoc_item| assoc_item.is_fn()) - .map(|assoc_item| assoc_item.name) + .map(|assoc_item| assoc_item.name()) .collect() } else { BTreeSet::new() diff --git a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs index 2104eb302ab..0c17cc5d8f6 100644 --- a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs @@ -322,7 +322,7 @@ impl UnconditionalRecursion { .in_definition_order() // We're not interested in foreign implementations of the `Default` trait. .find(|item| { - item.is_fn() && item.def_id.is_local() && item.name == kw::Default + item.is_fn() && item.def_id.is_local() && item.name() == kw::Default }) && let Some(body_node) = cx.tcx.hir_get_if_local(assoc_item.def_id) && let Some(body_id) = body_node.body_id() -- cgit 1.4.1-3-g733a5