From 51f42d617e99dfaa790a55b44a68c28cc97f5ae1 Mon Sep 17 00:00:00 2001 From: Lukas Bergdoll Date: Fri, 24 Apr 2026 14:59:57 +0200 Subject: [PATCH 01/42] Add temporary scope to assert_eq and assert_ne This is a follow-up to https://github.com/rust-lang/rust/pull/155431 --- library/core/src/macros/mod.rs | 16 ++++++++-------- library/coretests/tests/macros.rs | 14 +++++++++++++- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 08a12b6447e61..26a964a76c598 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -40,7 +40,7 @@ macro_rules! panic { #[rustc_diagnostic_item = "assert_eq_macro"] #[allow_internal_unstable(panic_internals)] macro_rules! assert_eq { - ($left:expr, $right:expr $(,)?) => { + ($left:expr, $right:expr $(,)?) => {{ match (&$left, &$right) { (left_val, right_val) => { if !(*left_val == *right_val) { @@ -52,8 +52,8 @@ macro_rules! assert_eq { } } } - }; - ($left:expr, $right:expr, $($arg:tt)+) => { + }}; + ($left:expr, $right:expr, $($arg:tt)+) => {{ match (&$left, &$right) { (left_val, right_val) => { if !(*left_val == *right_val) { @@ -65,7 +65,7 @@ macro_rules! assert_eq { } } } - }; + }}; } /// Asserts that two expressions are not equal to each other (using [`PartialEq`]). @@ -96,7 +96,7 @@ macro_rules! assert_eq { #[rustc_diagnostic_item = "assert_ne_macro"] #[allow_internal_unstable(panic_internals)] macro_rules! assert_ne { - ($left:expr, $right:expr $(,)?) => { + ($left:expr, $right:expr $(,)?) => {{ match (&$left, &$right) { (left_val, right_val) => { if *left_val == *right_val { @@ -108,8 +108,8 @@ macro_rules! assert_ne { } } } - }; - ($left:expr, $right:expr, $($arg:tt)+) => { + }}; + ($left:expr, $right:expr, $($arg:tt)+) => {{ match (&($left), &($right)) { (left_val, right_val) => { if *left_val == *right_val { @@ -121,7 +121,7 @@ macro_rules! assert_ne { } } } - }; + }}; } /// Asserts that an expression matches the provided pattern. diff --git a/library/coretests/tests/macros.rs b/library/coretests/tests/macros.rs index 9f73ebd253c3b..86419bb41e527 100644 --- a/library/coretests/tests/macros.rs +++ b/library/coretests/tests/macros.rs @@ -241,7 +241,19 @@ fn temporary_scope_introduction() { (assert_matches!(*MutRefWithDrop(&mut val).0, 0), std::mem::take(&mut val)); (assert_matches!(*MutRefWithDrop(&mut val).0, 0, "msg"), std::mem::take(&mut val)); - (debug_assert_matches!(*MutRefWithDrop(&mut val).0, 0), std::mem::take(&mut val)); (debug_assert_matches!(*MutRefWithDrop(&mut val).0, 0, "msg"), std::mem::take(&mut val)); + + (assert_eq!(*MutRefWithDrop(&mut val).0, 0), std::mem::take(&mut val)); + (assert_eq!(*MutRefWithDrop(&mut val).0, 0, "msg"), std::mem::take(&mut val)); + (debug_assert_eq!(*MutRefWithDrop(&mut val).0, 0), std::mem::take(&mut val)); + (debug_assert_eq!(*MutRefWithDrop(&mut val).0, 0, "msg"), std::mem::take(&mut val)); + + (assert_ne!(*MutRefWithDrop(&mut val).0, 1), std::mem::take(&mut val)); + (assert_ne!(*MutRefWithDrop(&mut val).0, 1, "msg"), std::mem::take(&mut val)); + (debug_assert_ne!(*MutRefWithDrop(&mut val).0, 1), std::mem::take(&mut val)); + (debug_assert_ne!(*MutRefWithDrop(&mut val).0, 1, "msg"), std::mem::take(&mut val)); + + (assert!(*MutRefWithDrop(&mut val).0 == 0), std::mem::take(&mut val)); + (assert!(*MutRefWithDrop(&mut val).0 == 0, "msg"), std::mem::take(&mut val)); } From d061dcb71f45ade7f38578edbbcbe486349037e8 Mon Sep 17 00:00:00 2001 From: Dnreikronos Date: Sun, 24 May 2026 14:20:29 -0300 Subject: [PATCH 02/42] Fix misattributed type inference error span for index expressions When an index expression with an ambiguous type (e.g. `arr[idx.into()]`) appears inside a cast or binary operation, the type inference error was incorrectly attributed to the outer expression instead of the `.into()` call. Resolve the index sub-expression type first so the error points at the actual ambiguous site. --- compiler/rustc_hir_typeck/src/cast.rs | 16 ++++++- compiler/rustc_hir_typeck/src/op.rs | 10 +++++ .../index-expr-ambiguous-type.rs | 30 +++++++++++++ .../index-expr-ambiguous-type.stderr | 42 +++++++++++++++++++ 4 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 tests/ui/type-inference/index-expr-ambiguous-type.rs create mode 100644 tests/ui/type-inference/index-expr-ambiguous-type.stderr diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 4d934703f4670..97ff7765896a8 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -727,7 +727,21 @@ impl<'a, 'tcx> CastCheck<'tcx> { #[instrument(skip(fcx), level = "debug")] pub(crate) fn check(mut self, fcx: &FnCtxt<'a, 'tcx>) { - self.expr_ty = fcx.structurally_resolve_type(self.expr_span, self.expr_ty); + if let hir::ExprKind::Index(_, idx, _) = self.expr.kind + && self.expr_ty.has_infer() + { + let idx_ty = fcx.resolve_vars_if_possible(fcx.node_ty(idx.hir_id)); + if idx_ty.is_ty_var() { + let resolved = fcx.structurally_resolve_type(idx.span, idx_ty); + if resolved.references_error() { + self.expr_ty = resolved; + } + } + } + // Skip if idx resolution above already emitted a diagnostic and set expr_ty to error. + if !self.expr_ty.references_error() { + self.expr_ty = fcx.structurally_resolve_type(self.expr_span, self.expr_ty); + } self.cast_ty = fcx.structurally_resolve_type(self.cast_span, self.cast_ty); debug!("check_cast({}, {:?} as {:?})", self.expr.hir_id, self.expr_ty, self.cast_ty); diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index 1e9986fa761c4..0a67b384ae8de 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -313,6 +313,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method); + + if method.sig.output().has_infer() + && let hir::ExprKind::Index(_, idx, _) = rhs_expr.kind + { + let idx_ty = self.resolve_vars_if_possible(self.node_ty(idx.hir_id)); + if idx_ty.is_ty_var() { + self.structurally_resolve_type(idx.span, idx_ty); + } + } + method.sig.output() } // error types are considered "builtin" diff --git a/tests/ui/type-inference/index-expr-ambiguous-type.rs b/tests/ui/type-inference/index-expr-ambiguous-type.rs new file mode 100644 index 0000000000000..32b45703e2003 --- /dev/null +++ b/tests/ui/type-inference/index-expr-ambiguous-type.rs @@ -0,0 +1,30 @@ +// Regression test for #156738 +// +// When the index type in `arr[idx]` is ambiguous, the error should point +// at the index sub-expression, not the whole indexing expression or +// surrounding operators. + +fn with_cast() { + let bad_idx = 0u8; + let _foo = [1, 2, 3][bad_idx.into()] as i32; + //~^ ERROR type annotations needed +} + +fn with_binop() { + let bad_idx = 0u8; + let _foo = 0 + [1, 2, 3][bad_idx.into()]; + //~^ ERROR type annotations needed +} + +fn standalone() { + let bad_idx = 0u8; + let _foo = [1, 2, 3][bad_idx.into()]; + //~^ ERROR type annotations needed +} + +fn with_known_index_type() { + let bad_idx = 0u8; + let _foo = [1, 2, 3][Into::::into(bad_idx)] as i32; +} + +fn main() {} diff --git a/tests/ui/type-inference/index-expr-ambiguous-type.stderr b/tests/ui/type-inference/index-expr-ambiguous-type.stderr new file mode 100644 index 0000000000000..80c0aa6c4a952 --- /dev/null +++ b/tests/ui/type-inference/index-expr-ambiguous-type.stderr @@ -0,0 +1,42 @@ +error[E0282]: type annotations needed + --> $DIR/index-expr-ambiguous-type.rs:9:34 + | +LL | let _foo = [1, 2, 3][bad_idx.into()] as i32; + | ^^^^ + | +help: try using a fully qualified path to specify the expected types + | +LL - let _foo = [1, 2, 3][bad_idx.into()] as i32; +LL + let _foo = [1, 2, 3][>::into(bad_idx)] as i32; + | + +error[E0282]: type annotations needed + --> $DIR/index-expr-ambiguous-type.rs:15:38 + | +LL | let _foo = 0 + [1, 2, 3][bad_idx.into()]; + | ^^^^ + | +help: try using a fully qualified path to specify the expected types + | +LL - let _foo = 0 + [1, 2, 3][bad_idx.into()]; +LL + let _foo = 0 + [1, 2, 3][>::into(bad_idx)]; + | + +error[E0283]: type annotations needed + --> $DIR/index-expr-ambiguous-type.rs:21:34 + | +LL | let _foo = [1, 2, 3][bad_idx.into()]; + | ^^^^ + | + = note: the type must implement `From` + = note: required for `u8` to implement `Into<_>` +help: try using a fully qualified path to specify the expected types + | +LL - let _foo = [1, 2, 3][bad_idx.into()]; +LL + let _foo = [1, 2, 3][>::into(bad_idx)]; + | + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0282, E0283. +For more information about an error, try `rustc --explain E0282`. From 7be87edcb3fbdb060d9d867c9f4fb477f5e019ed Mon Sep 17 00:00:00 2001 From: Dnreikronos Date: Thu, 11 Jun 2026 19:47:14 -0300 Subject: [PATCH 03/42] Don't ICE on non-lifetime binders under `-Zassumptions-on-binders` The region-constraint machinery for `-Zassumptions-on-binders` is region-outlives-only. A non-lifetime binder (`for`) introduces a placeholder type in the binder's universe `u`. The rewrite that pulls constraints out of `u` only folds regions (`PlaceholderReplacer` just implements `fold_region`), so an alias-outlives constraint such as `::Assoc: 'r` reaches `pull_region_outlives_constraints_out_of_universe` still in `u` and trips `assert!(max_universe < u)`. Report ambiguity for those constraints instead of asserting, matching the existing `None => Ambiguity` bail-outs in this module. The goal then surfaces as an ordinary ambiguity error rather than an ICE. --- .../rustc_type_ir/src/region_constraint.rs | 14 +++++++++++-- .../non_lifetime_binder_alias_outlives.rs | 21 +++++++++++++++++++ .../non_lifetime_binder_alias_outlives.stderr | 20 ++++++++++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 tests/ui/assumptions_on_binders/non_lifetime_binder_alias_outlives.rs create mode 100644 tests/ui/assumptions_on_binders/non_lifetime_binder_alias_outlives.stderr diff --git a/compiler/rustc_type_ir/src/region_constraint.rs b/compiler/rustc_type_ir/src/region_constraint.rs index 43b1535d16809..b896d7a398178 100644 --- a/compiler/rustc_type_ir/src/region_constraint.rs +++ b/compiler/rustc_type_ir/src/region_constraint.rs @@ -654,8 +654,18 @@ fn pull_region_outlives_constraints_out_of_universe< use RegionConstraint::*; match constraint { Ambiguity | PlaceholderTyOutlives(..) | AliasTyOutlivesViaEnv(..) => { - assert!(max_universe(infcx, constraint.clone()) < u); - constraint + // With only lifetime binders the rewrite step lowers these constraints out of `u` + // (or destructures them), so we expect `max_universe < u` here. A non-lifetime + // binder (`for`) instead introduces a placeholder type in `u`, which + // `PlaceholderReplacer` (region-only, see its `fold_region`) cannot pull out, + // leaving e.g. `::Assoc: 'r` stranded in `u`. The assumptions-on-binders + // machinery is region-outlives-only and can't decide such a constraint, so report + // ambiguity rather than ICE. + if max_universe(infcx, constraint.clone()) < u { + constraint + } else { + RegionConstraint::Ambiguity + } } RegionOutlives(region_1, region_2) => { let region_1_u = max_universe(infcx, region_1); diff --git a/tests/ui/assumptions_on_binders/non_lifetime_binder_alias_outlives.rs b/tests/ui/assumptions_on_binders/non_lifetime_binder_alias_outlives.rs new file mode 100644 index 0000000000000..8178575555383 --- /dev/null +++ b/tests/ui/assumptions_on_binders/non_lifetime_binder_alias_outlives.rs @@ -0,0 +1,21 @@ +//@ compile-flags: -Znext-solver -Zassumptions-on-binders + +// Regression test for #157778. +// +// A non-lifetime binder (`for`) introduces a placeholder *type* in universe `u`. The +// resulting alias-outlives constraint `::Assoc: 'r` stays in `u` because the +// region-only rewrite (`PlaceholderReplacer` only folds regions) cannot pull a type +// placeholder out of `u`. This used to trip an `assert!(max_universe < u)` and ICE in +// `pull_region_outlives_constraints_out_of_universe`. The assumptions-on-binders machinery +// is region-outlives-only, so we now report ambiguity instead of panicking. + +#![feature(non_lifetime_binders)] + +trait Trait { + type Assoc; + type Ref //~ ERROR cannot satisfy `::Assoc: 'static` + where + for T: Trait; +} + +fn main() {} diff --git a/tests/ui/assumptions_on_binders/non_lifetime_binder_alias_outlives.stderr b/tests/ui/assumptions_on_binders/non_lifetime_binder_alias_outlives.stderr new file mode 100644 index 0000000000000..3b8c8720c6774 --- /dev/null +++ b/tests/ui/assumptions_on_binders/non_lifetime_binder_alias_outlives.stderr @@ -0,0 +1,20 @@ +error[E0284]: type annotations needed: cannot satisfy `::Assoc: 'static` + --> $DIR/non_lifetime_binder_alias_outlives.rs:16:5 + | +LL | / type Ref +LL | | where +LL | | for T: Trait; + | |________________________________________^ cannot satisfy `::Assoc: 'static` + | +note: required by a bound in `Trait::Ref` + --> $DIR/non_lifetime_binder_alias_outlives.rs:18:32 + | +LL | type Ref + | --- required by a bound in this associated type +LL | where +LL | for T: Trait; + | ^^^^^^^ required by this bound in `Trait::Ref` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0284`. From 5ffbf047faed9e481593c898108f6b4efa1e717d Mon Sep 17 00:00:00 2001 From: cyrgani Date: Sat, 30 May 2026 11:46:32 +0000 Subject: [PATCH 04/42] remove some redundant closures --- library/proc_macro/src/bridge/client.rs | 2 +- library/proc_macro/src/lib.rs | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs index a5966f767596e..48e6245ecf98b 100644 --- a/library/proc_macro/src/bridge/client.rs +++ b/library/proc_macro/src/bridge/client.rs @@ -282,7 +282,7 @@ impl Client { pub const fn expand1(f: impl Fn(crate::TokenStream) -> crate::TokenStream + Copy) -> Self { Client { run: super::selfless_reify::reify_to_extern_c_fn_hrt_bridge(move |bridge| { - run_client(bridge, |input| f(input)) + run_client(bridge, f) }), } } diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index e335fe1c70264..317b4de4e338e 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -295,7 +295,7 @@ impl TokenStream { /// Checks if this `TokenStream` is empty. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] pub fn is_empty(&self) -> bool { - self.0.as_ref().map(|h| BridgeMethods::ts_is_empty(h)).unwrap_or(true) + self.0.as_ref().map(BridgeMethods::ts_is_empty).unwrap_or(true) } /// Parses this `TokenStream` as an expression and attempts to expand any @@ -574,9 +574,7 @@ pub mod token_stream { type IntoIter = IntoIter; fn into_iter(self) -> IntoIter { - IntoIter( - self.0.map(|v| BridgeMethods::ts_into_trees(v)).unwrap_or_default().into_iter(), - ) + IntoIter(self.0.map(BridgeMethods::ts_into_trees).unwrap_or_default().into_iter()) } } } From acac5b30365c341df137c2df40acd218305b4f3c Mon Sep 17 00:00:00 2001 From: cyrgani Date: Sat, 30 May 2026 21:38:30 +0000 Subject: [PATCH 05/42] simplify `Buffer` --- library/proc_macro/src/bridge/buffer.rs | 32 ++----------------------- library/proc_macro/src/bridge/rpc.rs | 3 +-- 2 files changed, 3 insertions(+), 32 deletions(-) diff --git a/library/proc_macro/src/bridge/buffer.rs b/library/proc_macro/src/bridge/buffer.rs index 3760749d83a54..3176b9ea35c8c 100644 --- a/library/proc_macro/src/bridge/buffer.rs +++ b/library/proc_macro/src/bridge/buffer.rs @@ -1,8 +1,7 @@ //! Buffer management for same-process client<->server communication. -use std::io::{self, Write}; use std::mem::{self, ManuallyDrop}; -use std::ops::{Deref, DerefMut}; +use std::ops::Deref; use std::slice; #[repr(C)] @@ -32,13 +31,6 @@ impl Deref for Buffer { } } -impl DerefMut for Buffer { - #[inline] - fn deref_mut(&mut self) -> &mut [u8] { - unsafe { slice::from_raw_parts_mut(self.data, self.len) } - } -} - impl Buffer { #[inline] pub(super) fn new() -> Self { @@ -99,25 +91,6 @@ impl Buffer { } } -impl Write for Buffer { - #[inline] - fn write(&mut self, xs: &[u8]) -> io::Result { - self.extend_from_slice(xs); - Ok(xs.len()) - } - - #[inline] - fn write_all(&mut self, xs: &[u8]) -> io::Result<()> { - self.extend_from_slice(xs); - Ok(()) - } - - #[inline] - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - impl Drop for Buffer { #[inline] fn drop(&mut self) { @@ -128,8 +101,7 @@ impl Drop for Buffer { impl From> for Buffer { fn from(v: Vec) -> Self { - let mut v = ManuallyDrop::new(v); - let (data, len, capacity) = (v.as_mut_ptr(), v.len(), v.capacity()); + let (data, len, capacity) = v.into_raw_parts(); // This utility function is nested in here because it can *only* // be safely called on `Buffer`s created by *this* `proc_macro`. diff --git a/library/proc_macro/src/bridge/rpc.rs b/library/proc_macro/src/bridge/rpc.rs index 3459426b5cd3f..2c72497ad2723 100644 --- a/library/proc_macro/src/bridge/rpc.rs +++ b/library/proc_macro/src/bridge/rpc.rs @@ -1,6 +1,5 @@ //! Serialization for client-server communication. -use std::io::Write; use std::num::NonZero; use super::buffer::Buffer; @@ -209,7 +208,7 @@ impl Encode for &str { fn encode(self, w: &mut Buffer, s: &mut S) { let bytes = self.as_bytes(); bytes.len().encode(w, s); - w.write_all(bytes).unwrap(); + w.extend_from_slice(bytes); } } From d727a0e22414efd3f7f925424216daec4a505cab Mon Sep 17 00:00:00 2001 From: cyrgani Date: Mon, 1 Jun 2026 11:51:57 +0000 Subject: [PATCH 06/42] set `issue = none` for `proc_macro_internals` --- library/proc_macro/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 317b4de4e338e..4ead52e533e5d 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -37,7 +37,7 @@ #![warn(unreachable_pub)] #![deny(unsafe_op_in_unsafe_fn)] -#[unstable(feature = "proc_macro_internals", issue = "27812")] +#[unstable(feature = "proc_macro_internals", issue = "none")] #[doc(hidden)] pub mod bridge; @@ -592,7 +592,7 @@ pub macro quote($($t:tt)*) { /* compiler built-in */ } -#[unstable(feature = "proc_macro_internals", issue = "27812")] +#[unstable(feature = "proc_macro_internals", issue = "none")] #[doc(hidden)] mod quote; @@ -752,14 +752,14 @@ impl Span { // Used by the implementation of `Span::quote` #[doc(hidden)] - #[unstable(feature = "proc_macro_internals", issue = "27812")] + #[unstable(feature = "proc_macro_internals", issue = "none")] pub fn save_span(&self) -> usize { BridgeMethods::span_save_span(self.0) } // Used by the implementation of `Span::quote` #[doc(hidden)] - #[unstable(feature = "proc_macro_internals", issue = "27812")] + #[unstable(feature = "proc_macro_internals", issue = "none")] pub fn recover_proc_macro_span(id: usize) -> Span { Span(BridgeMethods::span_recover_proc_macro_span(id)) } From b292ff80a2a64ed136a7075c5fbb0d4e6661c06b Mon Sep 17 00:00:00 2001 From: cyrgani Date: Mon, 8 Jun 2026 09:11:17 +0000 Subject: [PATCH 07/42] fix "rountrips" typo --- library/proc_macro/src/lib.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 4ead52e533e5d..54ade77f86780 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -1293,7 +1293,7 @@ macro_rules! unsuffixed_int_literals { /// specified on this token, meaning that invocations like /// `Literal::i8_unsuffixed(1)` are equivalent to /// `Literal::u32_unsuffixed(1)`. - /// Literals created from negative numbers might not survive rountrips through + /// Literals created from negative numbers might not survive roundtrips through /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal). /// /// Literals created through this method have the `Span::call_site()` @@ -1413,7 +1413,7 @@ impl Literal { /// This constructor is similar to those like `Literal::i8_unsuffixed` where /// the float's value is emitted directly into the token but no suffix is /// used, so it may be inferred to be a `f64` later in the compiler. - /// Literals created from negative numbers might not survive rountrips through + /// Literals created from negative numbers might not survive roundtrips through /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal). /// /// # Panics @@ -1438,7 +1438,7 @@ impl Literal { /// specified is the preceding part of the token and `f32` is the suffix of /// the token. This token will always be inferred to be an `f32` in the /// compiler. - /// Literals created from negative numbers might not survive rountrips through + /// Literals created from negative numbers might not survive roundtrips through /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal). /// /// # Panics @@ -1458,7 +1458,7 @@ impl Literal { /// This constructor is similar to those like `Literal::i8_unsuffixed` where /// the float's value is emitted directly into the token but no suffix is /// used, so it may be inferred to be a `f64` later in the compiler. - /// Literals created from negative numbers might not survive rountrips through + /// Literals created from negative numbers might not survive roundtrips through /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal). /// /// # Panics @@ -1483,7 +1483,7 @@ impl Literal { /// specified is the preceding part of the token and `f64` is the suffix of /// the token. This token will always be inferred to be an `f64` in the /// compiler. - /// Literals created from negative numbers might not survive rountrips through + /// Literals created from negative numbers might not survive roundtrips through /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal). /// /// # Panics From 30004a85b3c636d395180850cafdab91d3cb6367 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Mon, 8 Jun 2026 09:11:29 +0000 Subject: [PATCH 08/42] improve `nonfatal-parsing` test --- .../auxiliary/nonfatal-parsing-body.rs | 33 +++++-- tests/ui/proc-macro/nonfatal-parsing.stderr | 26 +++++- tests/ui/proc-macro/nonfatal-parsing.stdout | 92 ++++++++++--------- 3 files changed, 102 insertions(+), 49 deletions(-) diff --git a/tests/ui/proc-macro/auxiliary/nonfatal-parsing-body.rs b/tests/ui/proc-macro/auxiliary/nonfatal-parsing-body.rs index f58aa1b228e31..258f77067ce9c 100644 --- a/tests/ui/proc-macro/auxiliary/nonfatal-parsing-body.rs +++ b/tests/ui/proc-macro/auxiliary/nonfatal-parsing-body.rs @@ -15,26 +15,38 @@ enum Mode { OtherWithPanic, } +fn print_unspanned(s: &str) -> Result +where + T: FromStr + Debug, +{ + let t = T::from_str(s); + let mut s = format!("{t:?}"); + while let Some((l, r)) = s.split_once("span: #") { + let (_, r) = r.split_once(")").unwrap(); + s = format!("{l}span: Span{r}"); + } + println!("{s}"); + t +} + fn parse(s: &str, mode: Mode) where T: FromStr + Debug, { match mode { NormalOk => { - let t = T::from_str(s); - println!("{:?}", t); + let t = print_unspanned::(s); assert!(t.is_ok()); } NormalErr => { - let t = T::from_str(s); - println!("{:?}", t); + let t = print_unspanned::(s); assert!(t.is_err()); } OtherError => { - println!("{:?}", T::from_str(s)); + print_unspanned::(s); } OtherWithPanic => { - if catch_unwind(|| println!("{:?}", T::from_str(s))).is_ok() { + if catch_unwind(|| print_unspanned::(s)).is_ok() { eprintln!("{s} did not panic"); } } @@ -64,7 +76,10 @@ fn lit(s: &str, mode: Mode) { } pub fn run() { + assert_eq!("\'", "'"); // returns Ok(valid instance) + lit("r\"g\"", NormalOk); + lit("r#\"g\"#", NormalOk); lit("123", NormalOk); lit("\"ab\"", NormalOk); lit("\'b\'", NormalOk); @@ -72,6 +87,7 @@ pub fn run() { lit("b\"b\"", NormalOk); lit("c\"b\"", NormalOk); lit("cr\"b\"", NormalOk); + lit("'\\''", NormalOk); lit("b'b'", NormalOk); lit("256u8", NormalOk); lit("-256u8", NormalOk); @@ -99,10 +115,13 @@ pub fn run() { NormalOk, ); stream("/*a*/ //", NormalOk); + lit("\"\"", NormalOk); + stream("", NormalOk); println!("### ERRORS"); // returns Err(LexError) + lit("", NormalErr); lit("\'c\'/**/", NormalErr); lit(" 0", NormalErr); lit("0 ", NormalErr); @@ -119,10 +138,12 @@ pub fn run() { // emits diagnostics and returns LexError lit("r'r'", OtherError); lit("c'r'", OtherError); + lit("\u{2000}", OtherError); // emits diagnostic and returns a seemingly valid tokenstream stream("r'r'", OtherError); stream("c'r'", OtherError); + stream("\u{2000}", OtherError); for parse in [stream as fn(&str, Mode), lit] { // emits diagnostic(s), then panics diff --git a/tests/ui/proc-macro/nonfatal-parsing.stderr b/tests/ui/proc-macro/nonfatal-parsing.stderr index 874a7a2f410d9..cb6e243eebc9b 100644 --- a/tests/ui/proc-macro/nonfatal-parsing.stderr +++ b/tests/ui/proc-macro/nonfatal-parsing.stderr @@ -22,6 +22,17 @@ help: consider inserting whitespace here LL | c 'r' | + +error: unknown start of token: \u{2000} + --> :1:1 + | +LL |   + | ^ + | +help: Unicode character ' ' (En Quad) looks like ' ' (Space), but it is not + | +LL | + | + error: prefix `r` is unknown --> $DIR/nonfatal-parsing.rs:15:5 | @@ -40,6 +51,19 @@ LL | nonfatal_parsing::run!(); = note: prefixed identifiers and literals are reserved since Rust 2021 = note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info) +error: unknown start of token: \u{2000} + --> $DIR/nonfatal-parsing.rs:15:5 + | +LL | nonfatal_parsing::run!(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info) +help: Unicode character ' ' (En Quad) looks like ' ' (Space), but it is not + --> :1:1 + | +LL | + | + error: found invalid character; only `#` is allowed in raw string delimitation: \u{0} --> $DIR/nonfatal-parsing.rs:15:5 | @@ -175,6 +199,6 @@ error: invalid digit for a base 2 literal LL | /*a*/ 0b2 // | ^ -error: aborting due to 20 previous errors +error: aborting due to 22 previous errors For more information about this error, try `rustc --explain E0768`. diff --git a/tests/ui/proc-macro/nonfatal-parsing.stdout b/tests/ui/proc-macro/nonfatal-parsing.stdout index 2b92474fb8b4c..a46ef66f0f9d0 100644 --- a/tests/ui/proc-macro/nonfatal-parsing.stdout +++ b/tests/ui/proc-macro/nonfatal-parsing.stdout @@ -1,34 +1,40 @@ -Ok(Literal { kind: Integer, symbol: "123", suffix: None, span: #44 bytes(361..385) }) -Ok(Literal { kind: Str, symbol: "ab", suffix: None, span: #44 bytes(361..385) }) -Ok(Literal { kind: Char, symbol: "b", suffix: None, span: #44 bytes(361..385) }) -Ok(Literal { kind: Char, symbol: "b", suffix: None, span: #44 bytes(361..385) }) -Ok(Literal { kind: ByteStr, symbol: "b", suffix: None, span: #44 bytes(361..385) }) -Ok(Literal { kind: CStr, symbol: "b", suffix: None, span: #44 bytes(361..385) }) -Ok(Literal { kind: CStrRaw(0), symbol: "b", suffix: None, span: #44 bytes(361..385) }) -Ok(Literal { kind: Byte, symbol: "b", suffix: None, span: #44 bytes(361..385) }) -Ok(Literal { kind: Integer, symbol: "256", suffix: Some("u8"), span: #44 bytes(361..385) }) -Ok(Literal { kind: Integer, symbol: "-256", suffix: Some("u8"), span: #44 bytes(361..385) }) -Ok(TokenStream [Punct { ch: '-', spacing: Alone, span: #44 bytes(361..385) }, Literal { kind: Integer, symbol: "256", suffix: Some("u8"), span: #44 bytes(361..385) }]) -Ok(Literal { kind: Integer, symbol: "0b11111000000001111", suffix: Some("i16"), span: #44 bytes(361..385) }) -Ok(Literal { kind: Integer, symbol: "0xf32", suffix: None, span: #44 bytes(361..385) }) -Ok(Literal { kind: Integer, symbol: "0b0", suffix: Some("f32"), span: #44 bytes(361..385) }) -Ok(Literal { kind: Float, symbol: "2E4", suffix: None, span: #44 bytes(361..385) }) -Ok(Literal { kind: Float, symbol: "2.2E-4", suffix: Some("f64"), span: #44 bytes(361..385) }) -Ok(Literal { kind: Integer, symbol: "18", suffix: Some("u8E"), span: #44 bytes(361..385) }) -Ok(Literal { kind: Float, symbol: "18.0", suffix: Some("u8E"), span: #44 bytes(361..385) }) -Ok(Literal { kind: CStrRaw(1), symbol: "// /* // \n */", suffix: None, span: #44 bytes(361..385) }) -Ok(Literal { kind: Char, symbol: "\'", suffix: None, span: #44 bytes(361..385) }) -Ok(Literal { kind: Char, symbol: "\'", suffix: None, span: #44 bytes(361..385) }) -Ok(Literal { kind: StrRaw(255), symbol: "a", suffix: None, span: #44 bytes(361..385) }) -Ok(TokenStream [Ident { ident: "fn", span: #44 bytes(361..385) }, Ident { ident: "main", span: #44 bytes(361..385) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #44 bytes(361..385) }, Group { delimiter: Brace, stream: TokenStream [Ident { ident: "println", span: #44 bytes(361..385) }, Punct { ch: '!', spacing: Alone, span: #44 bytes(361..385) }, Group { delimiter: Parenthesis, stream: TokenStream [Literal { kind: Str, symbol: "Hello, world!", suffix: None, span: #44 bytes(361..385) }], span: #44 bytes(361..385) }], span: #44 bytes(361..385) }]) -Ok(TokenStream [Literal { kind: Integer, symbol: "18", suffix: None, span: #44 bytes(361..385) }, Punct { ch: '.', spacing: Alone, span: #44 bytes(361..385) }, Ident { ident: "u8E", span: #44 bytes(361..385) }]) -Ok(TokenStream [Literal { kind: Float, symbol: "18.0", suffix: Some("f32"), span: #44 bytes(361..385) }]) -Ok(TokenStream [Literal { kind: Float, symbol: "18.0", suffix: Some("f34"), span: #44 bytes(361..385) }]) -Ok(TokenStream [Literal { kind: Integer, symbol: "18", suffix: None, span: #44 bytes(361..385) }, Punct { ch: '.', spacing: Alone, span: #44 bytes(361..385) }, Ident { ident: "bu8", span: #44 bytes(361..385) }]) -Ok(TokenStream [Literal { kind: Integer, symbol: "3", suffix: None, span: #44 bytes(361..385) }, Literal { kind: Integer, symbol: "4", suffix: None, span: #44 bytes(361..385) }]) -Ok(TokenStream [Literal { kind: Char, symbol: "c", suffix: None, span: #44 bytes(361..385) }]) +Ok(Literal { kind: StrRaw(0), symbol: "g", suffix: None, span: Span }) +Ok(Literal { kind: StrRaw(1), symbol: "g", suffix: None, span: Span }) +Ok(Literal { kind: Integer, symbol: "123", suffix: None, span: Span }) +Ok(Literal { kind: Str, symbol: "ab", suffix: None, span: Span }) +Ok(Literal { kind: Char, symbol: "b", suffix: None, span: Span }) +Ok(Literal { kind: Char, symbol: "b", suffix: None, span: Span }) +Ok(Literal { kind: ByteStr, symbol: "b", suffix: None, span: Span }) +Ok(Literal { kind: CStr, symbol: "b", suffix: None, span: Span }) +Ok(Literal { kind: CStrRaw(0), symbol: "b", suffix: None, span: Span }) +Ok(Literal { kind: Char, symbol: "\'", suffix: None, span: Span }) +Ok(Literal { kind: Byte, symbol: "b", suffix: None, span: Span }) +Ok(Literal { kind: Integer, symbol: "256", suffix: Some("u8"), span: Span }) +Ok(Literal { kind: Integer, symbol: "-256", suffix: Some("u8"), span: Span }) +Ok(TokenStream [Punct { ch: '-', spacing: Alone, span: Span }, Literal { kind: Integer, symbol: "256", suffix: Some("u8"), span: Span }]) +Ok(Literal { kind: Integer, symbol: "0b11111000000001111", suffix: Some("i16"), span: Span }) +Ok(Literal { kind: Integer, symbol: "0xf32", suffix: None, span: Span }) +Ok(Literal { kind: Integer, symbol: "0b0", suffix: Some("f32"), span: Span }) +Ok(Literal { kind: Float, symbol: "2E4", suffix: None, span: Span }) +Ok(Literal { kind: Float, symbol: "2.2E-4", suffix: Some("f64"), span: Span }) +Ok(Literal { kind: Integer, symbol: "18", suffix: Some("u8E"), span: Span }) +Ok(Literal { kind: Float, symbol: "18.0", suffix: Some("u8E"), span: Span }) +Ok(Literal { kind: CStrRaw(1), symbol: "// /* // \n */", suffix: None, span: Span }) +Ok(Literal { kind: Char, symbol: "\'", suffix: None, span: Span }) +Ok(Literal { kind: Char, symbol: "\'", suffix: None, span: Span }) +Ok(Literal { kind: StrRaw(255), symbol: "a", suffix: None, span: Span }) +Ok(TokenStream [Ident { ident: "fn", span: Span }, Ident { ident: "main", span: Span }, Group { delimiter: Parenthesis, stream: TokenStream [], span: Span }, Group { delimiter: Brace, stream: TokenStream [Ident { ident: "println", span: Span }, Punct { ch: '!', spacing: Alone, span: Span }, Group { delimiter: Parenthesis, stream: TokenStream [Literal { kind: Str, symbol: "Hello, world!", suffix: None, span: Span }], span: Span }], span: Span }]) +Ok(TokenStream [Literal { kind: Integer, symbol: "18", suffix: None, span: Span }, Punct { ch: '.', spacing: Alone, span: Span }, Ident { ident: "u8E", span: Span }]) +Ok(TokenStream [Literal { kind: Float, symbol: "18.0", suffix: Some("f32"), span: Span }]) +Ok(TokenStream [Literal { kind: Float, symbol: "18.0", suffix: Some("f34"), span: Span }]) +Ok(TokenStream [Literal { kind: Integer, symbol: "18", suffix: None, span: Span }, Punct { ch: '.', spacing: Alone, span: Span }, Ident { ident: "bu8", span: Span }]) +Ok(TokenStream [Literal { kind: Integer, symbol: "3", suffix: None, span: Span }, Literal { kind: Integer, symbol: "4", suffix: None, span: Span }]) +Ok(TokenStream [Literal { kind: Char, symbol: "c", suffix: None, span: Span }]) +Ok(TokenStream []) +Ok(Literal { kind: Str, symbol: "", suffix: None, span: Span }) Ok(TokenStream []) ### ERRORS +Err(LexError("not a literal")) Err(LexError("comment or whitespace around literal")) Err(LexError("comment or whitespace around literal")) Err(LexError("comment or whitespace around literal")) @@ -42,17 +48,19 @@ Err(LexError("unexpected closing delimiter: `)`")) Err(LexError("unexpected closing delimiter: `]`")) Err(LexError("not a literal")) Err(LexError("not a literal")) -Ok(TokenStream [Ident { ident: "r", span: #44 bytes(361..385) }, Literal { kind: Char, symbol: "r", suffix: None, span: #44 bytes(361..385) }]) -Ok(TokenStream [Ident { ident: "c", span: #44 bytes(361..385) }, Literal { kind: Char, symbol: "r", suffix: None, span: #44 bytes(361..385) }]) -Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: #44 bytes(361..385) }]) -Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b", suffix: Some("f32"), span: #44 bytes(361..385) }]) -Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b0.0", suffix: Some("f32"), span: #44 bytes(361..385) }]) -Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "'''", suffix: None, span: #44 bytes(361..385) }]) -Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "'\n'", suffix: None, span: #44 bytes(361..385) }]) -Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: #44 bytes(361..385) }]) -Ok(Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: #44 bytes(361..385) }) -Ok(Literal { kind: ErrWithGuar, symbol: "0b", suffix: Some("f32"), span: #44 bytes(361..385) }) -Ok(Literal { kind: ErrWithGuar, symbol: "0b0.0", suffix: Some("f32"), span: #44 bytes(361..385) }) -Ok(Literal { kind: ErrWithGuar, symbol: "'''", suffix: None, span: #44 bytes(361..385) }) -Ok(Literal { kind: ErrWithGuar, symbol: "'\n'", suffix: None, span: #44 bytes(361..385) }) +Err(LexError("not a literal")) +Ok(TokenStream [Ident { ident: "r", span: Span }, Literal { kind: Char, symbol: "r", suffix: None, span: Span }]) +Ok(TokenStream [Ident { ident: "c", span: Span }, Literal { kind: Char, symbol: "r", suffix: None, span: Span }]) +Ok(TokenStream []) +Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: Span }]) +Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b", suffix: Some("f32"), span: Span }]) +Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b0.0", suffix: Some("f32"), span: Span }]) +Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "'''", suffix: None, span: Span }]) +Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "'\n'", suffix: None, span: Span }]) +Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: Span }]) +Ok(Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: Span }) +Ok(Literal { kind: ErrWithGuar, symbol: "0b", suffix: Some("f32"), span: Span }) +Ok(Literal { kind: ErrWithGuar, symbol: "0b0.0", suffix: Some("f32"), span: Span }) +Ok(Literal { kind: ErrWithGuar, symbol: "'''", suffix: None, span: Span }) +Ok(Literal { kind: ErrWithGuar, symbol: "'\n'", suffix: None, span: Span }) Err(LexError("comment or whitespace around literal")) From a39003660da2f444a518b8593d2aba66705bc9da Mon Sep 17 00:00:00 2001 From: Dnreikronos Date: Mon, 15 Jun 2026 11:59:10 -0300 Subject: [PATCH 09/42] resolve region inference vars when computing their max universe The `MaxUniverse` region visitor matched on `ReVar` terms and unwrapped `universe_of_lt`, which returns `None` for a variable that has already been unified with another region. Such resolved variables can reach the visitor while computing region assumptions under `-Zassumptions-on-binders`, causing an ICE. Resolve the variable first and inspect whatever it points at instead of assuming it is still an unresolved inference variable. --- .../rustc_type_ir/src/region_constraint.rs | 23 +++++++++++++--- .../resolved-region-var-max-universe.rs | 26 +++++++++++++++++++ .../resolved-region-var-max-universe.stderr | 14 ++++++++++ 3 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 tests/ui/assumptions_on_binders/resolved-region-var-max-universe.rs create mode 100644 tests/ui/assumptions_on_binders/resolved-region-var-max-universe.stderr diff --git a/compiler/rustc_type_ir/src/region_constraint.rs b/compiler/rustc_type_ir/src/region_constraint.rs index 4b23bfd0f7765..6f13eedda4983 100644 --- a/compiler/rustc_type_ir/src/region_constraint.rs +++ b/compiler/rustc_type_ir/src/region_constraint.rs @@ -1013,6 +1013,10 @@ impl<'a, Infcx: InferCtxtLike, I: Interner> TypeVisitor match t.kind() { TyKind::Placeholder(p) => self.max_universe = self.max_universe.max(p.universe), TyKind::Infer(InferTy::TyVar(inf)) => { + // Unlike `visit_region`, we don't resolve the variable first: callers + // computing assumptions bail on any non-region inference variable + // before reaching here, so a type infer var is always unresolved and + // has a universe. let u = self.infcx.universe_of_ty(inf).unwrap(); debug!("var {inf:?} in universe {u:?}"); self.max_universe = self.max_universe.max(u); @@ -1025,6 +1029,8 @@ impl<'a, Infcx: InferCtxtLike, I: Interner> TypeVisitor match c.kind() { ConstKind::Placeholder(p) => self.max_universe = self.max_universe.max(p.universe), ConstKind::Infer(rustc_type_ir::InferConst::Var(inf)) => { + // See the comment in `visit_ty`: a const infer var is always + // unresolved here, so unlike a region it needs no resolving first. let u = self.infcx.universe_of_ct(inf).unwrap(); debug!("var {inf:?} in universe {u:?}"); self.max_universe = self.max_universe.max(u); @@ -1037,9 +1043,20 @@ impl<'a, Infcx: InferCtxtLike, I: Interner> TypeVisitor match r.kind() { RegionKind::RePlaceholder(p) => self.max_universe = self.max_universe.max(p.universe), RegionKind::ReVar(var) => { - let u = self.infcx.universe_of_lt(var).unwrap(); - debug!("var {var:?} in universe {u:?}"); - self.max_universe = self.max_universe.max(u); + // The variable may already have been unified with another region. + // `universe_of_lt` returns `None` for a resolved variable, so resolve + // it first and inspect whatever it points at. + match self.infcx.opportunistic_resolve_lt_var(var).kind() { + RegionKind::RePlaceholder(p) => { + self.max_universe = self.max_universe.max(p.universe) + } + RegionKind::ReVar(var) => { + let u = self.infcx.universe_of_lt(var).unwrap(); + debug!("var {var:?} in universe {u:?}"); + self.max_universe = self.max_universe.max(u); + } + _ => (), + } } _ => (), } diff --git a/tests/ui/assumptions_on_binders/resolved-region-var-max-universe.rs b/tests/ui/assumptions_on_binders/resolved-region-var-max-universe.rs new file mode 100644 index 0000000000000..f0286fb92453a --- /dev/null +++ b/tests/ui/assumptions_on_binders/resolved-region-var-max-universe.rs @@ -0,0 +1,26 @@ +//@ compile-flags: -Zassumptions-on-binders -Znext-solver=globally + +// Regression test for an ICE in the `MaxUniverse` region visitor. When computing +// the max universe of a region constraint, a `ReVar` term could already have been +// unified with another region. `universe_of_lt` returns `None` for such a resolved +// variable, so the visitor used to `unwrap()` `None` and panic. It now resolves the +// variable before inspecting its universe. + +#![feature(min_generic_const_args, inherent_associated_types, generic_const_items)] + +struct Parent<'a> { + a: &'a str, +} + +impl<'a> Parent<'a> { + type const CT: usize = 0; +} + +fn check/**/() +where + [(); Parent::CT::]:, + //~^ ERROR cannot find type `T` in this scope +{ +} + +fn main() {} diff --git a/tests/ui/assumptions_on_binders/resolved-region-var-max-universe.stderr b/tests/ui/assumptions_on_binders/resolved-region-var-max-universe.stderr new file mode 100644 index 0000000000000..6fa91876dd47b --- /dev/null +++ b/tests/ui/assumptions_on_binders/resolved-region-var-max-universe.stderr @@ -0,0 +1,14 @@ +error[E0425]: cannot find type `T` in this scope + --> $DIR/resolved-region-var-max-universe.rs:21:23 + | +LL | [(); Parent::CT::]:, + | ^ not found in this scope + | +help: you might be missing a type parameter + | +LL | fn check/**/() + | +++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. From b1483e347cd1152851def06910486635dd381772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Wed, 17 Jun 2026 13:07:22 +0200 Subject: [PATCH 10/42] Update mingw-w64 C toolchain --- src/ci/scripts/install-mingw.sh | 4 ++-- src/doc/rustc/src/platform-support/windows-gnu.md | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/ci/scripts/install-mingw.sh b/src/ci/scripts/install-mingw.sh index 17bedaa7b8266..470ef4ffea433 100755 --- a/src/ci/scripts/install-mingw.sh +++ b/src/ci/scripts/install-mingw.sh @@ -6,8 +6,8 @@ IFS=$'\n\t' source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" -MINGW_ARCHIVE_32="i686-14.1.0-release-posix-dwarf-msvcrt-rt_v12-rev0.7z" -MINGW_ARCHIVE_64="x86_64-14.1.0-release-posix-seh-msvcrt-rt_v12-rev0.7z" +MINGW_ARCHIVE_32="i686-14.2.0-release-posix-dwarf-msvcrt-rt_v12-rev2.7z" +MINGW_ARCHIVE_64="x86_64-14.2.0-release-posix-seh-msvcrt-rt_v12-rev2.7z" LLVM_MINGW_ARCHIVE_AARCH64="llvm-mingw-20251104-ucrt-aarch64.zip" LLVM_MINGW_ARCHIVE_X86_64="llvm-mingw-20251104-ucrt-x86_64.zip" diff --git a/src/doc/rustc/src/platform-support/windows-gnu.md b/src/doc/rustc/src/platform-support/windows-gnu.md index a867ebcfe2539..d7aec5af21dec 100644 --- a/src/doc/rustc/src/platform-support/windows-gnu.md +++ b/src/doc/rustc/src/platform-support/windows-gnu.md @@ -26,6 +26,18 @@ They follow Windows calling convention for `extern "C"`. Like with any other Windows target, created binaries are in PE format. +### C toolchain + +The targets are built and tested using a reasonably modern C toolchain, and it should be considered as the oldest supported version: + +* GNU Binutils 2.44 +* GCC 14.2 +* mingw-w64 12.0.0 +* MSVCRT library as the default + +Using older tools (especially Binutils) may not work properly, due to the number of issues plaguing older versions of Binutils. +The supported toolchain versions are subject to change. + ## Building Rust programs Rust does ship a pre-compiled std library for those targets. From b1403bc9f6cf3c0218c74ee8cbbb1e945bb52463 Mon Sep 17 00:00:00 2001 From: danieljofficial Date: Fri, 5 Jun 2026 13:59:31 +0100 Subject: [PATCH 11/42] Move derive tests out of tests/ui/issues --- .../{issues/issue-28561.rs => derives/derive-compound-arities.rs} | 0 .../derive-error-identifies-unsafe-trait-name.rs} | 0 .../derive-error-identifies-unsafe-trait-name.stderr} | 0 .../derived-trait-requires-field-impl.rs} | 0 .../derived-trait-requires-field-impl.stderr} | 0 .../no-ice-on-derived-copy-with-associated-type-field.rs} | 0 .../no-ice-on-path-style-derive-macro.rs} | 0 .../no-ice-on-path-style-derive-macro.stderr} | 0 .../no-spurious-unused-variable-warning-on-derive-hash.rs} | 0 9 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{issues/issue-28561.rs => derives/derive-compound-arities.rs} (100%) rename tests/ui/{issues/issue-33571.rs => derives/derive-error-identifies-unsafe-trait-name.rs} (100%) rename tests/ui/{issues/issue-33571.stderr => derives/derive-error-identifies-unsafe-trait-name.stderr} (100%) rename tests/ui/{issues/issue-27340.rs => derives/derived-trait-requires-field-impl.rs} (100%) rename tests/ui/{issues/issue-27340.stderr => derives/derived-trait-requires-field-impl.stderr} (100%) rename tests/ui/{issues/issue-32324.rs => derives/no-ice-on-derived-copy-with-associated-type-field.rs} (100%) rename tests/ui/{issues/issue-46101.rs => derives/no-ice-on-path-style-derive-macro.rs} (100%) rename tests/ui/{issues/issue-46101.stderr => derives/no-ice-on-path-style-derive-macro.stderr} (100%) rename tests/ui/{issues/issue-32292.rs => derives/no-spurious-unused-variable-warning-on-derive-hash.rs} (100%) diff --git a/tests/ui/issues/issue-28561.rs b/tests/ui/derives/derive-compound-arities.rs similarity index 100% rename from tests/ui/issues/issue-28561.rs rename to tests/ui/derives/derive-compound-arities.rs diff --git a/tests/ui/issues/issue-33571.rs b/tests/ui/derives/derive-error-identifies-unsafe-trait-name.rs similarity index 100% rename from tests/ui/issues/issue-33571.rs rename to tests/ui/derives/derive-error-identifies-unsafe-trait-name.rs diff --git a/tests/ui/issues/issue-33571.stderr b/tests/ui/derives/derive-error-identifies-unsafe-trait-name.stderr similarity index 100% rename from tests/ui/issues/issue-33571.stderr rename to tests/ui/derives/derive-error-identifies-unsafe-trait-name.stderr diff --git a/tests/ui/issues/issue-27340.rs b/tests/ui/derives/derived-trait-requires-field-impl.rs similarity index 100% rename from tests/ui/issues/issue-27340.rs rename to tests/ui/derives/derived-trait-requires-field-impl.rs diff --git a/tests/ui/issues/issue-27340.stderr b/tests/ui/derives/derived-trait-requires-field-impl.stderr similarity index 100% rename from tests/ui/issues/issue-27340.stderr rename to tests/ui/derives/derived-trait-requires-field-impl.stderr diff --git a/tests/ui/issues/issue-32324.rs b/tests/ui/derives/no-ice-on-derived-copy-with-associated-type-field.rs similarity index 100% rename from tests/ui/issues/issue-32324.rs rename to tests/ui/derives/no-ice-on-derived-copy-with-associated-type-field.rs diff --git a/tests/ui/issues/issue-46101.rs b/tests/ui/derives/no-ice-on-path-style-derive-macro.rs similarity index 100% rename from tests/ui/issues/issue-46101.rs rename to tests/ui/derives/no-ice-on-path-style-derive-macro.rs diff --git a/tests/ui/issues/issue-46101.stderr b/tests/ui/derives/no-ice-on-path-style-derive-macro.stderr similarity index 100% rename from tests/ui/issues/issue-46101.stderr rename to tests/ui/derives/no-ice-on-path-style-derive-macro.stderr diff --git a/tests/ui/issues/issue-32292.rs b/tests/ui/derives/no-spurious-unused-variable-warning-on-derive-hash.rs similarity index 100% rename from tests/ui/issues/issue-32292.rs rename to tests/ui/derives/no-spurious-unused-variable-warning-on-derive-hash.rs From 68f9f5ac8143a2dbce8872d2f4d509a66fa8551c Mon Sep 17 00:00:00 2001 From: danieljofficial Date: Fri, 5 Jun 2026 14:52:29 +0100 Subject: [PATCH 12/42] add issue links and bless --- tests/ui/derives/derive-compound-arities.rs | 1 + .../derives/derive-error-identifies-unsafe-trait-name.rs | 1 + .../derive-error-identifies-unsafe-trait-name.stderr | 8 ++++---- tests/ui/derives/derived-trait-requires-field-impl.rs | 1 + tests/ui/derives/derived-trait-requires-field-impl.stderr | 4 ++-- tests/ui/derives/hash-on-compound-types.rs | 3 +-- .../no-ice-on-derived-copy-with-associated-type-field.rs | 1 + tests/ui/derives/no-ice-on-path-style-derive-macro.rs | 1 + tests/ui/derives/no-ice-on-path-style-derive-macro.stderr | 4 ++-- .../no-spurious-unused-variable-warning-on-derive-hash.rs | 1 + 10 files changed, 15 insertions(+), 10 deletions(-) diff --git a/tests/ui/derives/derive-compound-arities.rs b/tests/ui/derives/derive-compound-arities.rs index 642b2193a4f9b..704d6747f7e07 100644 --- a/tests/ui/derives/derive-compound-arities.rs +++ b/tests/ui/derives/derive-compound-arities.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/28561 //@ check-pass #[derive(Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd, Clone, Copy)] struct Array { diff --git a/tests/ui/derives/derive-error-identifies-unsafe-trait-name.rs b/tests/ui/derives/derive-error-identifies-unsafe-trait-name.rs index 2713f47ad2ff6..586c5acf21611 100644 --- a/tests/ui/derives/derive-error-identifies-unsafe-trait-name.rs +++ b/tests/ui/derives/derive-error-identifies-unsafe-trait-name.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/33571 #[derive(Clone, Sync, //~ ERROR cannot find derive macro `Sync` in this scope //~| ERROR cannot find derive macro `Sync` in this scope diff --git a/tests/ui/derives/derive-error-identifies-unsafe-trait-name.stderr b/tests/ui/derives/derive-error-identifies-unsafe-trait-name.stderr index 819a533ddbe2f..862571cb2aecd 100644 --- a/tests/ui/derives/derive-error-identifies-unsafe-trait-name.stderr +++ b/tests/ui/derives/derive-error-identifies-unsafe-trait-name.stderr @@ -1,23 +1,23 @@ error: cannot find derive macro `Sync` in this scope - --> $DIR/issue-33571.rs:2:10 + --> $DIR/derive-error-identifies-unsafe-trait-name.rs:3:10 | LL | Sync, | ^^^^ | note: unsafe traits like `Sync` should be implemented explicitly - --> $DIR/issue-33571.rs:2:10 + --> $DIR/derive-error-identifies-unsafe-trait-name.rs:3:10 | LL | Sync, | ^^^^ error: cannot find derive macro `Sync` in this scope - --> $DIR/issue-33571.rs:2:10 + --> $DIR/derive-error-identifies-unsafe-trait-name.rs:3:10 | LL | Sync, | ^^^^ | note: unsafe traits like `Sync` should be implemented explicitly - --> $DIR/issue-33571.rs:2:10 + --> $DIR/derive-error-identifies-unsafe-trait-name.rs:3:10 | LL | Sync, | ^^^^ diff --git a/tests/ui/derives/derived-trait-requires-field-impl.rs b/tests/ui/derives/derived-trait-requires-field-impl.rs index 9966c24a7441e..fb1a98c10d843 100644 --- a/tests/ui/derives/derived-trait-requires-field-impl.rs +++ b/tests/ui/derives/derived-trait-requires-field-impl.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/27340 struct Foo; #[derive(Copy, Clone)] struct Bar(Foo); diff --git a/tests/ui/derives/derived-trait-requires-field-impl.stderr b/tests/ui/derives/derived-trait-requires-field-impl.stderr index 3b4ad58b1f080..6ca75fac56937 100644 --- a/tests/ui/derives/derived-trait-requires-field-impl.stderr +++ b/tests/ui/derives/derived-trait-requires-field-impl.stderr @@ -1,5 +1,5 @@ error[E0204]: the trait `Copy` cannot be implemented for this type - --> $DIR/issue-27340.rs:3:8 + --> $DIR/derived-trait-requires-field-impl.rs:4:8 | LL | #[derive(Copy, Clone)] | ---- in this derive macro expansion @@ -7,7 +7,7 @@ LL | struct Bar(Foo); | ^^^ --- this field does not implement `Copy` error[E0277]: the trait bound `Foo: Clone` is not satisfied - --> $DIR/issue-27340.rs:3:12 + --> $DIR/derived-trait-requires-field-impl.rs:4:12 | LL | #[derive(Copy, Clone)] | ----- in this derive macro expansion diff --git a/tests/ui/derives/hash-on-compound-types.rs b/tests/ui/derives/hash-on-compound-types.rs index 6d950df99d65c..be7094bccc4c3 100644 --- a/tests/ui/derives/hash-on-compound-types.rs +++ b/tests/ui/derives/hash-on-compound-types.rs @@ -1,5 +1,4 @@ -//! Regression test for . - +//! Regression test for https://github.com/rust-lang/rust/issues/21402 //@ check-pass #![allow(dead_code)] diff --git a/tests/ui/derives/no-ice-on-derived-copy-with-associated-type-field.rs b/tests/ui/derives/no-ice-on-derived-copy-with-associated-type-field.rs index 50ecfe993d438..755ec1f9d5229 100644 --- a/tests/ui/derives/no-ice-on-derived-copy-with-associated-type-field.rs +++ b/tests/ui/derives/no-ice-on-derived-copy-with-associated-type-field.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/32324 //@ check-pass #![allow(dead_code)] diff --git a/tests/ui/derives/no-ice-on-path-style-derive-macro.rs b/tests/ui/derives/no-ice-on-path-style-derive-macro.rs index 86b06f7c61d0a..664fe3f241115 100644 --- a/tests/ui/derives/no-ice-on-path-style-derive-macro.rs +++ b/tests/ui/derives/no-ice-on-path-style-derive-macro.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/46101 trait Foo {} #[derive(Foo::Anything)] //~ ERROR cannot find //~| ERROR cannot find diff --git a/tests/ui/derives/no-ice-on-path-style-derive-macro.stderr b/tests/ui/derives/no-ice-on-path-style-derive-macro.stderr index 1dada87d72d64..3e05d7b384704 100644 --- a/tests/ui/derives/no-ice-on-path-style-derive-macro.stderr +++ b/tests/ui/derives/no-ice-on-path-style-derive-macro.stderr @@ -1,11 +1,11 @@ error[E0433]: cannot find derive macro `Anything` in trait `Foo` - --> $DIR/issue-46101.rs:2:10 + --> $DIR/no-ice-on-path-style-derive-macro.rs:3:10 | LL | #[derive(Foo::Anything)] | ^^^^^^^^^^^^^ a derive macro can't exist within a trait error[E0433]: cannot find derive macro `Anything` in trait `Foo` - --> $DIR/issue-46101.rs:2:10 + --> $DIR/no-ice-on-path-style-derive-macro.rs:3:10 | LL | #[derive(Foo::Anything)] | ^^^^^^^^^^^^^ a derive macro can't exist within a trait diff --git a/tests/ui/derives/no-spurious-unused-variable-warning-on-derive-hash.rs b/tests/ui/derives/no-spurious-unused-variable-warning-on-derive-hash.rs index 2181dff505ace..4609730dff385 100644 --- a/tests/ui/derives/no-spurious-unused-variable-warning-on-derive-hash.rs +++ b/tests/ui/derives/no-spurious-unused-variable-warning-on-derive-hash.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/32292 //@ run-pass #![deny(warnings)] From a09fc01c54cb4ba2e085612f8553fb43484964c0 Mon Sep 17 00:00:00 2001 From: Dnreikronos Date: Fri, 19 Jun 2026 14:57:58 -0300 Subject: [PATCH 13/42] Avoid forcing index operand inference Adjust ambiguous index diagnostics without adding new index operand resolution points. Keep invalid operator and mismatched operand diagnostics on the operator while still pointing valid ambiguous index cases at the index operand. --- compiler/rustc_hir_typeck/src/cast.rs | 33 +++-- .../src/fn_ctxt/adjust_fulfillment_errors.rs | 122 +++++++++++++++++- compiler/rustc_hir_typeck/src/op.rs | 9 -- .../index-expr-ambiguous-type.rs | 24 ++++ .../index-expr-ambiguous-type.stderr | 60 ++++++--- 5 files changed, 208 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 97ff7765896a8..8140788a7d988 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -725,23 +725,21 @@ impl<'a, 'tcx> CastCheck<'tcx> { ); } - #[instrument(skip(fcx), level = "debug")] - pub(crate) fn check(mut self, fcx: &FnCtxt<'a, 'tcx>) { + fn expr_span_for_type_resolution(&self, fcx: &FnCtxt<'a, 'tcx>) -> Span { if let hir::ExprKind::Index(_, idx, _) = self.expr.kind - && self.expr_ty.has_infer() + && fcx.resolve_vars_if_possible(self.expr_ty).is_ty_var() + && fcx.resolve_vars_if_possible(fcx.node_ty(idx.hir_id)).is_ty_var() { - let idx_ty = fcx.resolve_vars_if_possible(fcx.node_ty(idx.hir_id)); - if idx_ty.is_ty_var() { - let resolved = fcx.structurally_resolve_type(idx.span, idx_ty); - if resolved.references_error() { - self.expr_ty = resolved; - } - } - } - // Skip if idx resolution above already emitted a diagnostic and set expr_ty to error. - if !self.expr_ty.references_error() { - self.expr_ty = fcx.structurally_resolve_type(self.expr_span, self.expr_ty); + index_operand_ambiguity_span(idx) + } else { + self.expr_span } + } + + #[instrument(skip(fcx), level = "debug")] + pub(crate) fn check(mut self, fcx: &FnCtxt<'a, 'tcx>) { + let expr_span = self.expr_span_for_type_resolution(fcx); + self.expr_ty = fcx.structurally_resolve_type(expr_span, self.expr_ty); self.cast_ty = fcx.structurally_resolve_type(self.cast_span, self.cast_ty); debug!("check_cast({}, {:?} as {:?})", self.expr.hir_id, self.expr_ty, self.cast_ty); @@ -1222,3 +1220,10 @@ impl<'a, 'tcx> CastCheck<'tcx> { } } } + +fn index_operand_ambiguity_span(expr: &hir::Expr<'_>) -> Span { + match expr.kind { + hir::ExprKind::MethodCall(segment, ..) => segment.ident.span, + _ => expr.span, + } +} diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index 825aa37065e15..2d436ec82b20e 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -4,8 +4,11 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_infer::traits::ObligationCauseCode; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; +use rustc_middle::ty::{ + self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, +}; use rustc_span::{Span, kw}; +use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits; use crate::FnCtxt; @@ -37,6 +40,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, error: &mut traits::FulfillmentError<'tcx>, ) -> bool { + if self.adjust_binop_index_operand(error) { + return true; + } + let (def_id, hir_id, idx, flavor) = match *error.obligation.cause.code().peel_derives() { ObligationCauseCode::WhereClauseInExpr(def_id, _, hir_id, idx) => { (def_id, hir_id, idx, ClauseFlavor::Where) @@ -165,6 +172,119 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + fn adjust_binop_index_operand(&self, error: &mut traits::FulfillmentError<'tcx>) -> bool { + let ObligationCauseCode::BinOp { lhs_hir_id, rhs_hir_id, .. } = + *error.obligation.cause.code().peel_derives() + else { + return false; + }; + if !matches!(error.code, traits::FulfillmentErrorCode::Ambiguity { .. }) + || !error.obligation.predicate.has_infer() + { + return false; + } + + let hir::Node::Expr(lhs_expr) = self.tcx.hir_node(lhs_hir_id) else { + return false; + }; + let hir::Node::Expr(rhs_expr) = self.tcx.hir_node(rhs_hir_id) else { + return false; + }; + let Some(binop) = self.binop_for_operands(lhs_hir_id, rhs_hir_id) else { + return false; + }; + let hir::ExprKind::Index(indexed_expr, idx, _) = rhs_expr.kind else { + return false; + }; + if !self.resolve_vars_if_possible(self.node_ty(idx.hir_id)).is_ty_var() { + return false; + } + let lhs_ty = self.resolve_vars_if_possible(self.node_ty(lhs_expr.hir_id)); + let indexed_ty = self.resolve_vars_if_possible(self.node_ty(indexed_expr.hir_id)); + let rhs_ty = match *indexed_ty.kind() { + ty::Array(element_ty, _) | ty::Slice(element_ty) => element_ty, + ty::Ref(_, pointee_ty, _) => match *pointee_ty.kind() { + ty::Array(element_ty, _) | ty::Slice(element_ty) => element_ty, + _ => self.resolve_vars_if_possible(self.node_ty(rhs_expr.hir_id)), + }, + _ => self.resolve_vars_if_possible(self.node_ty(rhs_expr.hir_id)), + }; + if !self.binop_accepts_types(binop.node, lhs_ty, rhs_ty) { + return false; + } + + error.obligation.cause.span = match idx.kind { + hir::ExprKind::MethodCall(segment, ..) => segment.ident.span, + _ => idx.span, + }; + true + } + + fn binop_for_operands( + &self, + lhs_hir_id: hir::HirId, + rhs_hir_id: hir::HirId, + ) -> Option { + let hir::Node::Expr(parent_expr) = self.tcx.parent_hir_node(rhs_hir_id) else { + return None; + }; + let hir::ExprKind::Binary(binop, lhs_expr, rhs_expr) = parent_expr.kind else { + return None; + }; + (lhs_expr.hir_id == lhs_hir_id && rhs_expr.hir_id == rhs_hir_id).then_some(binop) + } + + fn binop_accepts_types( + &self, + binop: hir::BinOpKind, + lhs_ty: Ty<'tcx>, + rhs_ty: Ty<'tcx>, + ) -> bool { + let lhs_ty = self.deref_ty_if_possible(lhs_ty); + let rhs_ty = self.deref_ty_if_possible(rhs_ty); + if lhs_ty.references_error() || rhs_ty.references_error() { + return true; + } + + match binop { + hir::BinOpKind::Shl | hir::BinOpKind::Shr => { + lhs_ty.is_integral() && rhs_ty.is_integral() + } + hir::BinOpKind::Add + | hir::BinOpKind::Sub + | hir::BinOpKind::Mul + | hir::BinOpKind::Div + | hir::BinOpKind::Rem => { + self.can_eq(self.param_env, lhs_ty, rhs_ty) + && (lhs_ty.is_integral() || lhs_ty.is_floating_point()) + && (rhs_ty.is_integral() || rhs_ty.is_floating_point()) + } + hir::BinOpKind::BitXor | hir::BinOpKind::BitAnd | hir::BinOpKind::BitOr => { + self.can_eq(self.param_env, lhs_ty, rhs_ty) + && ((lhs_ty.is_integral() && rhs_ty.is_integral()) + || (lhs_ty.is_bool() && rhs_ty.is_bool())) + } + hir::BinOpKind::Eq + | hir::BinOpKind::Ne + | hir::BinOpKind::Lt + | hir::BinOpKind::Le + | hir::BinOpKind::Ge + | hir::BinOpKind::Gt => { + self.can_eq(self.param_env, lhs_ty, rhs_ty) + && lhs_ty.is_scalar() + && rhs_ty.is_scalar() + } + hir::BinOpKind::And | hir::BinOpKind::Or => lhs_ty.is_bool() && rhs_ty.is_bool(), + } + } + + fn deref_ty_if_possible(&self, ty: Ty<'tcx>) -> Ty<'tcx> { + match ty.kind() { + ty::Ref(_, ty, hir::Mutability::Not) => *ty, + _ => ty, + } + } + fn point_at_expr_if_possible( &self, error: &mut traits::FulfillmentError<'tcx>, diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index 0a67b384ae8de..88a4241398ed8 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -314,15 +314,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method); - if method.sig.output().has_infer() - && let hir::ExprKind::Index(_, idx, _) = rhs_expr.kind - { - let idx_ty = self.resolve_vars_if_possible(self.node_ty(idx.hir_id)); - if idx_ty.is_ty_var() { - self.structurally_resolve_type(idx.span, idx_ty); - } - } - method.sig.output() } // error types are considered "builtin" diff --git a/tests/ui/type-inference/index-expr-ambiguous-type.rs b/tests/ui/type-inference/index-expr-ambiguous-type.rs index 32b45703e2003..061699c8a013f 100644 --- a/tests/ui/type-inference/index-expr-ambiguous-type.rs +++ b/tests/ui/type-inference/index-expr-ambiguous-type.rs @@ -27,4 +27,28 @@ fn with_known_index_type() { let _foo = [1, 2, 3][Into::::into(bad_idx)] as i32; } +fn invalid_operator_with_ambiguous_index() { + let bad_idx = 0u8; + let _foo = true + [1, 2, 3][bad_idx.into()]; + //~^ ERROR cannot add +} + +fn mismatched_numeric_binop_with_ambiguous_index() { + let bad_idx = 0u8; + let _foo = 0u64 + [1i32, 2, 3][bad_idx.into()]; + //~^ ERROR type annotations needed +} + +fn shift_with_ambiguous_index() { + let bad_idx = 0u8; + let _foo = 1u32 << [0u8][bad_idx.into()]; + //~^ ERROR type annotations needed +} + +fn string_add_with_ambiguous_index() { + let bad_idx = 0u8; + let _foo = String::new() + [""][bad_idx.into()]; + //~^ ERROR type annotations needed +} + fn main() {} diff --git a/tests/ui/type-inference/index-expr-ambiguous-type.stderr b/tests/ui/type-inference/index-expr-ambiguous-type.stderr index 80c0aa6c4a952..83de98d80cae6 100644 --- a/tests/ui/type-inference/index-expr-ambiguous-type.stderr +++ b/tests/ui/type-inference/index-expr-ambiguous-type.stderr @@ -2,25 +2,15 @@ error[E0282]: type annotations needed --> $DIR/index-expr-ambiguous-type.rs:9:34 | LL | let _foo = [1, 2, 3][bad_idx.into()] as i32; - | ^^^^ - | -help: try using a fully qualified path to specify the expected types - | -LL - let _foo = [1, 2, 3][bad_idx.into()] as i32; -LL + let _foo = [1, 2, 3][>::into(bad_idx)] as i32; - | + | ^^^^ cannot infer type -error[E0282]: type annotations needed +error[E0284]: type annotations needed --> $DIR/index-expr-ambiguous-type.rs:15:38 | LL | let _foo = 0 + [1, 2, 3][bad_idx.into()]; - | ^^^^ - | -help: try using a fully qualified path to specify the expected types - | -LL - let _foo = 0 + [1, 2, 3][bad_idx.into()]; -LL + let _foo = 0 + [1, 2, 3][>::into(bad_idx)]; + | ^^^^ cannot infer type | + = note: cannot satisfy `>::Output == _` error[E0283]: type annotations needed --> $DIR/index-expr-ambiguous-type.rs:21:34 @@ -36,7 +26,45 @@ LL - let _foo = [1, 2, 3][bad_idx.into()]; LL + let _foo = [1, 2, 3][>::into(bad_idx)]; | -error: aborting due to 3 previous errors +error[E0369]: cannot add `_` to `bool` + --> $DIR/index-expr-ambiguous-type.rs:32:21 + | +LL | let _foo = true + [1, 2, 3][bad_idx.into()]; + | ---- ^ ------------------------- _ + | | + | bool + +error[E0284]: type annotations needed + --> $DIR/index-expr-ambiguous-type.rs:38:21 + | +LL | let _foo = 0u64 + [1i32, 2, 3][bad_idx.into()]; + | ^ cannot infer type + | + = note: cannot satisfy `>::Output == _` + +error[E0284]: type annotations needed + --> $DIR/index-expr-ambiguous-type.rs:44:38 + | +LL | let _foo = 1u32 << [0u8][bad_idx.into()]; + | ^^^^ cannot infer type + | + = note: cannot satisfy `>::Output == _` + +error[E0283]: type annotations needed + --> $DIR/index-expr-ambiguous-type.rs:50:45 + | +LL | let _foo = String::new() + [""][bad_idx.into()]; + | ^^^^ + | + = note: the type must implement `From` + = note: required for `u8` to implement `Into<_>` +help: try using a fully qualified path to specify the expected types + | +LL - let _foo = String::new() + [""][bad_idx.into()]; +LL + let _foo = String::new() + [""][>::into(bad_idx)]; + | + +error: aborting due to 7 previous errors -Some errors have detailed explanations: E0282, E0283. +Some errors have detailed explanations: E0282, E0283, E0284, E0369. For more information about an error, try `rustc --explain E0282`. From a2f80c97243067708527f1d4f5d2bb5db75e4dff Mon Sep 17 00:00:00 2001 From: Dnreikronos Date: Fri, 19 Jun 2026 17:22:18 -0300 Subject: [PATCH 14/42] Handle alias outlives ambiguity during rewrite --- .../rustc_type_ir/src/region_constraint.rs | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_type_ir/src/region_constraint.rs b/compiler/rustc_type_ir/src/region_constraint.rs index b896d7a398178..ddace4b941a43 100644 --- a/compiler/rustc_type_ir/src/region_constraint.rs +++ b/compiler/rustc_type_ir/src/region_constraint.rs @@ -654,18 +654,8 @@ fn pull_region_outlives_constraints_out_of_universe< use RegionConstraint::*; match constraint { Ambiguity | PlaceholderTyOutlives(..) | AliasTyOutlivesViaEnv(..) => { - // With only lifetime binders the rewrite step lowers these constraints out of `u` - // (or destructures them), so we expect `max_universe < u` here. A non-lifetime - // binder (`for`) instead introduces a placeholder type in `u`, which - // `PlaceholderReplacer` (region-only, see its `fold_region`) cannot pull out, - // leaving e.g. `::Assoc: 'r` stranded in `u`. The assumptions-on-binders - // machinery is region-outlives-only and can't decide such a constraint, so report - // ambiguity rather than ICE. - if max_universe(infcx, constraint.clone()) < u { - constraint - } else { - RegionConstraint::Ambiguity - } + assert!(max_universe(infcx, constraint.clone()) < u); + constraint } RegionOutlives(region_1, region_2) => { let region_1_u = max_universe(infcx, region_1); @@ -850,7 +840,15 @@ fn rewrite_type_outlives_constraints_in_universe_for_eager_placeholder_handling< escaping_outlives, I::BoundVarKinds::from_vars(infcx.cx(), bound_vars), ); - candidates.push(RegionConstraint::AliasTyOutlivesViaEnv(bound_outlives)); + let candidate = RegionConstraint::AliasTyOutlivesViaEnv(bound_outlives); + if max_universe(infcx, candidate.clone()) < u { + candidates.push(candidate); + } else { + // `PlaceholderReplacer` only folds regions. A non-lifetime binder can leave + // a placeholder type in `u`, so this type-outlives constraint cannot be + // handled by the region-outlives-only eager placeholder machinery. + candidates.push(Ambiguity); + } } let assumptions = match assumptions { @@ -895,12 +893,17 @@ fn rewrite_type_outlives_constraints_in_universe_for_eager_placeholder_handling< // while we did skip the binder, bound vars aren't in any universe so // this can't be an escaping bound var - candidates.extend( - regions_outliving(escaping_r, assumptions, infcx.cx()) - .filter(|r2| max_universe(infcx, *r2) < u) - .map(|r2| AliasTyOutlivesViaEnv(bound_alias.map_bound(|alias| (alias, r2)))) - .collect::>(), - ); + for r2 in regions_outliving(escaping_r, assumptions, infcx.cx()) + .filter(|r2| max_universe(infcx, *r2) < u) + { + let candidate = + AliasTyOutlivesViaEnv(bound_alias.map_bound(|alias| (alias, r2))); + if max_universe(infcx, candidate.clone()) < u { + candidates.push(candidate); + } else { + candidates.push(Ambiguity); + } + } } // I'm not convinced our handling here is *complete* so for now From 3bb0a1c892df204b9cdeca8aa394e7367680db9f Mon Sep 17 00:00:00 2001 From: Dnreikronos Date: Sat, 20 Jun 2026 15:54:57 -0300 Subject: [PATCH 15/42] Resolve vars before computing max universe --- compiler/rustc_type_ir/src/region_constraint.rs | 14 ++++---------- .../resolved-region-var-max-universe.rs | 8 +++++--- .../resolved-region-var-max-universe.stderr | 4 ++-- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_type_ir/src/region_constraint.rs b/compiler/rustc_type_ir/src/region_constraint.rs index 6f13eedda4983..3bc0502b4f3cb 100644 --- a/compiler/rustc_type_ir/src/region_constraint.rs +++ b/compiler/rustc_type_ir/src/region_constraint.rs @@ -978,11 +978,14 @@ pub fn regions_outlived_by_placeholder( } /// The largest universe a variable or placeholder was from in `t` -pub fn max_universe, I: Interner, T: TypeVisitable>( +pub fn max_universe, I: Interner, T: TypeFoldable>( infcx: &Infcx, t: T, ) -> UniverseIndex { let mut visitor = MaxUniverse::new(infcx); + // `max_universe` is also used while rewriting constraints to lower universes, + // so do not rely on callers having already resolved non-region infer vars. + let t = infcx.resolve_vars_if_possible(t); t.visit_with(&mut visitor); visitor.max_universe() } @@ -1013,10 +1016,6 @@ impl<'a, Infcx: InferCtxtLike, I: Interner> TypeVisitor match t.kind() { TyKind::Placeholder(p) => self.max_universe = self.max_universe.max(p.universe), TyKind::Infer(InferTy::TyVar(inf)) => { - // Unlike `visit_region`, we don't resolve the variable first: callers - // computing assumptions bail on any non-region inference variable - // before reaching here, so a type infer var is always unresolved and - // has a universe. let u = self.infcx.universe_of_ty(inf).unwrap(); debug!("var {inf:?} in universe {u:?}"); self.max_universe = self.max_universe.max(u); @@ -1029,8 +1028,6 @@ impl<'a, Infcx: InferCtxtLike, I: Interner> TypeVisitor match c.kind() { ConstKind::Placeholder(p) => self.max_universe = self.max_universe.max(p.universe), ConstKind::Infer(rustc_type_ir::InferConst::Var(inf)) => { - // See the comment in `visit_ty`: a const infer var is always - // unresolved here, so unlike a region it needs no resolving first. let u = self.infcx.universe_of_ct(inf).unwrap(); debug!("var {inf:?} in universe {u:?}"); self.max_universe = self.max_universe.max(u); @@ -1043,9 +1040,6 @@ impl<'a, Infcx: InferCtxtLike, I: Interner> TypeVisitor match r.kind() { RegionKind::RePlaceholder(p) => self.max_universe = self.max_universe.max(p.universe), RegionKind::ReVar(var) => { - // The variable may already have been unified with another region. - // `universe_of_lt` returns `None` for a resolved variable, so resolve - // it first and inspect whatever it points at. match self.infcx.opportunistic_resolve_lt_var(var).kind() { RegionKind::RePlaceholder(p) => { self.max_universe = self.max_universe.max(p.universe) diff --git a/tests/ui/assumptions_on_binders/resolved-region-var-max-universe.rs b/tests/ui/assumptions_on_binders/resolved-region-var-max-universe.rs index f0286fb92453a..46c9aacdd93d9 100644 --- a/tests/ui/assumptions_on_binders/resolved-region-var-max-universe.rs +++ b/tests/ui/assumptions_on_binders/resolved-region-var-max-universe.rs @@ -3,8 +3,10 @@ // Regression test for an ICE in the `MaxUniverse` region visitor. When computing // the max universe of a region constraint, a `ReVar` term could already have been // unified with another region. `universe_of_lt` returns `None` for such a resolved -// variable, so the visitor used to `unwrap()` `None` and panic. It now resolves the -// variable before inspecting its universe. +// variable, so the visitor used to `unwrap()` `None` and panic. +// +// The missing `T` in `check` is intentional. It makes HIR ty lowering emit an +// error while still leaving behind the region constraint that used to ICE. #![feature(min_generic_const_args, inherent_associated_types, generic_const_items)] @@ -16,7 +18,7 @@ impl<'a> Parent<'a> { type const CT: usize = 0; } -fn check/**/() +fn check() where [(); Parent::CT::]:, //~^ ERROR cannot find type `T` in this scope diff --git a/tests/ui/assumptions_on_binders/resolved-region-var-max-universe.stderr b/tests/ui/assumptions_on_binders/resolved-region-var-max-universe.stderr index 6fa91876dd47b..e77a0994fc2db 100644 --- a/tests/ui/assumptions_on_binders/resolved-region-var-max-universe.stderr +++ b/tests/ui/assumptions_on_binders/resolved-region-var-max-universe.stderr @@ -1,12 +1,12 @@ error[E0425]: cannot find type `T` in this scope - --> $DIR/resolved-region-var-max-universe.rs:21:23 + --> $DIR/resolved-region-var-max-universe.rs:23:23 | LL | [(); Parent::CT::]:, | ^ not found in this scope | help: you might be missing a type parameter | -LL | fn check/**/() +LL | fn check() | +++ error: aborting due to 1 previous error From a44ab8d43042ffe67ab5e288a765f181d4474dc4 Mon Sep 17 00:00:00 2001 From: Dnreikronos Date: Sat, 20 Jun 2026 16:05:13 -0300 Subject: [PATCH 16/42] Format max universe visitor --- .../rustc_type_ir/src/region_constraint.rs | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_type_ir/src/region_constraint.rs b/compiler/rustc_type_ir/src/region_constraint.rs index 3bc0502b4f3cb..2ba2d40f3a540 100644 --- a/compiler/rustc_type_ir/src/region_constraint.rs +++ b/compiler/rustc_type_ir/src/region_constraint.rs @@ -1039,19 +1039,17 @@ impl<'a, Infcx: InferCtxtLike, I: Interner> TypeVisitor fn visit_region(&mut self, r: I::Region) { match r.kind() { RegionKind::RePlaceholder(p) => self.max_universe = self.max_universe.max(p.universe), - RegionKind::ReVar(var) => { - match self.infcx.opportunistic_resolve_lt_var(var).kind() { - RegionKind::RePlaceholder(p) => { - self.max_universe = self.max_universe.max(p.universe) - } - RegionKind::ReVar(var) => { - let u = self.infcx.universe_of_lt(var).unwrap(); - debug!("var {var:?} in universe {u:?}"); - self.max_universe = self.max_universe.max(u); - } - _ => (), + RegionKind::ReVar(var) => match self.infcx.opportunistic_resolve_lt_var(var).kind() { + RegionKind::RePlaceholder(p) => { + self.max_universe = self.max_universe.max(p.universe) } - } + RegionKind::ReVar(var) => { + let u = self.infcx.universe_of_lt(var).unwrap(); + debug!("var {var:?} in universe {u:?}"); + self.max_universe = self.max_universe.max(u); + } + _ => (), + }, _ => (), } } From e7b8d13714f087dbc0bdeb30db2c3b17ea71b99e Mon Sep 17 00:00:00 2001 From: Dnreikronos Date: Sun, 21 Jun 2026 14:55:15 -0300 Subject: [PATCH 17/42] Ignore println newline in foreign format hints --- compiler/rustc_builtin_macros/src/format.rs | 4 +++- .../format-foreign-dollar-without-spec.stderr | 14 ++++++-------- tests/ui/macros/issue-92267.stderr | 14 ++++++-------- .../trailing-percent-format-hint-issue-158216.rs | 7 +++++++ ...railing-percent-format-hint-issue-158216.stderr | 14 ++++++++++++++ 5 files changed, 36 insertions(+), 17 deletions(-) create mode 100644 tests/ui/macros/trailing-percent-format-hint-issue-158216.rs create mode 100644 tests/ui/macros/trailing-percent-format-hint-issue-158216.stderr diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 007251ff3df05..89ea581d34d60 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -607,6 +607,8 @@ fn make_format_args( // If there's a lot of unused arguments, // let's check if this format arguments looks like another syntax (printf / shell). let detect_foreign_fmt = unused.len() > args.explicit_args().len() / 2; + let foreign_fmt_str = + if append_newline { fmt_str.strip_suffix('\n').unwrap_or(fmt_str) } else { fmt_str }; report_missing_placeholders( ecx, unused, @@ -616,7 +618,7 @@ fn make_format_args( &invalid_refs, detect_foreign_fmt, str_style, - fmt_str, + foreign_fmt_str, uncooked_fmt_str.1.as_str(), fmt_span, ); diff --git a/tests/ui/macros/format-foreign-dollar-without-spec.stderr b/tests/ui/macros/format-foreign-dollar-without-spec.stderr index d5a07c50f00d0..87d86061188af 100644 --- a/tests/ui/macros/format-foreign-dollar-without-spec.stderr +++ b/tests/ui/macros/format-foreign-dollar-without-spec.stderr @@ -2,15 +2,13 @@ error: argument never used --> $DIR/format-foreign-dollar-without-spec.rs:3:25 | LL | println!("%65536$", 1); - | ^ argument never used + | --------- ^ argument never used + | | + | formatting specifier missing | -note: format specifiers use curly braces, and the conversion specifier ` - ` is unknown or unsupported - --> $DIR/format-foreign-dollar-without-spec.rs:3:15 +help: format specifiers use curly braces, consider adding a format specifier | -LL | println!("%65536$", 1); - | ^^^^^^^^ - = note: printf formatting is not supported; see the documentation for `std::fmt` +LL | println!("%65536${}", 1); + | ++ error: aborting due to 1 previous error - diff --git a/tests/ui/macros/issue-92267.stderr b/tests/ui/macros/issue-92267.stderr index 4259815328b30..8f8d345f51b5f 100644 --- a/tests/ui/macros/issue-92267.stderr +++ b/tests/ui/macros/issue-92267.stderr @@ -2,15 +2,13 @@ error: argument never used --> $DIR/issue-92267.rs:3:34 | LL | pub fn main() { println!("🦀%%%", 0) } - | ^ argument never used + | ------- ^ argument never used + | | + | formatting specifier missing | -note: format specifiers use curly braces, and the conversion specifier ` - ` is unknown or unsupported - --> $DIR/issue-92267.rs:3:30 +help: format specifiers use curly braces, consider adding a format specifier | -LL | pub fn main() { println!("🦀%%%", 0) } - | ^^ - = note: printf formatting is not supported; see the documentation for `std::fmt` +LL | pub fn main() { println!("🦀%%%{}", 0) } + | ++ error: aborting due to 1 previous error - diff --git a/tests/ui/macros/trailing-percent-format-hint-issue-158216.rs b/tests/ui/macros/trailing-percent-format-hint-issue-158216.rs new file mode 100644 index 0000000000000..bebea2dfe48c6 --- /dev/null +++ b/tests/ui/macros/trailing-percent-format-hint-issue-158216.rs @@ -0,0 +1,7 @@ +//@ check-fail +//@ compile-flags: --crate-type=lib + +pub fn f(x: f64) { + println!("{x:>8.2}%", "foo"); + //~^ ERROR argument never used +} diff --git a/tests/ui/macros/trailing-percent-format-hint-issue-158216.stderr b/tests/ui/macros/trailing-percent-format-hint-issue-158216.stderr new file mode 100644 index 0000000000000..2b18d0193441d --- /dev/null +++ b/tests/ui/macros/trailing-percent-format-hint-issue-158216.stderr @@ -0,0 +1,14 @@ +error: argument never used + --> $DIR/trailing-percent-format-hint-issue-158216.rs:5:27 + | +LL | println!("{x:>8.2}%", "foo"); + | ----------- ^^^^^ argument never used + | | + | formatting specifier missing + | +help: format specifiers use curly braces, consider adding a format specifier + | +LL | println!("{x:>8.2}%{}", "foo"); + | ++ + +error: aborting due to 1 previous error From 56dfba726240149fc2e67d4ac37f2d72ebbf0e1c Mon Sep 17 00:00:00 2001 From: Dnreikronos Date: Sun, 21 Jun 2026 16:50:20 -0300 Subject: [PATCH 18/42] Update foreign format UI baselines --- tests/ui/macros/format-foreign-dollar-without-spec.stderr | 1 + tests/ui/macros/issue-92267.stderr | 5 +++-- .../macros/trailing-percent-format-hint-issue-158216.stderr | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/ui/macros/format-foreign-dollar-without-spec.stderr b/tests/ui/macros/format-foreign-dollar-without-spec.stderr index 87d86061188af..c4c241048abb0 100644 --- a/tests/ui/macros/format-foreign-dollar-without-spec.stderr +++ b/tests/ui/macros/format-foreign-dollar-without-spec.stderr @@ -12,3 +12,4 @@ LL | println!("%65536${}", 1); | ++ error: aborting due to 1 previous error + diff --git a/tests/ui/macros/issue-92267.stderr b/tests/ui/macros/issue-92267.stderr index 8f8d345f51b5f..7bbbb28cdacad 100644 --- a/tests/ui/macros/issue-92267.stderr +++ b/tests/ui/macros/issue-92267.stderr @@ -1,14 +1,15 @@ error: argument never used --> $DIR/issue-92267.rs:3:34 | -LL | pub fn main() { println!("🦀%%%", 0) } +LL | pub fn main() { println!("🦀%%%", 0) } //~ ERROR argument never used | ------- ^ argument never used | | | formatting specifier missing | help: format specifiers use curly braces, consider adding a format specifier | -LL | pub fn main() { println!("🦀%%%{}", 0) } +LL | pub fn main() { println!("🦀%%%{}", 0) } //~ ERROR argument never used | ++ error: aborting due to 1 previous error + diff --git a/tests/ui/macros/trailing-percent-format-hint-issue-158216.stderr b/tests/ui/macros/trailing-percent-format-hint-issue-158216.stderr index 2b18d0193441d..b5c120f939b40 100644 --- a/tests/ui/macros/trailing-percent-format-hint-issue-158216.stderr +++ b/tests/ui/macros/trailing-percent-format-hint-issue-158216.stderr @@ -12,3 +12,4 @@ LL | println!("{x:>8.2}%{}", "foo"); | ++ error: aborting due to 1 previous error + From 356c63f036093b4e6e3a8bf4102c106f84f5e21c Mon Sep 17 00:00:00 2001 From: Dnreikronos Date: Sun, 21 Jun 2026 17:59:29 -0300 Subject: [PATCH 19/42] Correct issue 92267 UI baseline --- tests/ui/macros/issue-92267.stderr | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/ui/macros/issue-92267.stderr b/tests/ui/macros/issue-92267.stderr index 7bbbb28cdacad..8f8d345f51b5f 100644 --- a/tests/ui/macros/issue-92267.stderr +++ b/tests/ui/macros/issue-92267.stderr @@ -1,15 +1,14 @@ error: argument never used --> $DIR/issue-92267.rs:3:34 | -LL | pub fn main() { println!("🦀%%%", 0) } //~ ERROR argument never used +LL | pub fn main() { println!("🦀%%%", 0) } | ------- ^ argument never used | | | formatting specifier missing | help: format specifiers use curly braces, consider adding a format specifier | -LL | pub fn main() { println!("🦀%%%{}", 0) } //~ ERROR argument never used +LL | pub fn main() { println!("🦀%%%{}", 0) } | ++ error: aborting due to 1 previous error - From 2a86b91480a420a5bfcdfc3cbb733fc390ab8e72 Mon Sep 17 00:00:00 2001 From: Dnreikronos Date: Sun, 21 Jun 2026 18:38:02 -0300 Subject: [PATCH 20/42] Update issue 92267 stderr ending --- tests/ui/macros/issue-92267.stderr | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/ui/macros/issue-92267.stderr b/tests/ui/macros/issue-92267.stderr index 8f8d345f51b5f..2318d5d565a1d 100644 --- a/tests/ui/macros/issue-92267.stderr +++ b/tests/ui/macros/issue-92267.stderr @@ -12,3 +12,4 @@ LL | pub fn main() { println!("🦀%%%{}", 0) } | ++ error: aborting due to 1 previous error + From b1e1db9ef4b8a9d6b13fc8d05cde358920793857 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 22 Jun 2026 06:55:41 +0000 Subject: [PATCH 21/42] Add tup expr arg unbounded assoc const test and update test with proper expected enum diagnostics --- .../mgca/tuple_expr_arg_bad-issue-151048.rs | 2 +- .../mgca/tuple_expr_arg_bad-issue-151048.stderr | 2 +- .../mgca/tuple_expr_arg_mismatch_type.rs | 2 +- .../mgca/tuple_expr_arg_mismatch_type.stderr | 2 +- .../mgca/tuple_expr_arg_unbounded_assoc_const.rs | 13 +++++++++++++ .../tuple_expr_arg_unbounded_assoc_const.stderr | 8 ++++++++ 6 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 tests/ui/const-generics/mgca/tuple_expr_arg_unbounded_assoc_const.rs create mode 100644 tests/ui/const-generics/mgca/tuple_expr_arg_unbounded_assoc_const.stderr diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.rs b/tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.rs index 4aecd30e86bbb..70b955589d3e7 100644 --- a/tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.rs +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.rs @@ -2,7 +2,7 @@ #![expect(incomplete_features)] struct Y { - stuff: [u8; { ([1, 2], 3, [4, 5]) }], //~ ERROR expected `usize`, found const tuple + stuff: [u8; { ([1, 2], 3, [4, 5]) }], //~ ERROR expected `usize`, found `([1, 2], 3, [4, 5])` } fn main() {} diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.stderr b/tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.stderr index 468bf703d90d4..aa54a5ae77048 100644 --- a/tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.stderr +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.stderr @@ -1,4 +1,4 @@ -error: expected `usize`, found const tuple +error: expected `usize`, found `([1, 2], 3, [4, 5])` --> $DIR/tuple_expr_arg_bad-issue-151048.rs:5:19 | LL | stuff: [u8; { ([1, 2], 3, [4, 5]) }], diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.rs b/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.rs index 95acd66074f6f..608a4af353a5e 100644 --- a/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.rs +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.rs @@ -2,7 +2,7 @@ #![expect(incomplete_features)] pub fn takes_nested_tuple() { - takes_nested_tuple::<{ () }> //~ ERROR expected `u32`, found const tuple + takes_nested_tuple::<{ () }> //~ ERROR expected `u32`, found `()` } fn main() {} diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.stderr b/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.stderr index dfbd294951fdc..d8314a6b6a57e 100644 --- a/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.stderr +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.stderr @@ -1,4 +1,4 @@ -error: expected `u32`, found const tuple +error: expected `u32`, found `()` --> $DIR/tuple_expr_arg_mismatch_type.rs:5:28 | LL | takes_nested_tuple::<{ () }> diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_unbounded_assoc_const.rs b/tests/ui/const-generics/mgca/tuple_expr_arg_unbounded_assoc_const.rs new file mode 100644 index 0000000000000..f844dae5c8220 --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_unbounded_assoc_const.rs @@ -0,0 +1,13 @@ +#![feature(min_generic_const_args, adt_const_params)] + +// Regression test for an ICE in privacy checking while walking the `T` qself +// of `T::ASSOC` inside a tuple const argument. + +fn takes_tuple() {} + +fn generic_caller() { + takes_tuple::<{ (N, T::ASSOC) }>; + //~^ ERROR expected `()`, found `(N, T::ASSOC)` +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_unbounded_assoc_const.stderr b/tests/ui/const-generics/mgca/tuple_expr_arg_unbounded_assoc_const.stderr new file mode 100644 index 0000000000000..3af04db14b60b --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_unbounded_assoc_const.stderr @@ -0,0 +1,8 @@ +error: expected `()`, found `(N, T::ASSOC)` + --> $DIR/tuple_expr_arg_unbounded_assoc_const.rs:9:21 + | +LL | takes_tuple::<{ (N, T::ASSOC) }>; + | ^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + From f0cf39249c1aa48fd18c3e957ff7a7e32059bdf8 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 22 Jun 2026 06:59:09 +0000 Subject: [PATCH 22/42] typo fix from hid_id to hir_id --- compiler/rustc_hir_typeck/src/writeback.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index ba5b55b43049f..58139a5e3480a 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -348,7 +348,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> { fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx, AmbigArg>) { intravisit::walk_ty(self, hir_ty); // If there are type checking errors, Type privacy pass will stop, - // so we may not get the type from hid_id, see #104513 + // so we may not get the type from hir_id, see #104513 if let Some(ty) = self.fcx.node_ty_opt(hir_ty.hir_id) { let ty = self.resolve(ty, &hir_ty.span); self.write_ty_to_typeck_results(hir_ty.hir_id, ty); From cd8c4d06e229c16566972e94b6b95ee82f6a217c Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 22 Jun 2026 07:12:32 +0000 Subject: [PATCH 23/42] Check the target and souce tuple elements mismatch duing const_arg_tup lowering --- .../src/hir_ty_lowering/mod.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) 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 80c1106780ca7..21fe7f70e2359 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2518,15 +2518,29 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ) -> Const<'tcx> { let tcx = self.tcx(); + let found_tuple = || { + tcx.sess + .source_map() + .span_to_snippet(span) + .map(|snippet| format!("`{snippet}`")) + .unwrap_or_else(|_| "const tuple".to_string()) + }; + let tys = match ty.kind() { ty::Tuple(tys) => tys, ty::Error(e) => return Const::new_error(tcx, *e), _ => { - let e = tcx.dcx().span_err(span, format!("expected `{}`, found const tuple", ty)); + let e = + tcx.dcx().span_err(span, format!("expected `{}`, found {}", ty, found_tuple())); return Const::new_error(tcx, e); } }; + if exprs.len() != tys.len() { + let e = tcx.dcx().span_err(span, format!("expected `{}`, found {}", ty, found_tuple())); + return Const::new_error(tcx, e); + } + let exprs = exprs .iter() .zip(tys.iter()) From 3da461260fb33a4038adf6fd2ee328215b136819 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 22 Jun 2026 16:50:44 +0200 Subject: [PATCH 24/42] norm: fix escaping placeholder check --- compiler/rustc_next_trait_solver/src/normalize.rs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/normalize.rs b/compiler/rustc_next_trait_solver/src/normalize.rs index 3bf2f64cf8887..675c8be873f0d 100644 --- a/compiler/rustc_next_trait_solver/src/normalize.rs +++ b/compiler/rustc_next_trait_solver/src/normalize.rs @@ -121,24 +121,21 @@ where alias_term: AliasTerm, has_escaping: HasEscapingBoundVars, ) -> Result, NoSolution> { - let current_universe = self.infcx.universe(); - self.infcx.create_next_universe(); - let (normalized, ambig_goal) = (self.normalize)(alias_term)?; // Return ambiguous higher ranked alias as is, if // - it contains escaping vars, and - // - the normalized term contains infer vars newly created - // in the normalization above. - // The problem is that they may be resolved to types - // referencing the temporary placeholders. + // - the normalized term contains infer vars which may mention + // temporary placeholders after we've already mapped them back + // to bound vars. // - // We can normalize the ambiguous alias again after the binder is instantiated. + // We can normalize the ambiguous alias again after the binder is instantiated + // or once we've made further inference progress. if ambig_goal.is_some() && has_escaping == HasEscapingBoundVars::Yes { let mut visitor = MaxUniverse::new(self.infcx); normalized.visit_with(&mut visitor); let max_universe = visitor.max_universe(); - if current_universe.cannot_name(max_universe) { + if max_universe.can_name(self.universes.first().unwrap().unwrap()) { return Ok(None); } } From f99e8948be12104fbe57d25b81d6d8b4cf9ae5ee Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 21 Jun 2026 20:38:41 +0200 Subject: [PATCH 25/42] Move target checking for `#[lang]` to the attribute parser --- .../src/attributes/rustc_internal.rs | 25 ++++++++++++++++++- .../rustc_attr_parsing/src/diagnostics.rs | 24 ++++++++++++++++-- compiler/rustc_passes/src/diagnostics.rs | 20 --------------- compiler/rustc_passes/src/lang_items.rs | 23 +++++++---------- compiler/rustc_passes/src/weak_lang_items.rs | 24 ++++++++---------- tests/ui/error-codes/E0264.rs | 4 +-- tests/ui/error-codes/E0264.stderr | 6 ++--- .../panic-handler-wrong-location.rs | 2 +- .../panic-handler-wrong-location.stderr | 11 ++++---- 9 files changed, 77 insertions(+), 62 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 6552c9de7c5a5..07e24329ccea1 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -12,6 +12,7 @@ use rustc_span::Symbol; use super::prelude::*; use super::util::parse_single_integer; use crate::diagnostics; +use crate::diagnostics::{LangItemOnIncorrectTarget, UnknownExternLangItem}; use crate::session_diagnostics::{ AttributeRequiresOpt, CguFieldsMissing, RustcScalableVectorCountOutOfRange, UnknownLangItem, }; @@ -576,6 +577,28 @@ impl SingleAttributeParser for LangParser { cx.emit_err(UnknownLangItem { span: cx.attr_span, name }); return None; }; + + // Only weak lang items may be applied to foreign items + if [Target::ForeignFn, Target::ForeignStatic, Target::ForeignTy, Target::ForeignMod] + .contains(&cx.target) + && !lang_item.is_weak() + { + cx.emit_err(UnknownExternLangItem { span: cx.attr_span, lang_item: lang_item.name() }); + return None; + } + + // Check the target + if cx.target != lang_item.target() + && !(cx.target == Target::ForeignFn && lang_item == LangItem::PanicImpl) + { + cx.emit_err(LangItemOnIncorrectTarget { + span: cx.attr_span, + name, + expected_target: lang_item.target(), + actual_target: cx.target, + }); + return None; + } Some(AttributeKind::Lang(lang_item)) } } @@ -599,7 +622,7 @@ pub(crate) struct PanicHandlerParser; impl NoArgsAttributeParser for PanicHandlerParser { const PATH: &[Symbol] = &[sym::panic_handler]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); // Targets are checked per lang item in `rustc_passes` + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const STABILITY: AttributeStability = AttributeStability::Stable; const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Lang(LangItem::PanicImpl); } diff --git a/compiler/rustc_attr_parsing/src/diagnostics.rs b/compiler/rustc_attr_parsing/src/diagnostics.rs index b22fe88a4de3d..cf6a773bd1394 100644 --- a/compiler/rustc_attr_parsing/src/diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/diagnostics.rs @@ -1,5 +1,6 @@ -use rustc_errors::{Applicability, DiagArgValue, E0232, MultiSpan}; -use rustc_hir::AttrPath; +use rustc_errors::E0264; +use rustc_errors::{Applicability, DiagArgValue, E0232, E0718, MultiSpan}; +use rustc_hir::{AttrPath, Target}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::{Span, Symbol}; @@ -801,3 +802,22 @@ pub(crate) struct UnsafeAttribute { pub attr_path: AttrPath, pub note: &'static str, } + +#[derive(Diagnostic)] +#[diag("`{$name}` lang item must be applied to a {$expected_target}", code = E0718)] +pub(crate) struct LangItemOnIncorrectTarget { + #[primary_span] + #[label("attribute should be applied to a {$expected_target}, not a {$actual_target}")] + pub span: Span, + pub name: Symbol, + pub expected_target: Target, + pub actual_target: Target, +} + +#[derive(Diagnostic)] +#[diag("unknown external lang item: `{$lang_item}`", code = E0264)] +pub(crate) struct UnknownExternLangItem { + #[primary_span] + pub span: Span, + pub lang_item: Symbol, +} diff --git a/compiler/rustc_passes/src/diagnostics.rs b/compiler/rustc_passes/src/diagnostics.rs index f6c4b0cf77d12..a4ba014d2f6aa 100644 --- a/compiler/rustc_passes/src/diagnostics.rs +++ b/compiler/rustc_passes/src/diagnostics.rs @@ -5,7 +5,6 @@ use rustc_errors::codes::*; use rustc_errors::{ Diag, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee, Level, MultiSpan, msg, }; -use rustc_hir::Target; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_middle::ty::{MainDefinition, Ty}; use rustc_span::{DUMMY_SP, Ident, Span, Symbol}; @@ -326,14 +325,6 @@ pub(crate) struct DeprecatedAnnotationHasNoEffect { pub span: Span, } -#[derive(Diagnostic)] -#[diag("unknown external lang item: `{$lang_item}`", code = E0264)] -pub(crate) struct UnknownExternLangItem { - #[primary_span] - pub span: Span, - pub lang_item: Symbol, -} - #[derive(Diagnostic)] #[diag("`#[panic_handler]` function required, but not found")] pub(crate) struct MissingPanicHandler; @@ -398,17 +389,6 @@ pub(crate) struct LangItemWithTargetFeature { pub sig_span: Span, } -#[derive(Diagnostic)] -#[diag("`{$name}` lang item must be applied to a {$expected_target}", code = E0718)] -pub(crate) struct LangItemOnIncorrectTarget { - #[primary_span] - #[label("attribute should be applied to a {$expected_target}, not a {$actual_target}")] - pub span: Span, - pub name: Symbol, - pub expected_target: Target, - pub actual_target: Target, -} - #[derive(Diagnostic)] #[diag("duplicate diagnostic item in crate `{$crate_name}`: `{$name}`")] pub(crate) struct DuplicateDiagnosticItemInCrate { diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs index 53fb6888ddcd8..1686b4d595933 100644 --- a/compiler/rustc_passes/src/lang_items.rs +++ b/compiler/rustc_passes/src/lang_items.rs @@ -18,9 +18,7 @@ use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; use rustc_session::cstore::ExternCrate; use rustc_span::{Span, Symbol, sym}; -use crate::diagnostics::{ - DuplicateLangItem, IncorrectCrateType, IncorrectTarget, LangItemOnIncorrectTarget, -}; +use crate::diagnostics::{DuplicateLangItem, IncorrectCrateType, IncorrectTarget}; use crate::weak_lang_items; pub(crate) enum Duplicate { @@ -63,8 +61,14 @@ impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> { ) { if let Some((name, attr_span)) = extract_ast(attrs) { match LangItem::from_name(name) { - // Known lang item with attribute on correct target. - Some(lang_item) if actual_target == lang_item.target() => { + // Known lang item + Some(lang_item) => { + if actual_target != lang_item.target() { + self.tcx + .dcx() + .delayed_bug("lang item target is checked in attribute parser"); + return; + } self.collect_item_extended( lang_item, def_id, @@ -74,15 +78,6 @@ impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> { actual_target, ); } - // Known lang item with attribute on incorrect target. - Some(lang_item) => { - self.tcx.dcx().emit_err(LangItemOnIncorrectTarget { - span: attr_span, - name, - expected_target: lang_item.target(), - actual_target, - }); - } // Unknown lang item. _ => { self.tcx.dcx().delayed_bug("unknown lang item"); diff --git a/compiler/rustc_passes/src/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs index b42b27ec74184..98e0c0f241b4c 100644 --- a/compiler/rustc_passes/src/weak_lang_items.rs +++ b/compiler/rustc_passes/src/weak_lang_items.rs @@ -10,7 +10,7 @@ use rustc_middle::ty::TyCtxt; use rustc_session::config::CrateType; use crate::diagnostics::{ - MissingLangItem, MissingPanicHandler, PanicUnwindWithoutStd, UnknownExternLangItem, + MissingLangItem, MissingPanicHandler, PanicUnwindWithoutStd, }; use crate::lang_items::extract_ast; @@ -28,27 +28,23 @@ pub(crate) fn check_crate( items.missing.push(LangItem::EhPersonality); } - visit::Visitor::visit_crate(&mut WeakLangItemVisitor { tcx, items }, krate); + visit::Visitor::visit_crate(&mut WeakLangItemVisitor { items }, krate); verify(tcx, items); } -struct WeakLangItemVisitor<'a, 'tcx> { - tcx: TyCtxt<'tcx>, +struct WeakLangItemVisitor<'a> { items: &'a mut lang_items::LanguageItems, } -impl<'ast> visit::Visitor<'ast> for WeakLangItemVisitor<'_, '_> { +impl<'ast> visit::Visitor<'ast> for WeakLangItemVisitor<'_> { fn visit_foreign_item(&mut self, i: &'ast ast::ForeignItem) { - if let Some((lang_item, _)) = extract_ast(&i.attrs) { - if let Some(item) = LangItem::from_name(lang_item) - && item.is_weak() - { - if self.items.get(item).is_none() { - self.items.missing.push(item); - } - } else { - self.tcx.dcx().emit_err(UnknownExternLangItem { span: i.span, lang_item }); + if let Some((lang_item, _)) = extract_ast(&i.attrs) + && let Some(item) = LangItem::from_name(lang_item) + && item.is_weak() + { + if self.items.get(item).is_none() { + self.items.missing.push(item); } } } diff --git a/tests/ui/error-codes/E0264.rs b/tests/ui/error-codes/E0264.rs index 855644796ed45..ef3c8a1c3acd1 100644 --- a/tests/ui/error-codes/E0264.rs +++ b/tests/ui/error-codes/E0264.rs @@ -1,8 +1,8 @@ #![feature(lang_items)] extern "C" { - #[lang = "copy"] - fn copy(); //~ ERROR E0264 + #[lang = "copy"] //~ ERROR E0264 + fn copy(); } fn main() {} diff --git a/tests/ui/error-codes/E0264.stderr b/tests/ui/error-codes/E0264.stderr index 6442f42e689d6..b15ba468aa1a7 100644 --- a/tests/ui/error-codes/E0264.stderr +++ b/tests/ui/error-codes/E0264.stderr @@ -1,8 +1,8 @@ error[E0264]: unknown external lang item: `copy` - --> $DIR/E0264.rs:5:5 + --> $DIR/E0264.rs:4:5 | -LL | fn copy(); - | ^^^^^^^^^^ +LL | #[lang = "copy"] + | ^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/panic-handler/panic-handler-wrong-location.rs b/tests/ui/panic-handler/panic-handler-wrong-location.rs index 8fff7067136e2..22f6b6e724890 100644 --- a/tests/ui/panic-handler/panic-handler-wrong-location.rs +++ b/tests/ui/panic-handler/panic-handler-wrong-location.rs @@ -3,7 +3,7 @@ #![no_std] #![no_main] -#[panic_handler] //~ ERROR `panic_impl` lang item must be applied to a function +#[panic_handler] //~ ERROR attribute cannot be used on statics static X: u32 = 42; //~? ERROR `#[panic_handler]` function required, but not found diff --git a/tests/ui/panic-handler/panic-handler-wrong-location.stderr b/tests/ui/panic-handler/panic-handler-wrong-location.stderr index 9b361bf8d603f..7af0a4326d9a0 100644 --- a/tests/ui/panic-handler/panic-handler-wrong-location.stderr +++ b/tests/ui/panic-handler/panic-handler-wrong-location.stderr @@ -1,11 +1,12 @@ -error[E0718]: `panic_impl` lang item must be applied to a function +error: `#[panic_handler]` function required, but not found + +error: `#[panic_handler]` attribute cannot be used on statics --> $DIR/panic-handler-wrong-location.rs:6:1 | LL | #[panic_handler] - | ^^^^^^^^^^^^^^^^ attribute should be applied to a function, not a static - -error: `#[panic_handler]` function required, but not found + | ^^^^^^^^^^^^^^^^ + | + = help: `#[panic_handler]` can only be applied to functions error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0718`. From b8758a32d7ab334fd6406861e66189c7eed92e26 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 21 Jun 2026 20:49:22 +0200 Subject: [PATCH 26/42] Add lifetime parameter to `AllowedTargets` --- .../src/attributes/allow_unstable.rs | 6 +- .../src/attributes/autodiff.rs | 2 +- .../rustc_attr_parsing/src/attributes/body.rs | 3 +- .../src/attributes/cfi_encoding.rs | 2 +- .../src/attributes/codegen_attrs.rs | 36 ++++---- .../src/attributes/confusables.rs | 2 +- .../src/attributes/crate_level.rs | 40 ++++----- .../src/attributes/debugger.rs | 2 +- .../src/attributes/deprecation.rs | 2 +- .../attributes/diagnostic/do_not_recommend.rs | 2 +- .../src/attributes/diagnostic/on_const.rs | 2 +- .../src/attributes/diagnostic/on_move.rs | 2 +- .../attributes/diagnostic/on_type_error.rs | 2 +- .../attributes/diagnostic/on_unimplemented.rs | 2 +- .../src/attributes/diagnostic/on_unknown.rs | 2 +- .../diagnostic/on_unmatched_args.rs | 2 +- .../rustc_attr_parsing/src/attributes/doc.rs | 4 +- .../src/attributes/dummy.rs | 2 +- .../src/attributes/inline.rs | 4 +- .../src/attributes/instruction_set.rs | 2 +- .../src/attributes/link_attrs.rs | 24 ++--- .../src/attributes/lint_helpers.rs | 10 +-- .../src/attributes/loop_match.rs | 4 +- .../src/attributes/macro_attrs.rs | 15 ++-- .../rustc_attr_parsing/src/attributes/mod.rs | 14 +-- .../src/attributes/must_not_suspend.rs | 2 +- .../src/attributes/must_use.rs | 2 +- .../src/attributes/no_implicit_prelude.rs | 2 +- .../src/attributes/no_link.rs | 2 +- .../src/attributes/non_exhaustive.rs | 2 +- .../rustc_attr_parsing/src/attributes/path.rs | 2 +- .../src/attributes/pin_v2.rs | 2 +- .../src/attributes/proc_macro_attrs.rs | 11 +-- .../src/attributes/prototype.rs | 2 +- .../rustc_attr_parsing/src/attributes/repr.rs | 6 +- .../src/attributes/rustc_allocator.rs | 10 +-- .../src/attributes/rustc_dump.rs | 29 ++++--- .../src/attributes/rustc_internal.rs | 87 ++++++++++--------- .../src/attributes/semantics.rs | 4 +- .../src/attributes/splat.rs | 2 +- .../src/attributes/stability.rs | 12 +-- .../src/attributes/test_attrs.rs | 16 ++-- .../src/attributes/traits.rs | 20 ++--- .../src/attributes/transparency.rs | 3 +- .../src/attributes/unroll.rs | 2 +- compiler/rustc_attr_parsing/src/context.rs | 2 +- .../rustc_attr_parsing/src/diagnostics.rs | 3 +- .../rustc_attr_parsing/src/target_checking.rs | 12 +-- compiler/rustc_passes/src/weak_lang_items.rs | 4 +- 49 files changed, 216 insertions(+), 211 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs index 3e10e5e70b2c2..119b67b353cb8 100644 --- a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs +++ b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs @@ -11,7 +11,7 @@ impl CombineAttributeParser for AllowInternalUnstableParser { type Item = (Symbol, Span); const CONVERT: ConvertFn = |items, span| AttributeKind::AllowInternalUnstable(items, span); - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::MacroDef), Allow(Target::Fn), Warn(Target::Field), @@ -36,7 +36,7 @@ impl CombineAttributeParser for UnstableFeatureBoundParser { type Item = (Symbol, Span); const CONVERT: ConvertFn = |items, _| AttributeKind::UnstableFeatureBound(items); const STABILITY: AttributeStability = unstable!(staged_api); - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Impl { of_trait: true }), Allow(Target::Trait), @@ -59,7 +59,7 @@ impl CombineAttributeParser for RustcAllowConstFnUnstableParser { type Item = Symbol; const CONVERT: ConvertFn = |items, first_span| AttributeKind::RustcAllowConstFnUnstable(items, first_span); - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: true })), diff --git a/compiler/rustc_attr_parsing/src/attributes/autodiff.rs b/compiler/rustc_attr_parsing/src/attributes/autodiff.rs index 890cb33d08720..78ed4ff46d997 100644 --- a/compiler/rustc_attr_parsing/src/attributes/autodiff.rs +++ b/compiler/rustc_attr_parsing/src/attributes/autodiff.rs @@ -19,7 +19,7 @@ pub(crate) struct RustcAutodiffParser; impl SingleAttributeParser for RustcAutodiffParser { const PATH: &[Symbol] = &[sym::rustc_autodiff]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: true })), diff --git a/compiler/rustc_attr_parsing/src/attributes/body.rs b/compiler/rustc_attr_parsing/src/attributes/body.rs index b817d9346dafc..f3a4f04e02ae8 100644 --- a/compiler/rustc_attr_parsing/src/attributes/body.rs +++ b/compiler/rustc_attr_parsing/src/attributes/body.rs @@ -8,7 +8,8 @@ pub(crate) struct CoroutineParser; impl NoArgsAttributeParser for CoroutineParser { const PATH: &[Symbol] = &[sym::coroutine]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Closure)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = + AllowedTargets::AllowList(&[Allow(Target::Closure)]); const STABILITY: AttributeStability = unstable!(coroutines); const CREATE: fn(rustc_span::Span) -> AttributeKind = |_| AttributeKind::Coroutine; } diff --git a/compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs b/compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs index 2e7644fc70551..8a9102a78e25b 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs @@ -4,7 +4,7 @@ use super::prelude::*; pub(crate) struct CfiEncodingParser; impl SingleAttributeParser for CfiEncodingParser { const PATH: &[Symbol] = &[sym::cfi_encoding]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ Allow(Target::Struct), Allow(Target::ForeignTy), Allow(Target::Enum), diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index 155df43c813e8..7beee7e341b90 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -18,7 +18,7 @@ pub(crate) struct OptimizeParser; impl SingleAttributeParser for OptimizeParser { const PATH: &[Symbol] = &[sym::optimize]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Closure), Allow(Target::Method(MethodKind::Trait { body: true })), @@ -51,7 +51,7 @@ pub(crate) struct ColdParser; impl NoArgsAttributeParser for ColdParser { const PATH: &[Symbol] = &[sym::cold]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Trait { body: true })), Allow(Target::Method(MethodKind::TraitImpl)), @@ -67,7 +67,7 @@ pub(crate) struct CoverageParser; impl SingleAttributeParser for CoverageParser { const PATH: &[Symbol] = &[sym::coverage]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Closure), Allow(Target::Method(MethodKind::Trait { body: true })), @@ -114,7 +114,7 @@ impl SingleAttributeParser for ExportNameParser { note: "the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them", unsafe_since: Some(Edition2024), }; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Static), Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), @@ -151,7 +151,7 @@ pub(crate) struct RustcObjcClassParser; impl SingleAttributeParser for RustcObjcClassParser { const PATH: &[rustc_span::Symbol] = &[sym::rustc_objc_class]; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::ForeignStatic)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "ClassName"); const STABILITY: AttributeStability = unstable!(rustc_attrs); @@ -179,7 +179,7 @@ pub(crate) struct RustcObjcSelectorParser; impl SingleAttributeParser for RustcObjcSelectorParser { const PATH: &[rustc_span::Symbol] = &[sym::rustc_objc_selector]; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::ForeignStatic)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "methodName"); const STABILITY: AttributeStability = unstable!(rustc_attrs); @@ -226,7 +226,7 @@ impl AttributeParser for NakedParser { note: "the `#[naked]` attribute adds the safety obligation that the function's body must respect the function’s calling convention, uphold its signature, and either return or diverge (i.e., not fall through past the end of the assembly code).", unsafe_since: None, }; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: true })), @@ -334,7 +334,7 @@ pub(crate) struct TrackCallerParser; impl NoArgsAttributeParser for TrackCallerParser { const PATH: &[Symbol] = &[sym::track_caller]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: true })), @@ -359,7 +359,7 @@ impl NoArgsAttributeParser for NoMangleParser { note: "the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them", unsafe_since: Some(Edition2024), }; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ Allow(Target::Fn), Allow(Target::Static), Allow(Target::Method(MethodKind::Inherent)), @@ -462,7 +462,7 @@ impl AttributeParser for UsedParser { } }, )]; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Static), Warn(Target::MacroCall)]); fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option { @@ -533,7 +533,7 @@ impl CombineAttributeParser for TargetFeatureParser { parse_tf_attribute(cx, args) } - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: true })), @@ -561,7 +561,7 @@ impl CombineAttributeParser for ForceTargetFeatureParser { was_forced: true, }; const TEMPLATE: AttributeTemplate = template!(List: &["enable = \"feat1, feat2\""]); - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: true })), @@ -581,7 +581,7 @@ pub(crate) struct InstrumentFnParser; impl SingleAttributeParser for InstrumentFnParser { const PATH: &[Symbol] = &[sym::instrument_fn]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: true })), @@ -619,7 +619,7 @@ pub(crate) struct SanitizeParser; impl SingleAttributeParser for SanitizeParser { const PATH: &[Symbol] = &[sym::sanitize]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Closure), Allow(Target::Method(MethodKind::Inherent)), @@ -751,7 +751,7 @@ pub(crate) struct ThreadLocalParser; impl NoArgsAttributeParser for ThreadLocalParser { const PATH: &[Symbol] = &[sym::thread_local]; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Static), Allow(Target::ForeignStatic)]); const STABILITY: AttributeStability = unstable!(thread_local); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ThreadLocal; @@ -761,7 +761,7 @@ pub(crate) struct RustcPassIndirectlyInNonRusticAbisParser; impl NoArgsAttributeParser for RustcPassIndirectlyInNonRusticAbisParser { const PATH: &[Symbol] = &[sym::rustc_pass_indirectly_in_non_rustic_abis]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Struct)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcPassIndirectlyInNonRusticAbis; } @@ -770,7 +770,7 @@ pub(crate) struct RustcEiiForeignItemParser; impl NoArgsAttributeParser for RustcEiiForeignItemParser { const PATH: &[Symbol] = &[sym::rustc_eii_foreign_item]; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::ForeignFn), Allow(Target::ForeignStatic)]); const STABILITY: AttributeStability = unstable!(eii_internals); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcEiiForeignItem; @@ -780,7 +780,7 @@ pub(crate) struct PatchableFunctionEntryParser; impl SingleAttributeParser for PatchableFunctionEntryParser { const PATH: &[Symbol] = &[sym::patchable_function_entry]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const TEMPLATE: AttributeTemplate = template!(List: &["prefix_nops = m, entry_nops = n"]); const STABILITY: AttributeStability = unstable!(patchable_function_entry); diff --git a/compiler/rustc_attr_parsing/src/attributes/confusables.rs b/compiler/rustc_attr_parsing/src/attributes/confusables.rs index 3b2115eeb01e2..091566012d158 100644 --- a/compiler/rustc_attr_parsing/src/attributes/confusables.rs +++ b/compiler/rustc_attr_parsing/src/attributes/confusables.rs @@ -32,7 +32,7 @@ impl AttributeParser for ConfusablesParser { this.first_span.get_or_insert(cx.attr_span); }, )]; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Method(MethodKind::Inherent))]); fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option { diff --git a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs index eb78bc0775f6b..f99cb61be42c2 100644 --- a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs +++ b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs @@ -13,7 +13,7 @@ impl SingleAttributeParser for CrateNameParser { const PATH: &[Symbol] = &[sym::crate_name]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name"); - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = AttributeStability::Stable; @@ -32,7 +32,7 @@ impl CombineAttributeParser for CrateTypeParser { const PATH: &[Symbol] = &[sym::crate_type]; type Item = CrateType; const CONVERT: ConvertFn = |items, _| AttributeKind::CrateType(items); - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "crate type", "https://doc.rust-lang.org/reference/linkage.html"); @@ -76,7 +76,7 @@ impl SingleAttributeParser for RecursionLimitParser { const PATH: &[Symbol] = &[sym::recursion_limit]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N", "https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute"); - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = AttributeStability::Stable; @@ -92,7 +92,7 @@ pub(crate) struct MoveSizeLimitParser; impl SingleAttributeParser for MoveSizeLimitParser { const PATH: &[Symbol] = &[sym::move_size_limit]; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = unstable!(large_assignments); fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option { @@ -108,7 +108,7 @@ impl SingleAttributeParser for TypeLengthLimitParser { const PATH: &[Symbol] = &[sym::type_length_limit]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = AttributeStability::Stable; @@ -124,7 +124,7 @@ pub(crate) struct PatternComplexityLimitParser; impl SingleAttributeParser for PatternComplexityLimitParser { const PATH: &[Symbol] = &[sym::pattern_complexity_limit]; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = unstable!( rustc_attrs, "the `#[pattern_complexity_limit]` attribute is used for rustc unit tests" @@ -141,7 +141,7 @@ pub(crate) struct NoCoreParser; impl NoArgsAttributeParser for NoCoreParser { const PATH: &[Symbol] = &[sym::no_core]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = unstable!(no_core); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoCore; } @@ -151,7 +151,7 @@ pub(crate) struct NoStdParser; impl NoArgsAttributeParser for NoStdParser { const PATH: &[Symbol] = &[sym::no_std]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = AttributeStability::Stable; const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoStd; @@ -162,7 +162,7 @@ pub(crate) struct NoMainParser; impl NoArgsAttributeParser for NoMainParser { const PATH: &[Symbol] = &[sym::no_main]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = AttributeStability::Stable; const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoMain; @@ -172,7 +172,7 @@ pub(crate) struct RustcCoherenceIsCoreParser; impl NoArgsAttributeParser for RustcCoherenceIsCoreParser { const PATH: &[Symbol] = &[sym::rustc_coherence_is_core]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcCoherenceIsCore; } @@ -182,7 +182,7 @@ pub(crate) struct WindowsSubsystemParser; impl SingleAttributeParser for WindowsSubsystemParser { const PATH: &[Symbol] = &[sym::windows_subsystem]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: ["windows", "console"], "https://doc.rust-lang.org/reference/runtime.html#the-windows_subsystem-attribute"); const STABILITY: AttributeStability = AttributeStability::Stable; @@ -210,7 +210,7 @@ pub(crate) struct PanicRuntimeParser; impl NoArgsAttributeParser for PanicRuntimeParser { const PATH: &[Symbol] = &[sym::panic_runtime]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = unstable!(panic_runtime); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::PanicRuntime; } @@ -219,7 +219,7 @@ pub(crate) struct NeedsPanicRuntimeParser; impl NoArgsAttributeParser for NeedsPanicRuntimeParser { const PATH: &[Symbol] = &[sym::needs_panic_runtime]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = unstable!(needs_panic_runtime); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NeedsPanicRuntime; } @@ -228,7 +228,7 @@ pub(crate) struct ProfilerRuntimeParser; impl NoArgsAttributeParser for ProfilerRuntimeParser { const PATH: &[Symbol] = &[sym::profiler_runtime]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = unstable!(profiler_runtime); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ProfilerRuntime; } @@ -238,7 +238,7 @@ pub(crate) struct NoBuiltinsParser; impl NoArgsAttributeParser for NoBuiltinsParser { const PATH: &[Symbol] = &[sym::no_builtins]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = AttributeStability::Stable; const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoBuiltins; @@ -248,7 +248,7 @@ pub(crate) struct RustcPreserveUbChecksParser; impl NoArgsAttributeParser for RustcPreserveUbChecksParser { const PATH: &[Symbol] = &[sym::rustc_preserve_ub_checks]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcPreserveUbChecks; } @@ -257,7 +257,7 @@ pub(crate) struct RustcNoImplicitBoundsParser; impl NoArgsAttributeParser for RustcNoImplicitBoundsParser { const PATH: &[Symbol] = &[sym::rustc_no_implicit_bounds]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNoImplicitBounds; } @@ -266,7 +266,7 @@ pub(crate) struct DefaultLibAllocatorParser; impl NoArgsAttributeParser for DefaultLibAllocatorParser { const PATH: &[Symbol] = &[sym::default_lib_allocator]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = unstable!(allocator_internals); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::DefaultLibAllocator; } @@ -277,7 +277,7 @@ impl CombineAttributeParser for FeatureParser { const PATH: &[Symbol] = &[sym::feature]; type Item = Ident; const CONVERT: ConvertFn = AttributeKind::Feature; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]); const TEMPLATE: AttributeTemplate = template!(List: &["feature1, feature2, ..."]); const STABILITY: AttributeStability = AttributeStability::Stable; @@ -323,7 +323,7 @@ impl CombineAttributeParser for RegisterToolParser { const PATH: &[Symbol] = &[sym::register_tool]; type Item = Ident; const CONVERT: ConvertFn = |tools, _span| AttributeKind::RegisterTool(tools); - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const TEMPLATE: AttributeTemplate = template!(List: &["tool1, tool2, ..."]); const STABILITY: AttributeStability = unstable!(register_tool); diff --git a/compiler/rustc_attr_parsing/src/attributes/debugger.rs b/compiler/rustc_attr_parsing/src/attributes/debugger.rs index 8d2cff35905ed..b514235a48eca 100644 --- a/compiler/rustc_attr_parsing/src/attributes/debugger.rs +++ b/compiler/rustc_attr_parsing/src/attributes/debugger.rs @@ -7,7 +7,7 @@ pub(crate) struct DebuggerVisualizerParser; impl CombineAttributeParser for DebuggerVisualizerParser { const PATH: &[Symbol] = &[sym::debugger_visualizer]; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Mod), Allow(Target::Crate)]); const TEMPLATE: AttributeTemplate = template!( List: &[r#"natvis_file = "...", gdb_script_file = "...""#], diff --git a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs index ee3734bf19541..d401aafed7bec 100644 --- a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs +++ b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs @@ -32,7 +32,7 @@ fn get( pub(crate) struct DeprecatedParser; impl SingleAttributeParser for DeprecatedParser { const PATH: &[Symbol] = &[sym::deprecated]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ Allow(Target::Fn), Allow(Target::Mod), Allow(Target::Struct), diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/do_not_recommend.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/do_not_recommend.rs index 85708273a409b..250326db42bb7 100644 --- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/do_not_recommend.rs +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/do_not_recommend.rs @@ -16,7 +16,7 @@ impl SingleAttributeParser for DoNotRecommendParser { const PATH: &[Symbol] = &[sym::diagnostic, sym::do_not_recommend]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; // "Allowed" on any target, noop on all but trait impls - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[Allow(Target::Impl { of_trait: true })]); const TEMPLATE: AttributeTemplate = template!(Word /*doesn't matter */); const STABILITY: AttributeStability = AttributeStability::Stable; diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_const.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_const.rs index dc8260ae944ef..a7b71b9080dca 100644 --- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_const.rs +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_const.rs @@ -37,7 +37,7 @@ impl AttributeParser for OnConstParser { // "Allowed" on all targets; noop on anything but non-const trait impls; // this linted on in parser. - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ // FIXME(mejrs) no constness field on `Target`, // so non-constness is still checked in check_attr.rs Allow(Target::Impl { of_trait: true }), diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_move.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_move.rs index ec77ede4127f5..1c8b3418fa746 100644 --- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_move.rs +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_move.rs @@ -43,7 +43,7 @@ impl AttributeParser for OnMoveParser { }, )]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ Allow(Target::Enum), Allow(Target::Struct), Allow(Target::Union), diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_type_error.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_type_error.rs index d5636b23a09b1..89cae4b7c55f1 100644 --- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_type_error.rs +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_type_error.rs @@ -42,7 +42,7 @@ impl AttributeParser for OnTypeErrorParser { }, )]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ Allow(Target::Enum), Allow(Target::Struct), Allow(Target::Union), diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unimplemented.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unimplemented.rs index 86a96f7093587..057d243c6d123 100644 --- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unimplemented.rs +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unimplemented.rs @@ -45,7 +45,7 @@ impl AttributeParser for OnUnimplementedParser { }, ), ]; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[Allow(Target::Trait)]); fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option { diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unknown.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unknown.rs index fc05ae9150d15..bfa26d993b17e 100644 --- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unknown.rs +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unknown.rs @@ -40,7 +40,7 @@ impl AttributeParser for OnUnknownParser { }, )]; // "Allowed" for all targets, but noop for all but use statements. - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ Allow(Target::Use), Allow(Target::Mod), Allow(Target::Crate), diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unmatched_args.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unmatched_args.rs index 44975cd49c93f..18f980bfebbe8 100644 --- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unmatched_args.rs +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unmatched_args.rs @@ -33,7 +33,7 @@ impl AttributeParser for OnUnmatchedArgsParser { }, )]; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[Allow(Target::MacroDef)]); fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option { diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index e91ab584bcf47..988df2b200f86 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -706,8 +706,8 @@ impl AttributeParser for DocParser { }, )]; // FIXME: Currently emitted from 2 different places, generating duplicated warnings. - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); - // const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(ALL_TARGETS); + // const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ // Allow(Target::ExternCrate), // Allow(Target::Use), // Allow(Target::Static), diff --git a/compiler/rustc_attr_parsing/src/attributes/dummy.rs b/compiler/rustc_attr_parsing/src/attributes/dummy.rs index d436c7f232ec7..83984d48919b7 100644 --- a/compiler/rustc_attr_parsing/src/attributes/dummy.rs +++ b/compiler/rustc_attr_parsing/src/attributes/dummy.rs @@ -12,7 +12,7 @@ pub(crate) struct RustcDummyParser; impl SingleAttributeParser for RustcDummyParser { const PATH: &[Symbol] = &[sym::rustc_dummy]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Ignore; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::ManuallyChecked; + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::ManuallyChecked; const TEMPLATE: AttributeTemplate = template!(Word); // Anything, really const STABILITY: AttributeStability = unstable!(rustc_attrs, "the `#[rustc_dummy]` attribute is used for rustc unit tests"); diff --git a/compiler/rustc_attr_parsing/src/attributes/inline.rs b/compiler/rustc_attr_parsing/src/attributes/inline.rs index 84b880202a9e6..80328e1c8ef96 100644 --- a/compiler/rustc_attr_parsing/src/attributes/inline.rs +++ b/compiler/rustc_attr_parsing/src/attributes/inline.rs @@ -13,7 +13,7 @@ pub(crate) struct InlineParser; impl SingleAttributeParser for InlineParser { const PATH: &[Symbol] = &[sym::inline]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: true })), @@ -66,7 +66,7 @@ pub(crate) struct RustcForceInlineParser; impl SingleAttributeParser for RustcForceInlineParser { const PATH: &[Symbol] = &[sym::rustc_force_inline]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), ]); diff --git a/compiler/rustc_attr_parsing/src/attributes/instruction_set.rs b/compiler/rustc_attr_parsing/src/attributes/instruction_set.rs index 612d5d33d94e0..3a4bb926f759c 100644 --- a/compiler/rustc_attr_parsing/src/attributes/instruction_set.rs +++ b/compiler/rustc_attr_parsing/src/attributes/instruction_set.rs @@ -8,7 +8,7 @@ pub(crate) struct InstructionSetParser; impl SingleAttributeParser for InstructionSetParser { const PATH: &[Symbol] = &[sym::instruction_set]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ Allow(Target::Fn), Allow(Target::Closure), Allow(Target::Method(MethodKind::Inherent)), diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index f260863840080..2357d6846935c 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -26,7 +26,7 @@ pub(crate) struct LinkNameParser; impl SingleAttributeParser for LinkNameParser { const PATH: &[Symbol] = &[sym::link_name]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ Allow(Target::ForeignFn), Allow(Target::ForeignStatic), ]); @@ -70,7 +70,7 @@ impl CombineAttributeParser for LinkParser { r#"name = "...", import_name_type = "decorated|noprefix|undecorated""#, r#"name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated""#, ], "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute"); - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[Allow(Target::ForeignMod)]); const STABILITY: AttributeStability = AttributeStability::Stable; @@ -494,7 +494,7 @@ impl SingleAttributeParser for LinkSectionParser { unsafe_since: Some(Edition2024), }; const STABILITY: AttributeStability = AttributeStability::Stable; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ Allow(Target::Static), Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), @@ -535,7 +535,7 @@ impl SingleAttributeParser for LinkSectionParser { pub(crate) struct ExportStableParser; impl NoArgsAttributeParser for ExportStableParser { const PATH: &[Symbol] = &[sym::export_stable]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Struct), @@ -558,7 +558,8 @@ impl NoArgsAttributeParser for FfiConstParser { note: "`#[ffi_const]` functions shall have no effects except for its return value, which can only depend on the values of the function parameters, and is not affected by changes to the observable state of the program.", unsafe_since: None, }; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = + AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]); const STABILITY: AttributeStability = unstable!(ffi_const); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::FfiConst; } @@ -570,7 +571,8 @@ impl NoArgsAttributeParser for FfiPureParser { note: "`#[ffi_pure]` functions shall have no effects except for its return value, which shall not change across two consecutive function calls with the same parameters.", unsafe_since: None, }; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = + AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]); const STABILITY: AttributeStability = unstable!(ffi_pure); const CREATE: fn(Span) -> AttributeKind = AttributeKind::FfiPure; } @@ -578,7 +580,7 @@ impl NoArgsAttributeParser for FfiPureParser { pub(crate) struct RustcStdInternalSymbolParser; impl NoArgsAttributeParser for RustcStdInternalSymbolParser { const PATH: &[Symbol] = &[sym::rustc_std_internal_symbol]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::ForeignFn), Allow(Target::Static), @@ -592,7 +594,7 @@ pub(crate) struct LinkOrdinalParser; impl SingleAttributeParser for LinkOrdinalParser { const PATH: &[Symbol] = &[sym::link_ordinal]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::ForeignFn), Allow(Target::ForeignStatic), Warn(Target::MacroCall), @@ -632,7 +634,7 @@ pub(crate) struct LinkageParser; impl SingleAttributeParser for LinkageParser { const PATH: &[Symbol] = &[sym::linkage]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: true })), @@ -708,7 +710,7 @@ pub(crate) struct NeedsAllocatorParser; impl NoArgsAttributeParser for NeedsAllocatorParser { const PATH: &[Symbol] = &[sym::needs_allocator]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = unstable!(allocator_internals); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NeedsAllocator; } @@ -717,7 +719,7 @@ pub(crate) struct CompilerBuiltinsParser; impl NoArgsAttributeParser for CompilerBuiltinsParser { const PATH: &[Symbol] = &[sym::compiler_builtins]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = unstable!(compiler_builtins); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::CompilerBuiltins; } diff --git a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs index 75a07e868129e..38afeea07794a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs +++ b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs @@ -5,7 +5,7 @@ use super::prelude::*; pub(crate) struct RustcAsPtrParser; impl NoArgsAttributeParser for RustcAsPtrParser { const PATH: &[Symbol] = &[sym::rustc_as_ptr]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: false })), @@ -19,7 +19,7 @@ impl NoArgsAttributeParser for RustcAsPtrParser { pub(crate) struct RustcPubTransparentParser; impl NoArgsAttributeParser for RustcPubTransparentParser { const PATH: &[Symbol] = &[sym::rustc_pub_transparent]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Struct), Allow(Target::Enum), Allow(Target::Union), @@ -31,7 +31,7 @@ impl NoArgsAttributeParser for RustcPubTransparentParser { pub(crate) struct RustcPassByValueParser; impl NoArgsAttributeParser for RustcPassByValueParser { const PATH: &[Symbol] = &[sym::rustc_pass_by_value]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Struct), Allow(Target::Enum), Allow(Target::TyAlias), @@ -43,7 +43,7 @@ impl NoArgsAttributeParser for RustcPassByValueParser { pub(crate) struct RustcShouldNotBeCalledOnConstItemsParser; impl NoArgsAttributeParser for RustcShouldNotBeCalledOnConstItemsParser { const PATH: &[Symbol] = &[sym::rustc_should_not_be_called_on_const_items]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::TraitImpl)), ]); @@ -55,7 +55,7 @@ pub(crate) struct AutomaticallyDerivedParser; impl NoArgsAttributeParser for AutomaticallyDerivedParser { const PATH: &[Symbol] = &[sym::automatically_derived]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ Allow(Target::Impl { of_trait: true }), Error(Target::Crate), Error(Target::WherePredicate), diff --git a/compiler/rustc_attr_parsing/src/attributes/loop_match.rs b/compiler/rustc_attr_parsing/src/attributes/loop_match.rs index 06c3cd286a06e..e46d2edaa49ba 100644 --- a/compiler/rustc_attr_parsing/src/attributes/loop_match.rs +++ b/compiler/rustc_attr_parsing/src/attributes/loop_match.rs @@ -5,7 +5,7 @@ use super::prelude::*; pub(crate) struct LoopMatchParser; impl NoArgsAttributeParser for LoopMatchParser { const PATH: &[Symbol] = &[sym::loop_match]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Loop)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Loop)]); const STABILITY: AttributeStability = unstable!(loop_match); const CREATE: fn(Span) -> AttributeKind = AttributeKind::LoopMatch; } @@ -13,7 +13,7 @@ impl NoArgsAttributeParser for LoopMatchParser { pub(crate) struct ConstContinueParser; impl NoArgsAttributeParser for ConstContinueParser { const PATH: &[Symbol] = &[sym::const_continue]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Break)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Break)]); const STABILITY: AttributeStability = unstable!(loop_match); const CREATE: fn(Span) -> AttributeKind = AttributeKind::ConstContinue; } diff --git a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs index 8ad202bad3d84..f49a7e674d560 100644 --- a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs @@ -8,7 +8,7 @@ pub(crate) struct MacroEscapeParser; impl NoArgsAttributeParser for MacroEscapeParser { const PATH: &[Symbol] = &[sym::macro_escape]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const ALLOWED_TARGETS: AllowedTargets = MACRO_USE_ALLOWED_TARGETS; + const ALLOWED_TARGETS: AllowedTargets<'_> = MACRO_USE_ALLOWED_TARGETS; const STABILITY: AttributeStability = AttributeStability::Stable; const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::MacroEscape; } @@ -32,7 +32,7 @@ const MACRO_USE_TEMPLATE: AttributeTemplate = template!( Word, List: &["name1, name2, ..."], "https://doc.rust-lang.org/reference/macros-by-example.html#the-macro_use-attribute" ); -const MACRO_USE_ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ +const MACRO_USE_ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ Allow(Target::Mod), Allow(Target::ExternCrate), Error(Target::WherePredicate), @@ -106,7 +106,7 @@ impl AttributeParser for MacroUseParser { } }, )]; - const ALLOWED_TARGETS: AllowedTargets = MACRO_USE_ALLOWED_TARGETS; + const ALLOWED_TARGETS: AllowedTargets<'_> = MACRO_USE_ALLOWED_TARGETS; fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option { Some(AttributeKind::MacroUse { span: self.first_span?, arguments: self.state }) @@ -118,7 +118,7 @@ pub(crate) struct AllowInternalUnsafeParser; impl NoArgsAttributeParser for AllowInternalUnsafeParser { const PATH: &[Symbol] = &[sym::allow_internal_unsafe]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Ignore; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::MacroDef), Warn(Target::Field), @@ -134,7 +134,7 @@ impl SingleAttributeParser for MacroExportParser { const PATH: &[Symbol] = &[sym::macro_export]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const TEMPLATE: AttributeTemplate = template!(Word, List: &["local_inner_macros"]); - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ Allow(Target::MacroDef), Error(Target::WherePredicate), Error(Target::Crate), @@ -174,7 +174,8 @@ impl SingleAttributeParser for CollapseDebugInfoParser { List: &["no", "external", "yes"], "https://doc.rust-lang.org/reference/attributes/debugger.html#the-collapse_debuginfo-attribute" ); - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::MacroDef)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = + AllowedTargets::AllowList(&[Allow(Target::MacroDef)]); const STABILITY: AttributeStability = AttributeStability::Stable; fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option { @@ -204,7 +205,7 @@ pub(crate) struct RustcProcMacroDeclsParser; impl NoArgsAttributeParser for RustcProcMacroDeclsParser { const PATH: &[Symbol] = &[sym::rustc_proc_macro_decls]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Static)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Static)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcProcMacroDecls; } diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 5c64e9f2eaed6..17aaa6ddf9333 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -105,7 +105,7 @@ pub(crate) trait AttributeParser: Default + 'static { /// /// If an attribute has this symbol, the `accept` function will be called on it. const ATTRIBUTES: AcceptMapping; - const ALLOWED_TARGETS: AllowedTargets; + const ALLOWED_TARGETS: AllowedTargets<'_>; const SAFETY: AttributeSafety = AttributeSafety::Normal; /// The parser has gotten a chance to accept the attributes on an item, @@ -140,7 +140,7 @@ pub(crate) trait SingleAttributeParser: 'static { const SAFETY: AttributeSafety = AttributeSafety::Normal; const STABILITY: AttributeStability; - const ALLOWED_TARGETS: AllowedTargets; + const ALLOWED_TARGETS: AllowedTargets<'_>; /// The template this attribute parser should implement. Used for diagnostics. const TEMPLATE: AttributeTemplate; @@ -174,7 +174,7 @@ impl AttributeParser for Single { } }, )]; - const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS; + const ALLOWED_TARGETS: AllowedTargets<'_> = T::ALLOWED_TARGETS; const SAFETY: AttributeSafety = T::SAFETY; fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option { @@ -252,7 +252,7 @@ pub enum AttributeSafety { pub(crate) trait NoArgsAttributeParser: 'static { const PATH: &[Symbol]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; - const ALLOWED_TARGETS: AllowedTargets; + const ALLOWED_TARGETS: AllowedTargets<'_>; const SAFETY: AttributeSafety = AttributeSafety::Normal; const STABILITY: AttributeStability; @@ -273,7 +273,7 @@ impl SingleAttributeParser for WithoutArgs { const ON_DUPLICATE: OnDuplicate = T::ON_DUPLICATE; const SAFETY: AttributeSafety = T::SAFETY; const STABILITY: AttributeStability = T::STABILITY; - const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS; + const ALLOWED_TARGETS: AllowedTargets<'_> = T::ALLOWED_TARGETS; const TEMPLATE: AttributeTemplate = template!(Word); fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option { @@ -303,7 +303,7 @@ pub(crate) trait CombineAttributeParser: 'static { const SAFETY: AttributeSafety = AttributeSafety::Normal; const STABILITY: AttributeStability; - const ALLOWED_TARGETS: AllowedTargets; + const ALLOWED_TARGETS: AllowedTargets<'_>; /// The template this attribute parser should implement. Used for diagnostics. const TEMPLATE: AttributeTemplate; @@ -342,7 +342,7 @@ impl AttributeParser for Combine { group.first_span.get_or_insert(cx.attr_span); group.items.extend(T::extend(cx, args)) })]; - const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS; + const ALLOWED_TARGETS: AllowedTargets<'_> = T::ALLOWED_TARGETS; const SAFETY: AttributeSafety = T::SAFETY; fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option { diff --git a/compiler/rustc_attr_parsing/src/attributes/must_not_suspend.rs b/compiler/rustc_attr_parsing/src/attributes/must_not_suspend.rs index 25fdd5fb3e086..c7c302dd9ee2d 100644 --- a/compiler/rustc_attr_parsing/src/attributes/must_not_suspend.rs +++ b/compiler/rustc_attr_parsing/src/attributes/must_not_suspend.rs @@ -6,7 +6,7 @@ pub(crate) struct MustNotSuspendParser; impl SingleAttributeParser for MustNotSuspendParser { const PATH: &[rustc_span::Symbol] = &[sym::must_not_suspend]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Struct), Allow(Target::Enum), Allow(Target::Union), diff --git a/compiler/rustc_attr_parsing/src/attributes/must_use.rs b/compiler/rustc_attr_parsing/src/attributes/must_use.rs index ae41efd769ed0..62e75a2e7afd9 100644 --- a/compiler/rustc_attr_parsing/src/attributes/must_use.rs +++ b/compiler/rustc_attr_parsing/src/attributes/must_use.rs @@ -7,7 +7,7 @@ pub(crate) struct MustUseParser; impl SingleAttributeParser for MustUseParser { const PATH: &[Symbol] = &[sym::must_use]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ Allow(Target::Fn), Allow(Target::Enum), Allow(Target::Struct), diff --git a/compiler/rustc_attr_parsing/src/attributes/no_implicit_prelude.rs b/compiler/rustc_attr_parsing/src/attributes/no_implicit_prelude.rs index ce172bc41beee..34ceca9092036 100644 --- a/compiler/rustc_attr_parsing/src/attributes/no_implicit_prelude.rs +++ b/compiler/rustc_attr_parsing/src/attributes/no_implicit_prelude.rs @@ -7,7 +7,7 @@ pub(crate) struct NoImplicitPreludeParser; impl NoArgsAttributeParser for NoImplicitPreludeParser { const PATH: &[rustc_span::Symbol] = &[sym::no_implicit_prelude]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[Allow(Target::Mod), Allow(Target::Crate)]); const STABILITY: AttributeStability = AttributeStability::Stable; const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoImplicitPrelude; diff --git a/compiler/rustc_attr_parsing/src/attributes/no_link.rs b/compiler/rustc_attr_parsing/src/attributes/no_link.rs index d067db5df81e6..772ebb6b34f69 100644 --- a/compiler/rustc_attr_parsing/src/attributes/no_link.rs +++ b/compiler/rustc_attr_parsing/src/attributes/no_link.rs @@ -6,7 +6,7 @@ pub(crate) struct NoLinkParser; impl NoArgsAttributeParser for NoLinkParser { const PATH: &[Symbol] = &[sym::no_link]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::ExternCrate), Warn(Target::Field), Warn(Target::Arm), diff --git a/compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs b/compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs index c4cc47e593a6a..cbbaad445f70f 100644 --- a/compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs +++ b/compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs @@ -12,7 +12,7 @@ pub(crate) struct NonExhaustiveParser; impl NoArgsAttributeParser for NonExhaustiveParser { const PATH: &[Symbol] = &[sym::non_exhaustive]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Enum), Allow(Target::Struct), Allow(Target::Variant), diff --git a/compiler/rustc_attr_parsing/src/attributes/path.rs b/compiler/rustc_attr_parsing/src/attributes/path.rs index 57114d850dba8..ad4641c4be7f2 100644 --- a/compiler/rustc_attr_parsing/src/attributes/path.rs +++ b/compiler/rustc_attr_parsing/src/attributes/path.rs @@ -7,7 +7,7 @@ pub(crate) struct PathParser; impl SingleAttributeParser for PathParser { const PATH: &[Symbol] = &[sym::path]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[Allow(Target::Mod), Error(Target::Crate)]); const TEMPLATE: AttributeTemplate = template!( NameValueStr: "file", diff --git a/compiler/rustc_attr_parsing/src/attributes/pin_v2.rs b/compiler/rustc_attr_parsing/src/attributes/pin_v2.rs index ba84b6f8e98c4..59c35690d3c93 100644 --- a/compiler/rustc_attr_parsing/src/attributes/pin_v2.rs +++ b/compiler/rustc_attr_parsing/src/attributes/pin_v2.rs @@ -12,7 +12,7 @@ pub(crate) struct PinV2Parser; impl NoArgsAttributeParser for PinV2Parser { const PATH: &[Symbol] = &[sym::pin_v2]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Enum), Allow(Target::Struct), Allow(Target::Union), diff --git a/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs index 887eb668d65ab..8b2720d2a9ca5 100644 --- a/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs @@ -3,13 +3,13 @@ use rustc_session::lint::builtin::AMBIGUOUS_DERIVE_HELPERS; use super::prelude::*; -const PROC_MACRO_ALLOWED_TARGETS: AllowedTargets = +const PROC_MACRO_ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn), Warn(Target::Crate), Warn(Target::MacroCall)]); pub(crate) struct ProcMacroParser; impl NoArgsAttributeParser for ProcMacroParser { const PATH: &[Symbol] = &[sym::proc_macro]; - const ALLOWED_TARGETS: AllowedTargets = PROC_MACRO_ALLOWED_TARGETS; + const ALLOWED_TARGETS: AllowedTargets<'_> = PROC_MACRO_ALLOWED_TARGETS; const STABILITY: AttributeStability = AttributeStability::Stable; const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ProcMacro; } @@ -17,7 +17,7 @@ impl NoArgsAttributeParser for ProcMacroParser { pub(crate) struct ProcMacroAttributeParser; impl NoArgsAttributeParser for ProcMacroAttributeParser { const PATH: &[Symbol] = &[sym::proc_macro_attribute]; - const ALLOWED_TARGETS: AllowedTargets = PROC_MACRO_ALLOWED_TARGETS; + const ALLOWED_TARGETS: AllowedTargets<'_> = PROC_MACRO_ALLOWED_TARGETS; const STABILITY: AttributeStability = AttributeStability::Stable; const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ProcMacroAttribute; } @@ -25,7 +25,7 @@ impl NoArgsAttributeParser for ProcMacroAttributeParser { pub(crate) struct ProcMacroDeriveParser; impl SingleAttributeParser for ProcMacroDeriveParser { const PATH: &[Symbol] = &[sym::proc_macro_derive]; - const ALLOWED_TARGETS: AllowedTargets = PROC_MACRO_ALLOWED_TARGETS; + const ALLOWED_TARGETS: AllowedTargets<'_> = PROC_MACRO_ALLOWED_TARGETS; const TEMPLATE: AttributeTemplate = template!( List: &["TraitName", "TraitName, attributes(name1, name2, ...)"], "https://doc.rust-lang.org/reference/procedural-macros.html#derive-macros" @@ -44,7 +44,8 @@ impl SingleAttributeParser for ProcMacroDeriveParser { pub(crate) struct RustcBuiltinMacroParser; impl SingleAttributeParser for RustcBuiltinMacroParser { const PATH: &[Symbol] = &[sym::rustc_builtin_macro]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::MacroDef)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = + AllowedTargets::AllowList(&[Allow(Target::MacroDef)]); const TEMPLATE: AttributeTemplate = template!(List: &["TraitName", "TraitName, attributes(name1, name2, ...)"]); const STABILITY: AttributeStability = unstable!(rustc_attrs); diff --git a/compiler/rustc_attr_parsing/src/attributes/prototype.rs b/compiler/rustc_attr_parsing/src/attributes/prototype.rs index ddc40e62a7e8e..a41010395e7c1 100644 --- a/compiler/rustc_attr_parsing/src/attributes/prototype.rs +++ b/compiler/rustc_attr_parsing/src/attributes/prototype.rs @@ -18,7 +18,7 @@ impl SingleAttributeParser for CustomMirParser { const PATH: &[rustc_span::Symbol] = &[sym::custom_mir]; const STABILITY: AttributeStability = unstable!(custom_mir); - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const TEMPLATE: AttributeTemplate = template!(List: &[r#"dialect = "...", phase = "...""#]); diff --git a/compiler/rustc_attr_parsing/src/attributes/repr.rs b/compiler/rustc_attr_parsing/src/attributes/repr.rs index b6e63de1a2095..bf03d87942651 100644 --- a/compiler/rustc_attr_parsing/src/attributes/repr.rs +++ b/compiler/rustc_attr_parsing/src/attributes/repr.rs @@ -63,7 +63,7 @@ impl CombineAttributeParser for ReprParser { reprs } - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::ManuallyChecked; + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::ManuallyChecked; const STABILITY: AttributeStability = AttributeStability::Stable; } @@ -306,7 +306,7 @@ impl RustcAlignParser { impl AttributeParser for RustcAlignParser { const ATTRIBUTES: AcceptMapping = &[(Self::PATH, Self::TEMPLATE, unstable!(fn_align), Self::parse)]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: true })), @@ -336,7 +336,7 @@ impl RustcAlignStaticParser { impl AttributeParser for RustcAlignStaticParser { const ATTRIBUTES: AcceptMapping = &[(Self::PATH, Self::TEMPLATE, unstable!(static_align), Self::parse)]; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Static), Allow(Target::ForeignStatic)]); fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option { diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs index cacf98bef6e93..467289d78da9b 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs @@ -6,7 +6,7 @@ pub(crate) struct RustcAllocatorParser; impl NoArgsAttributeParser for RustcAllocatorParser { const PATH: &[Symbol] = &[sym::rustc_allocator]; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcAllocator; @@ -16,7 +16,7 @@ pub(crate) struct RustcAllocatorZeroedParser; impl NoArgsAttributeParser for RustcAllocatorZeroedParser { const PATH: &[Symbol] = &[sym::rustc_allocator_zeroed]; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcAllocatorZeroed; @@ -26,7 +26,7 @@ pub(crate) struct RustcAllocatorZeroedVariantParser; impl SingleAttributeParser for RustcAllocatorZeroedVariantParser { const PATH: &[Symbol] = &[sym::rustc_allocator_zeroed_variant]; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "function"); const STABILITY: AttributeStability = unstable!(rustc_attrs); @@ -42,7 +42,7 @@ pub(crate) struct RustcDeallocatorParser; impl NoArgsAttributeParser for RustcDeallocatorParser { const PATH: &[Symbol] = &[sym::rustc_deallocator]; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDeallocator; @@ -52,7 +52,7 @@ pub(crate) struct RustcReallocatorParser; impl NoArgsAttributeParser for RustcReallocatorParser { const PATH: &[Symbol] = &[sym::rustc_reallocator]; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcReallocator; diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs index acd5b465a80fe..0fd3d5d65e3a5 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs @@ -10,7 +10,7 @@ pub(crate) struct RustcDumpUserArgsParser; impl NoArgsAttributeParser for RustcDumpUserArgsParser { const PATH: &[Symbol] = &[sym::rustc_dump_user_args]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpUserArgs; } @@ -19,7 +19,7 @@ pub(crate) struct RustcDumpDefParentsParser; impl NoArgsAttributeParser for RustcDumpDefParentsParser { const PATH: &[Symbol] = &[sym::rustc_dump_def_parents]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpDefParents; } @@ -28,7 +28,7 @@ pub(crate) struct RustcDumpDefPathParser; impl SingleAttributeParser for RustcDumpDefPathParser { const PATH: &[Symbol] = &[sym::rustc_dump_def_path]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::TraitImpl)), Allow(Target::Method(MethodKind::Inherent)), @@ -49,7 +49,7 @@ pub(crate) struct RustcDumpGenericsParser; impl NoArgsAttributeParser for RustcDumpGenericsParser { const PATH: &[Symbol] = &[sym::rustc_dump_generics]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Struct), Allow(Target::Enum), Allow(Target::Union), @@ -78,7 +78,7 @@ pub(crate) struct RustcDumpHiddenTypeOfOpaquesParser; impl NoArgsAttributeParser for RustcDumpHiddenTypeOfOpaquesParser { const PATH: &[Symbol] = &[sym::rustc_dump_hidden_type_of_opaques]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpHiddenTypeOfOpaques; } @@ -87,7 +87,7 @@ pub(crate) struct RustcDumpInferredOutlivesParser; impl NoArgsAttributeParser for RustcDumpInferredOutlivesParser { const PATH: &[Symbol] = &[sym::rustc_dump_inferred_outlives]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Struct), Allow(Target::Enum), Allow(Target::Union), @@ -101,7 +101,8 @@ pub(crate) struct RustcDumpItemBoundsParser; impl NoArgsAttributeParser for RustcDumpItemBoundsParser { const PATH: &[Symbol] = &[sym::rustc_dump_item_bounds]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::AssocTy)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = + AllowedTargets::AllowList(&[Allow(Target::AssocTy)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpItemBounds; } @@ -115,7 +116,7 @@ impl CombineAttributeParser for RustcDumpLayoutParser { const CONVERT: ConvertFn = |items, _| AttributeKind::RustcDumpLayout(items); - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Struct), Allow(Target::Enum), Allow(Target::Union), @@ -174,7 +175,7 @@ pub(crate) struct RustcDumpObjectLifetimeDefaultsParser; impl NoArgsAttributeParser for RustcDumpObjectLifetimeDefaultsParser { const PATH: &[Symbol] = &[sym::rustc_dump_object_lifetime_defaults]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::AssocConst), Allow(Target::AssocTy), Allow(Target::Const), @@ -201,7 +202,7 @@ pub(crate) struct RustcDumpPredicatesParser; impl NoArgsAttributeParser for RustcDumpPredicatesParser { const PATH: &[Symbol] = &[sym::rustc_dump_predicates]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::AssocConst), Allow(Target::AssocTy), Allow(Target::Const), @@ -229,7 +230,7 @@ pub(crate) struct RustcDumpSymbolNameParser; impl SingleAttributeParser for RustcDumpSymbolNameParser { const PATH: &[Symbol] = &[sym::rustc_dump_symbol_name]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::TraitImpl)), Allow(Target::Method(MethodKind::Inherent)), @@ -250,7 +251,7 @@ pub(crate) struct RustcDumpVariancesParser; impl NoArgsAttributeParser for RustcDumpVariancesParser { const PATH: &[Symbol] = &[sym::rustc_dump_variances]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Enum), Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), @@ -271,7 +272,7 @@ pub(crate) struct RustcDumpVariancesOfOpaquesParser; impl NoArgsAttributeParser for RustcDumpVariancesOfOpaquesParser { const PATH: &[Symbol] = &[sym::rustc_dump_variances_of_opaques]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpVariancesOfOpaques; } @@ -280,7 +281,7 @@ pub(crate) struct RustcDumpVtableParser; impl NoArgsAttributeParser for RustcDumpVtableParser { const PATH: &[Symbol] = &[sym::rustc_dump_vtable]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Impl { of_trait: true }), Allow(Target::TyAlias), ]); diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 07e24329ccea1..607c908565d3a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -21,7 +21,7 @@ pub(crate) struct RustcMainParser; impl NoArgsAttributeParser for RustcMainParser { const PATH: &[Symbol] = &[sym::rustc_main]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const STABILITY: AttributeStability = unstable!( rustc_attrs, "the `#[rustc_main]` attribute is used internally to specify test entry point function" @@ -33,7 +33,7 @@ pub(crate) struct RustcMustImplementOneOfParser; impl SingleAttributeParser for RustcMustImplementOneOfParser { const PATH: &[Symbol] = &[sym::rustc_must_implement_one_of]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); const STABILITY: AttributeStability = unstable!( rustc_attrs, "the `#[rustc_must_implement_one_of]` attribute is used to change minimal complete definition of a trait. Its syntax and semantics are highly experimental and will be subject to change before stabilization" @@ -79,7 +79,7 @@ pub(crate) struct RustcNeverReturnsNullPtrParser; impl NoArgsAttributeParser for RustcNeverReturnsNullPtrParser { const PATH: &[Symbol] = &[sym::rustc_never_returns_null_ptr]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: false })), @@ -94,7 +94,7 @@ pub(crate) struct RustcNoImplicitAutorefsParser; impl NoArgsAttributeParser for RustcNoImplicitAutorefsParser { const PATH: &[Symbol] = &[sym::rustc_no_implicit_autorefs]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: false })), @@ -110,7 +110,7 @@ pub(crate) struct RustcLegacyConstGenericsParser; impl SingleAttributeParser for RustcLegacyConstGenericsParser { const PATH: &[Symbol] = &[sym::rustc_legacy_const_generics]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const TEMPLATE: AttributeTemplate = template!(List: &["N"]); const STABILITY: AttributeStability = unstable!(rustc_attrs); @@ -150,7 +150,7 @@ pub(crate) struct RustcInheritOverflowChecksParser; impl NoArgsAttributeParser for RustcInheritOverflowChecksParser { const PATH: &[Symbol] = &[sym::rustc_inherit_overflow_checks]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::TraitImpl)), @@ -164,7 +164,7 @@ pub(crate) struct RustcLintOptDenyFieldAccessParser; impl SingleAttributeParser for RustcLintOptDenyFieldAccessParser { const PATH: &[Symbol] = &[sym::rustc_lint_opt_deny_field_access]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Field)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Field)]); const TEMPLATE: AttributeTemplate = template!(Word); const STABILITY: AttributeStability = unstable!(rustc_attrs); fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option { @@ -179,7 +179,7 @@ pub(crate) struct RustcLintOptTyParser; impl NoArgsAttributeParser for RustcLintOptTyParser { const PATH: &[Symbol] = &[sym::rustc_lint_opt_ty]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Struct)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintOptTy; } @@ -306,7 +306,7 @@ impl AttributeParser for RustcCguTestAttributeParser { ), ]; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Mod), Allow(Target::Crate)]); fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option { @@ -318,7 +318,7 @@ pub(crate) struct RustcDeprecatedSafe2024Parser; impl SingleAttributeParser for RustcDeprecatedSafe2024Parser { const PATH: &[Symbol] = &[sym::rustc_deprecated_safe_2024]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: false })), @@ -348,7 +348,7 @@ pub(crate) struct RustcConversionSuggestionParser; impl NoArgsAttributeParser for RustcConversionSuggestionParser { const PATH: &[Symbol] = &[sym::rustc_conversion_suggestion]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: false })), @@ -363,7 +363,8 @@ pub(crate) struct RustcCaptureAnalysisParser; impl NoArgsAttributeParser for RustcCaptureAnalysisParser { const PATH: &[Symbol] = &[sym::rustc_capture_analysis]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Closure)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = + AllowedTargets::AllowList(&[Allow(Target::Closure)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcCaptureAnalysis; } @@ -372,7 +373,7 @@ pub(crate) struct RustcNeverTypeOptionsParser; impl SingleAttributeParser for RustcNeverTypeOptionsParser { const PATH: &[Symbol] = &[sym::rustc_never_type_options]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const TEMPLATE: AttributeTemplate = template!(List: &[ r#"fallback = "unit", "never", "no""#, r#"diverging_block_default = "unit", "never""#, @@ -445,7 +446,7 @@ pub(crate) struct RustcTrivialFieldReadsParser; impl NoArgsAttributeParser for RustcTrivialFieldReadsParser { const PATH: &[Symbol] = &[sym::rustc_trivial_field_reads]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcTrivialFieldReads; } @@ -454,7 +455,7 @@ pub(crate) struct RustcNoMirInlineParser; impl NoArgsAttributeParser for RustcNoMirInlineParser { const PATH: &[Symbol] = &[sym::rustc_no_mir_inline]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: false })), @@ -470,7 +471,7 @@ pub(crate) struct RustcNoWritableParser; impl NoArgsAttributeParser for RustcNoWritableParser { const PATH: &[Symbol] = &[sym::rustc_no_writable]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Closure), Allow(Target::Method(MethodKind::Inherent)), @@ -485,7 +486,7 @@ pub(crate) struct RustcLintQueryInstabilityParser; impl NoArgsAttributeParser for RustcLintQueryInstabilityParser { const PATH: &[Symbol] = &[sym::rustc_lint_query_instability]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: false })), @@ -500,7 +501,7 @@ pub(crate) struct RustcRegionsParser; impl NoArgsAttributeParser for RustcRegionsParser { const PATH: &[Symbol] = &[sym::rustc_regions]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: false })), @@ -515,7 +516,7 @@ pub(crate) struct RustcLintUntrackedQueryInformationParser; impl NoArgsAttributeParser for RustcLintUntrackedQueryInformationParser { const PATH: &[Symbol] = &[sym::rustc_lint_untracked_query_information]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: false })), @@ -530,7 +531,7 @@ pub(crate) struct RustcSimdMonomorphizeLaneLimitParser; impl SingleAttributeParser for RustcSimdMonomorphizeLaneLimitParser { const PATH: &[Symbol] = &[sym::rustc_simd_monomorphize_lane_limit]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Struct)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); const STABILITY: AttributeStability = unstable!(rustc_attrs); @@ -544,7 +545,7 @@ pub(crate) struct RustcScalableVectorParser; impl SingleAttributeParser for RustcScalableVectorParser { const PATH: &[Symbol] = &[sym::rustc_scalable_vector]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Struct)]); const TEMPLATE: AttributeTemplate = template!(Word, List: &["count"]); const STABILITY: AttributeStability = unstable!(rustc_attrs); @@ -566,7 +567,7 @@ pub(crate) struct LangParser; impl SingleAttributeParser for LangParser { const PATH: &[Symbol] = &[sym::lang]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); // Targets are checked per lang item in `rustc_passes` + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::ManuallyChecked; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name"); const STABILITY: AttributeStability = unstable!(lang_items); @@ -607,7 +608,7 @@ pub(crate) struct RustcHasIncoherentInherentImplsParser; impl NoArgsAttributeParser for RustcHasIncoherentInherentImplsParser { const PATH: &[Symbol] = &[sym::rustc_has_incoherent_inherent_impls]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Trait), Allow(Target::Struct), Allow(Target::Enum), @@ -622,7 +623,7 @@ pub(crate) struct PanicHandlerParser; impl NoArgsAttributeParser for PanicHandlerParser { const PATH: &[Symbol] = &[sym::panic_handler]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const STABILITY: AttributeStability = AttributeStability::Stable; const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Lang(LangItem::PanicImpl); } @@ -631,7 +632,7 @@ pub(crate) struct RustcNounwindParser; impl NoArgsAttributeParser for RustcNounwindParser { const PATH: &[Symbol] = &[sym::rustc_nounwind]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::ForeignFn), Allow(Target::Method(MethodKind::Inherent)), @@ -646,7 +647,7 @@ pub(crate) struct RustcOffloadKernelParser; impl NoArgsAttributeParser for RustcOffloadKernelParser { const PATH: &[Symbol] = &[sym::rustc_offload_kernel]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcOffloadKernel; } @@ -659,7 +660,7 @@ impl CombineAttributeParser for RustcMirParser { type Item = RustcMirKind; const CONVERT: ConvertFn = |items, _| AttributeKind::RustcMir(items); - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::TraitImpl)), @@ -735,7 +736,7 @@ pub(crate) struct RustcNonConstTraitMethodParser; impl NoArgsAttributeParser for RustcNonConstTraitMethodParser { const PATH: &[Symbol] = &[sym::rustc_non_const_trait_method]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Method(MethodKind::Trait { body: true })), Allow(Target::Method(MethodKind::Trait { body: false })), ]); @@ -754,7 +755,7 @@ impl CombineAttributeParser for RustcCleanParser { type Item = RustcCleanAttribute; const CONVERT: ConvertFn = |items, _| AttributeKind::RustcClean(items); - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ // tidy-alphabetical-start Allow(Target::AssocConst), Allow(Target::AssocTy), @@ -847,7 +848,7 @@ pub(crate) struct RustcIfThisChangedParser; impl SingleAttributeParser for RustcIfThisChangedParser { const PATH: &[Symbol] = &[sym::rustc_if_this_changed]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ // tidy-alphabetical-start Allow(Target::AssocConst), Allow(Target::AssocTy), @@ -905,7 +906,7 @@ impl CombineAttributeParser for RustcThenThisWouldNeedParser { const CONVERT: ConvertFn = |items, _span| AttributeKind::RustcThenThisWouldNeed(items); - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ // tidy-alphabetical-start Allow(Target::AssocConst), Allow(Target::AssocTy), @@ -952,7 +953,7 @@ pub(crate) struct RustcInsignificantDtorParser; impl NoArgsAttributeParser for RustcInsignificantDtorParser { const PATH: &[Symbol] = &[sym::rustc_insignificant_dtor]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Enum), Allow(Target::Struct), Allow(Target::ForeignTy), @@ -965,7 +966,7 @@ pub(crate) struct RustcEffectiveVisibilityParser; impl NoArgsAttributeParser for RustcEffectiveVisibilityParser { const PATH: &[Symbol] = &[sym::rustc_effective_visibility]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Use), Allow(Target::Static), Allow(Target::Const), @@ -1004,7 +1005,7 @@ pub(crate) struct RustcDiagnosticItemParser; impl SingleAttributeParser for RustcDiagnosticItemParser { const PATH: &[Symbol] = &[sym::rustc_diagnostic_item]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Trait), Allow(Target::Struct), Allow(Target::Enum), @@ -1039,7 +1040,7 @@ pub(crate) struct RustcDoNotConstCheckParser; impl NoArgsAttributeParser for RustcDoNotConstCheckParser { const PATH: &[Symbol] = &[sym::rustc_do_not_const_check]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::TraitImpl)), @@ -1057,7 +1058,7 @@ pub(crate) struct RustcNonnullOptimizationGuaranteedParser; impl NoArgsAttributeParser for RustcNonnullOptimizationGuaranteedParser { const PATH: &[Symbol] = &[sym::rustc_nonnull_optimization_guaranteed]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Struct)]); const STABILITY: AttributeStability = unstable!( rustc_attrs, "the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to document guaranteed niche optimizations in the standard library", @@ -1070,7 +1071,7 @@ pub(crate) struct RustcStrictCoherenceParser; impl NoArgsAttributeParser for RustcStrictCoherenceParser { const PATH: &[Symbol] = &[sym::rustc_strict_coherence]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Trait), Allow(Target::Struct), Allow(Target::Enum), @@ -1085,7 +1086,7 @@ pub(crate) struct RustcReservationImplParser; impl SingleAttributeParser for RustcReservationImplParser { const PATH: &[Symbol] = &[sym::rustc_reservation_impl]; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Impl { of_trait: true })]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "reservation message"); const STABILITY: AttributeStability = unstable!(rustc_attrs); @@ -1102,7 +1103,7 @@ pub(crate) struct PreludeImportParser; impl NoArgsAttributeParser for PreludeImportParser { const PATH: &[Symbol] = &[sym::prelude_import]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Use)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Use)]); const STABILITY: AttributeStability = unstable!(prelude_import); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::PreludeImport; } @@ -1111,7 +1112,7 @@ pub(crate) struct RustcDocPrimitiveParser; impl SingleAttributeParser for RustcDocPrimitiveParser { const PATH: &[Symbol] = &[sym::rustc_doc_primitive]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Mod)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Mod)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "primitive name"); const STABILITY: AttributeStability = unstable!( rustc_attrs, @@ -1130,7 +1131,7 @@ pub(crate) struct RustcIntrinsicParser; impl NoArgsAttributeParser for RustcIntrinsicParser { const PATH: &[Symbol] = &[sym::rustc_intrinsic]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const STABILITY: AttributeStability = unstable!(intrinsics); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcIntrinsic; } @@ -1139,7 +1140,7 @@ pub(crate) struct RustcIntrinsicConstStableIndirectParser; impl NoArgsAttributeParser for RustcIntrinsicConstStableIndirectParser { const PATH: &'static [Symbol] = &[sym::rustc_intrinsic_const_stable_indirect]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcIntrinsicConstStableIndirect; } @@ -1148,7 +1149,7 @@ pub(crate) struct RustcExhaustiveParser; impl NoArgsAttributeParser for RustcExhaustiveParser { const PATH: &'static [Symbol] = &[sym::rustc_must_match_exhaustively]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Enum)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Enum)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcMustMatchExhaustively; } diff --git a/compiler/rustc_attr_parsing/src/attributes/semantics.rs b/compiler/rustc_attr_parsing/src/attributes/semantics.rs index 07c07eb6681df..74b2cc2ffd5a1 100644 --- a/compiler/rustc_attr_parsing/src/attributes/semantics.rs +++ b/compiler/rustc_attr_parsing/src/attributes/semantics.rs @@ -5,7 +5,7 @@ use super::prelude::*; pub(crate) struct MayDangleParser; impl NoArgsAttributeParser for MayDangleParser { const PATH: &[Symbol] = &[sym::may_dangle]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); //FIXME Still checked fully in `check_attr.rs` + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(ALL_TARGETS); //FIXME Still checked fully in `check_attr.rs` const STABILITY: AttributeStability = unstable!(dropck_eyepatch); const CREATE: fn(span: Span) -> AttributeKind = AttributeKind::MayDangle; } @@ -14,7 +14,7 @@ pub(crate) struct ComptimeParser; impl NoArgsAttributeParser for ComptimeParser { const PATH: &[Symbol] = &[sym::rustc_comptime]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Fn), ]); diff --git a/compiler/rustc_attr_parsing/src/attributes/splat.rs b/compiler/rustc_attr_parsing/src/attributes/splat.rs index 65fc9fb8123f4..ab34021ad7cdf 100644 --- a/compiler/rustc_attr_parsing/src/attributes/splat.rs +++ b/compiler/rustc_attr_parsing/src/attributes/splat.rs @@ -9,7 +9,7 @@ pub(crate) struct SplatParser; impl NoArgsAttributeParser for SplatParser { const PATH: &[Symbol] = &[sym::splat]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Param)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Param)]); const STABILITY: AttributeStability = unstable!(splat, "the `#[splat]` attribute is experimental"); const CREATE: fn(Span) -> AttributeKind = AttributeKind::Splat; diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs index b38bb6d535770..d8dbe167ed175 100644 --- a/compiler/rustc_attr_parsing/src/attributes/stability.rs +++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs @@ -13,7 +13,7 @@ use super::prelude::*; use super::util::parse_version; use crate::session_diagnostics; -const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ +const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Struct), Allow(Target::Enum), @@ -102,7 +102,7 @@ impl AttributeParser for StabilityParser { }, ), ]; - const ALLOWED_TARGETS: AllowedTargets = ALLOWED_TARGETS; + const ALLOWED_TARGETS: AllowedTargets<'_> = ALLOWED_TARGETS; fn finalize(mut self, cx: &FinalizeContext<'_, '_>) -> Option { if let Some(atum) = self.allowed_through_unstable_modules { @@ -158,7 +158,7 @@ impl AttributeParser for BodyStabilityParser { } }, )]; - const ALLOWED_TARGETS: AllowedTargets = ALLOWED_TARGETS; + const ALLOWED_TARGETS: AllowedTargets<'_> = ALLOWED_TARGETS; fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option { let (stability, span) = self.stability?; @@ -171,7 +171,7 @@ pub(crate) struct RustcConstStableIndirectParser; impl NoArgsAttributeParser for RustcConstStableIndirectParser { const PATH: &[Symbol] = &[sym::rustc_const_stable_indirect]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Ignore; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), ]); @@ -233,7 +233,7 @@ impl AttributeParser for ConstStabilityParser { this.promotable = true; }), ]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::TraitImpl)), @@ -460,7 +460,7 @@ pub(crate) struct UnstableRemovedParser; impl CombineAttributeParser for UnstableRemovedParser { type Item = UnstableRemovedFeature; const PATH: &[Symbol] = &[sym::unstable_removed]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const TEMPLATE: AttributeTemplate = template!(List: &[r#"feature = "name", reason = "...", link = "...", since = "version""#]); const STABILITY: AttributeStability = unstable!(staged_api); diff --git a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs index 00e113f171715..8905591bdba5a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs @@ -9,7 +9,7 @@ pub(crate) struct IgnoreParser; impl SingleAttributeParser for IgnoreParser { const PATH: &[Symbol] = &[sym::ignore]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[Allow(Target::Fn), Error(Target::WherePredicate)]); const TEMPLATE: AttributeTemplate = template!( Word, NameValueStr: "reason", @@ -51,7 +51,7 @@ pub(crate) struct ShouldPanicParser; impl SingleAttributeParser for ShouldPanicParser { const PATH: &[Symbol] = &[sym::should_panic]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[Allow(Target::Fn), Error(Target::WherePredicate)]); const TEMPLATE: AttributeTemplate = template!( Word, List: &[r#"expected = "reason""#], NameValueStr: "reason", @@ -83,7 +83,7 @@ pub(crate) struct ReexportTestHarnessMainParser; impl SingleAttributeParser for ReexportTestHarnessMainParser { const PATH: &[Symbol] = &[sym::reexport_test_harness_main]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name"); const STABILITY: AttributeStability = unstable!(custom_test_frameworks); @@ -105,7 +105,7 @@ pub(crate) struct RustcAbiParser; impl SingleAttributeParser for RustcAbiParser { const PATH: &[Symbol] = &[sym::rustc_abi]; const TEMPLATE: AttributeTemplate = template!(OneOf: &[sym::debug, sym::assert_eq]); - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::TyAlias), Allow(Target::Fn), Allow(Target::ForeignFn), @@ -150,7 +150,7 @@ pub(crate) struct RustcDelayedBugFromInsideQueryParser; impl NoArgsAttributeParser for RustcDelayedBugFromInsideQueryParser { const PATH: &[Symbol] = &[sym::rustc_delayed_bug_from_inside_query]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDelayedBugFromInsideQuery; } @@ -159,7 +159,7 @@ pub(crate) struct RustcEvaluateWhereClausesParser; impl NoArgsAttributeParser for RustcEvaluateWhereClausesParser { const PATH: &[Symbol] = &[sym::rustc_evaluate_where_clauses]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: true })), @@ -174,7 +174,7 @@ pub(crate) struct TestRunnerParser; impl SingleAttributeParser for TestRunnerParser { const PATH: &[Symbol] = &[sym::test_runner]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const TEMPLATE: AttributeTemplate = template!(List: &["path"]); const STABILITY: AttributeStability = unstable!(custom_test_frameworks); @@ -194,7 +194,7 @@ pub(crate) struct RustcTestMarkerParser; impl SingleAttributeParser for RustcTestMarkerParser { const PATH: &[Symbol] = &[sym::rustc_test_marker]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Const), Allow(Target::Fn), Allow(Target::Static), diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index 505cdea2477bf..a2348eef975cf 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -12,7 +12,7 @@ use crate::target_checking::Policy::{Allow, Warn}; pub(crate) struct RustcSkipDuringMethodDispatchParser; impl SingleAttributeParser for RustcSkipDuringMethodDispatchParser { const PATH: &[Symbol] = &[sym::rustc_skip_during_method_dispatch]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); const TEMPLATE: AttributeTemplate = template!(List: &["array, boxed_slice"]); const STABILITY: AttributeStability = unstable!(rustc_attrs); @@ -52,7 +52,7 @@ impl SingleAttributeParser for RustcSkipDuringMethodDispatchParser { pub(crate) struct RustcParenSugarParser; impl NoArgsAttributeParser for RustcParenSugarParser { const PATH: &[Symbol] = &[sym::rustc_paren_sugar]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcParenSugar; } @@ -62,7 +62,7 @@ impl NoArgsAttributeParser for RustcParenSugarParser { pub(crate) struct MarkerParser; impl NoArgsAttributeParser for MarkerParser { const PATH: &[Symbol] = &[sym::marker]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Trait), Warn(Target::Field), Warn(Target::Arm), @@ -75,7 +75,7 @@ impl NoArgsAttributeParser for MarkerParser { pub(crate) struct RustcDenyExplicitImplParser; impl NoArgsAttributeParser for RustcDenyExplicitImplParser { const PATH: &[Symbol] = &[sym::rustc_deny_explicit_impl]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDenyExplicitImpl; } @@ -83,7 +83,7 @@ impl NoArgsAttributeParser for RustcDenyExplicitImplParser { pub(crate) struct RustcDynIncompatibleTraitParser; impl NoArgsAttributeParser for RustcDynIncompatibleTraitParser { const PATH: &[Symbol] = &[sym::rustc_dyn_incompatible_trait]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcDynIncompatibleTrait; } @@ -93,7 +93,7 @@ impl NoArgsAttributeParser for RustcDynIncompatibleTraitParser { pub(crate) struct RustcSpecializationTraitParser; impl NoArgsAttributeParser for RustcSpecializationTraitParser { const PATH: &[Symbol] = &[sym::rustc_specialization_trait]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcSpecializationTrait; } @@ -101,7 +101,7 @@ impl NoArgsAttributeParser for RustcSpecializationTraitParser { pub(crate) struct RustcUnsafeSpecializationMarkerParser; impl NoArgsAttributeParser for RustcUnsafeSpecializationMarkerParser { const PATH: &[Symbol] = &[sym::rustc_unsafe_specialization_marker]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcUnsafeSpecializationMarker; } @@ -111,7 +111,7 @@ impl NoArgsAttributeParser for RustcUnsafeSpecializationMarkerParser { pub(crate) struct RustcCoinductiveParser; impl NoArgsAttributeParser for RustcCoinductiveParser { const PATH: &[Symbol] = &[sym::rustc_coinductive]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcCoinductive; } @@ -119,7 +119,7 @@ impl NoArgsAttributeParser for RustcCoinductiveParser { pub(crate) struct RustcAllowIncoherentImplParser; impl NoArgsAttributeParser for RustcAllowIncoherentImplParser { const PATH: &[Symbol] = &[sym::rustc_allow_incoherent_impl]; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Method(MethodKind::Inherent))]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcAllowIncoherentImpl; @@ -128,7 +128,7 @@ impl NoArgsAttributeParser for RustcAllowIncoherentImplParser { pub(crate) struct FundamentalParser; impl NoArgsAttributeParser for FundamentalParser { const PATH: &[Symbol] = &[sym::fundamental]; - const ALLOWED_TARGETS: AllowedTargets = + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Struct), Allow(Target::Trait)]); const STABILITY: AttributeStability = unstable!(fundamental); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Fundamental; diff --git a/compiler/rustc_attr_parsing/src/attributes/transparency.rs b/compiler/rustc_attr_parsing/src/attributes/transparency.rs index ad40f30ef418a..7f5cceb501acd 100644 --- a/compiler/rustc_attr_parsing/src/attributes/transparency.rs +++ b/compiler/rustc_attr_parsing/src/attributes/transparency.rs @@ -11,7 +11,8 @@ impl SingleAttributeParser for RustcMacroTransparencyParser { cx.dcx().span_err(vec![used, unused], "multiple macro transparency attributes"); }); const STABILITY: AttributeStability = unstable!(rustc_attrs); - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::MacroDef)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = + AllowedTargets::AllowList(&[Allow(Target::MacroDef)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: ["transparent", "semiopaque", "opaque"]); diff --git a/compiler/rustc_attr_parsing/src/attributes/unroll.rs b/compiler/rustc_attr_parsing/src/attributes/unroll.rs index b10ddcf9dc4fc..50c73ca041cdd 100644 --- a/compiler/rustc_attr_parsing/src/attributes/unroll.rs +++ b/compiler/rustc_attr_parsing/src/attributes/unroll.rs @@ -7,7 +7,7 @@ use super::prelude::*; pub(crate) struct UnrollParser; impl SingleAttributeParser for UnrollParser { const PATH: &[Symbol] = &[sym::unroll]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Loop), Allow(Target::ForLoop), Allow(Target::While), diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 14e443c922711..1595d2f80ddc7 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -85,7 +85,7 @@ pub(super) struct GroupTypeInner { pub(super) struct GroupTypeInnerAccept { pub(super) template: AttributeTemplate, pub(super) accept_fn: AcceptFn, - pub(super) allowed_targets: AllowedTargets, + pub(super) allowed_targets: AllowedTargets<'static>, pub(super) safety: AttributeSafety, pub(super) stability: AttributeStability, pub(super) finalizer: FinalizeFn, diff --git a/compiler/rustc_attr_parsing/src/diagnostics.rs b/compiler/rustc_attr_parsing/src/diagnostics.rs index cf6a773bd1394..f2201efe0507e 100644 --- a/compiler/rustc_attr_parsing/src/diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/diagnostics.rs @@ -1,5 +1,4 @@ -use rustc_errors::E0264; -use rustc_errors::{Applicability, DiagArgValue, E0232, E0718, MultiSpan}; +use rustc_errors::{Applicability, DiagArgValue, E0232, E0264, E0718, MultiSpan}; use rustc_hir::{AttrPath, Target}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::{Span, Symbol}; diff --git a/compiler/rustc_attr_parsing/src/target_checking.rs b/compiler/rustc_attr_parsing/src/target_checking.rs index 9903c6aa68d01..04f5c2ea39f70 100644 --- a/compiler/rustc_attr_parsing/src/target_checking.rs +++ b/compiler/rustc_attr_parsing/src/target_checking.rs @@ -16,9 +16,9 @@ use crate::target_checking::Policy::Allow; use crate::{AttributeParser, ShouldEmit}; #[derive(Debug)] -pub(crate) enum AllowedTargets { - AllowList(&'static [Policy]), - AllowListWarnRest(&'static [Policy]), +pub(crate) enum AllowedTargets<'a> { + AllowList(&'a [Policy]), + AllowListWarnRest(&'a [Policy]), /// This is useful for argument-dependent target checking. /// If debug assertions are enabled, /// this emits a delayed bug if the `cx.check_target(...)` method is not called during attribute parsing. @@ -31,7 +31,7 @@ pub(crate) enum AllowedResult { Error, } -impl AllowedTargets { +impl AllowedTargets<'_> { pub(crate) fn is_allowed(&self, target: Target) -> AllowedResult { match self { AllowedTargets::AllowList(list) => { @@ -94,7 +94,7 @@ pub(crate) enum Policy { impl<'sess> AttributeParser<'sess> { pub(crate) fn check_target( - allowed_targets: &AllowedTargets, + allowed_targets: &AllowedTargets<'_>, attribute_args: &'static str, cx: &mut AcceptContext<'_, 'sess>, ) { @@ -444,7 +444,7 @@ impl<'f, 'sess> AcceptContext<'f, 'sess> { pub(crate) fn check_target( &mut self, attribute_args: &'static str, - allowed_targets: &AllowedTargets, + allowed_targets: &AllowedTargets<'_>, ) { self.ignore_target_checks(); AttributeParser::check_target(allowed_targets, attribute_args, self); diff --git a/compiler/rustc_passes/src/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs index 98e0c0f241b4c..50730b852455c 100644 --- a/compiler/rustc_passes/src/weak_lang_items.rs +++ b/compiler/rustc_passes/src/weak_lang_items.rs @@ -9,9 +9,7 @@ use rustc_middle::middle::lang_items::required; use rustc_middle::ty::TyCtxt; use rustc_session::config::CrateType; -use crate::diagnostics::{ - MissingLangItem, MissingPanicHandler, PanicUnwindWithoutStd, -}; +use crate::diagnostics::{MissingLangItem, MissingPanicHandler, PanicUnwindWithoutStd}; use crate::lang_items::extract_ast; /// Checks the crate for usage of weak lang items, returning a vector of all the From 9ad6dbf24ff30bde68c58b537c30526762ad6615 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 21 Jun 2026 21:08:31 +0200 Subject: [PATCH 27/42] Use `AllowedTargets::ManuallyChecked` for `LangParser` --- .../src/attributes/rustc_internal.rs | 20 ++++++++----------- .../rustc_attr_parsing/src/diagnostics.rs | 15 ++------------ .../src/session_diagnostics.rs | 2 +- .../rustc_attr_parsing/src/target_checking.rs | 8 ++++---- .../src/error_codes/E0718.md | 4 +++- tests/ui/error-codes/E0718.rs | 2 +- tests/ui/error-codes/E0718.stderr | 7 ++++--- 7 files changed, 23 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 607c908565d3a..d4e15b8964ff7 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -12,7 +12,7 @@ use rustc_span::Symbol; use super::prelude::*; use super::util::parse_single_integer; use crate::diagnostics; -use crate::diagnostics::{LangItemOnIncorrectTarget, UnknownExternLangItem}; +use crate::diagnostics::UnknownExternLangItem; use crate::session_diagnostics::{ AttributeRequiresOpt, CguFieldsMissing, RustcScalableVectorCountOutOfRange, UnknownLangItem, }; @@ -589,17 +589,13 @@ impl SingleAttributeParser for LangParser { } // Check the target - if cx.target != lang_item.target() - && !(cx.target == Target::ForeignFn && lang_item == LangItem::PanicImpl) - { - cx.emit_err(LangItemOnIncorrectTarget { - span: cx.attr_span, - name, - expected_target: lang_item.target(), - actual_target: cx.target, - }); - return None; - } + let allowed_targets: &[_] = if lang_item == LangItem::PanicImpl { + &[Allow(Target::Fn), Allow(Target::ForeignFn)] + } else { + &[Allow(lang_item.target())] + }; + cx.check_target(&format!(" = \"{name}\""), &AllowedTargets::AllowList(allowed_targets)); + Some(AttributeKind::Lang(lang_item)) } } diff --git a/compiler/rustc_attr_parsing/src/diagnostics.rs b/compiler/rustc_attr_parsing/src/diagnostics.rs index f2201efe0507e..d8b7144aa01ba 100644 --- a/compiler/rustc_attr_parsing/src/diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/diagnostics.rs @@ -1,5 +1,5 @@ -use rustc_errors::{Applicability, DiagArgValue, E0232, E0264, E0718, MultiSpan}; -use rustc_hir::{AttrPath, Target}; +use rustc_errors::{Applicability, DiagArgValue, E0232, E0264, MultiSpan}; +use rustc_hir::AttrPath; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::{Span, Symbol}; @@ -802,17 +802,6 @@ pub(crate) struct UnsafeAttribute { pub note: &'static str, } -#[derive(Diagnostic)] -#[diag("`{$name}` lang item must be applied to a {$expected_target}", code = E0718)] -pub(crate) struct LangItemOnIncorrectTarget { - #[primary_span] - #[label("attribute should be applied to a {$expected_target}, not a {$actual_target}")] - pub span: Span, - pub name: Symbol, - pub expected_target: Target, - pub actual_target: Target, -} - #[derive(Diagnostic)] #[diag("unknown external lang item: `{$lang_item}`", code = E0264)] pub(crate) struct UnknownExternLangItem { diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 494824a8393b3..fef6f7d9e5503 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -337,7 +337,7 @@ pub(crate) struct InvalidTarget { pub target: &'static str, pub applied: DiagArgValue, pub only: &'static str, - pub attribute_args: &'static str, + pub attribute_args: String, #[subdiagnostic] pub help: Option, #[warning( diff --git a/compiler/rustc_attr_parsing/src/target_checking.rs b/compiler/rustc_attr_parsing/src/target_checking.rs index 04f5c2ea39f70..96737be04f5b2 100644 --- a/compiler/rustc_attr_parsing/src/target_checking.rs +++ b/compiler/rustc_attr_parsing/src/target_checking.rs @@ -95,7 +95,7 @@ pub(crate) enum Policy { impl<'sess> AttributeParser<'sess> { pub(crate) fn check_target( allowed_targets: &AllowedTargets<'_>, - attribute_args: &'static str, + attribute_args: &str, cx: &mut AcceptContext<'_, 'sess>, ) { if matches!(cx.should_emit, ShouldEmit::Nothing) { @@ -137,7 +137,7 @@ impl<'sess> AttributeParser<'sess> { target: cx.target.plural_name(), only: if only { "only " } else { "" }, applied: DiagArgValue::StrListSepByAnd(applied.into_iter().map(Cow::Owned).collect()), - attribute_args, + attribute_args: attribute_args.to_string(), help: Self::target_checking_help(attribute_args, cx), previously_accepted: matches!(result, AllowedResult::Warn) && !is_diagnostic_attr, on_macro_call: matches!(cx.target, Target::MacroCall), @@ -173,7 +173,7 @@ impl<'sess> AttributeParser<'sess> { } fn target_checking_help( - attribute_args: &'static str, + attribute_args: &str, cx: &AcceptContext<'_, '_>, ) -> Option { match &*cx.attr_path.segments { @@ -443,7 +443,7 @@ fn filter_targets( impl<'f, 'sess> AcceptContext<'f, 'sess> { pub(crate) fn check_target( &mut self, - attribute_args: &'static str, + attribute_args: &str, allowed_targets: &AllowedTargets<'_>, ) { self.ignore_target_checks(); diff --git a/compiler/rustc_error_codes/src/error_codes/E0718.md b/compiler/rustc_error_codes/src/error_codes/E0718.md index 1fe62ecf1f4e0..2ecf3081d2ed6 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0718.md +++ b/compiler/rustc_error_codes/src/error_codes/E0718.md @@ -1,8 +1,10 @@ +#### Note: this error code is no longer emitted by the compiler. + A `#[lang = ".."]` attribute was placed on the wrong item type. Erroneous code example: -```compile_fail,E0718 +```compile_fail #![feature(lang_items)] #[lang = "owned_box"] diff --git a/tests/ui/error-codes/E0718.rs b/tests/ui/error-codes/E0718.rs index 358bc348ec76d..87e366c91a609 100644 --- a/tests/ui/error-codes/E0718.rs +++ b/tests/ui/error-codes/E0718.rs @@ -1,7 +1,7 @@ #![feature(lang_items)] // Box is expected to be a struct, so this will error. -#[lang = "owned_box"] //~ ERROR lang item must be applied to a struct +#[lang = "owned_box"] //~ ERROR `#[lang = "owned_box"]` attribute cannot be used on statics static X: u32 = 42; fn main() {} diff --git a/tests/ui/error-codes/E0718.stderr b/tests/ui/error-codes/E0718.stderr index e7784d193ba7b..873c714df8c2f 100644 --- a/tests/ui/error-codes/E0718.stderr +++ b/tests/ui/error-codes/E0718.stderr @@ -1,9 +1,10 @@ -error[E0718]: `owned_box` lang item must be applied to a struct +error: `#[lang = "owned_box"]` attribute cannot be used on statics --> $DIR/E0718.rs:4:1 | LL | #[lang = "owned_box"] - | ^^^^^^^^^^^^^^^^^^^^^ attribute should be applied to a struct, not a static + | ^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[lang = "owned_box"]` can only be applied to structs error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0718`. From 68632812fe6be9b70f0ae945e74a274ef80b8517 Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Sun, 21 Jun 2026 12:58:34 +0200 Subject: [PATCH 28/42] Split `resolve_ident_in_module_non_globs_unadjusted` into local and external `module` variants. --- compiler/rustc_resolve/src/ident.rs | 103 ++++++++++++++++++++-------- 1 file changed, 76 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 2e69405811db4..86d740a93f651 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -23,9 +23,9 @@ use crate::late::{ use crate::macros::{MacroRulesScope, sub_namespace_match}; use crate::{ AmbiguityError, AmbiguityKind, AmbiguityWarning, BindingKey, CmResolver, Decl, DeclKind, - Determinacy, Finalize, IdentKey, ImportKind, ImportSummary, LateDecl, LocalModule, Module, - ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError, Res, ResolutionError, - Resolver, Scope, ScopeSet, Segment, Stage, Symbol, Used, diagnostics, + Determinacy, ExternModule, Finalize, IdentKey, ImportKind, ImportSummary, LateDecl, + LocalModule, Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError, + Res, ResolutionError, Resolver, Scope, ScopeSet, Segment, Stage, Symbol, Used, diagnostics, }; #[derive(Copy, Clone)] @@ -608,21 +608,36 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { finalize.map(|f| Finalize { used: Used::Scope, ..f }), ) }; - let decl = self.reborrow().resolve_ident_in_module_non_globs_unadjusted( - module, - ident, - orig_ident_span, - ns, - adjusted_parent_scope, - if matches!(scope_set, ScopeSet::Module(..)) { - Shadowing::Unrestricted - } else { - Shadowing::Restricted - }, - adjusted_finalize, - ignore_decl, - ignore_import, - ); + let shadowing = if matches!(scope_set, ScopeSet::Module(..)) { + Shadowing::Unrestricted + } else { + Shadowing::Restricted + }; + let decl = if module.is_local() { + self.reborrow().resolve_ident_in_local_module_non_globs_unadjusted( + module.expect_local(), + ident, + orig_ident_span, + ns, + adjusted_parent_scope, + shadowing, + adjusted_finalize, + ignore_decl, + ignore_import, + ) + } else { + self.reborrow().resolve_ident_in_extern_module_non_globs_unadjusted( + module.expect_extern(), + ident, + orig_ident_span, + ns, + adjusted_parent_scope, + shadowing, + adjusted_finalize, + ignore_decl, + ) + }; + match decl { Ok(decl) => { if let Some(lint_id) = derive_fallback_lint_id { @@ -1078,10 +1093,49 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } } - /// Attempts to resolve `ident` in namespace `ns` of non-glob bindings in `module`. - fn resolve_ident_in_module_non_globs_unadjusted<'r>( + /// Attempts to resolve `ident` in namespace `ns` of non-glob bindings in an external `module`. + fn resolve_ident_in_extern_module_non_globs_unadjusted<'r>( mut self: CmResolver<'r, 'ra, 'tcx>, - module: Module<'ra>, + module: ExternModule<'ra>, + ident: IdentKey, + orig_ident_span: Span, + ns: Namespace, + parent_scope: &ParentScope<'ra>, + shadowing: Shadowing, + finalize: Option, + // This binding should be ignored during in-module resolution, so that we don't get + // "self-confirming" import resolutions during import validation and checking. + ignore_decl: Option>, + ) -> Result, ControlFlow> { + let key = BindingKey::new(ident, ns); + let resolution = + &*self.resolution(module.to_module(), key).ok_or(ControlFlow::Continue(Determined))?; + + let binding = resolution.non_glob_decl.filter(|b| Some(*b) != ignore_decl); + + if let Some(finalize) = finalize { + return self.get_mut().finalize_module_binding( + ident, + orig_ident_span, + binding, + parent_scope, + finalize, + shadowing, + ); + } + + // Items and single imports are not shadowable, if we have one, then it's determined. + if let Some(binding) = binding { + let accessible = self.is_accessible_from(binding.vis(), parent_scope.module); + return if accessible { Ok(binding) } else { Err(ControlFlow::Break(Determined)) }; + } + Err(ControlFlow::Continue(Determined)) + } + + /// Attempts to resolve `ident` in namespace `ns` of non-glob bindings in a local `module`. + fn resolve_ident_in_local_module_non_globs_unadjusted<'r>( + mut self: CmResolver<'r, 'ra, 'tcx>, + module: LocalModule<'ra>, ident: IdentKey, orig_ident_span: Span, ns: Namespace, @@ -1098,7 +1152,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // doesn't need to be mutable. It will fail when there is a cycle of imports, and without // the exclusive access infinite recursion will crash the compiler with stack overflow. let resolution = &*self - .resolution_or_default(module, key, orig_ident_span) + .resolution_or_default(module.to_module(), key, orig_ident_span) .try_borrow_mut_unchecked() .map_err(|_| ControlFlow::Continue(Determined))?; @@ -1121,11 +1175,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { return if accessible { Ok(binding) } else { Err(ControlFlow::Break(Determined)) }; } - // In extern modules everything is determined from the start. - if !module.is_local() { - return Err(ControlFlow::Continue(Determined)); - }; - // Check if one of single imports can still define the name, block if it can. if self.reborrow().single_import_can_define_name( &resolution, From 0eb146cbab32a8082c2b43df7abaf6ef1113b42d Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Thu, 18 Jun 2026 22:27:27 +0000 Subject: [PATCH 29/42] Extract all instance shim variants into new `ShimKind` enum They tend to have similar handling -- e.g., they should be the only input to the `mir_shims` query -- so it's cleaner to group them together. This will also make potential future refactorings easier, such as only carrying `GenericArgsRef` for instances that actually use it (e.g., `Item`) but not others (e.g., `CloneShim`). Many of the shim variants still have `Shim` at the end of their names. To make the refactoring easier and keep the diff clean, I will trim those suffixes off in the next commit. --- .../rustc_codegen_cranelift/src/abi/mod.rs | 6 +- .../rustc_codegen_cranelift/src/constant.rs | 2 +- .../src/back/symbol_export.rs | 18 +- compiler/rustc_codegen_ssa/src/mir/block.rs | 4 +- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 2 +- .../rustc_const_eval/src/interpret/call.rs | 26 +- .../rustc_const_eval/src/interpret/step.rs | 2 +- .../src/middle/codegen_fn_attrs.rs | 11 +- .../src/middle/exported_symbols.rs | 2 +- compiler/rustc_middle/src/mir/mod.rs | 8 +- compiler/rustc_middle/src/mir/pretty.rs | 8 +- compiler/rustc_middle/src/mir/visit.rs | 30 +-- compiler/rustc_middle/src/mono.rs | 30 +-- compiler/rustc_middle/src/queries.rs | 4 +- compiler/rustc_middle/src/query/keys.rs | 6 + compiler/rustc_middle/src/ty/instance.rs | 237 +++++++++++------- compiler/rustc_middle/src/ty/mod.rs | 21 +- compiler/rustc_middle/src/ty/print/mod.rs | 57 +++-- .../rustc_mir_transform/src/coroutine/drop.rs | 2 +- .../rustc_mir_transform/src/coroutine/mod.rs | 2 +- compiler/rustc_mir_transform/src/inline.rs | 33 +-- .../rustc_mir_transform/src/inline/cycle.rs | 26 +- compiler/rustc_mir_transform/src/shim.rs | 88 +++---- .../src/shim/async_destructor_ctor.rs | 20 +- compiler/rustc_monomorphize/src/collector.rs | 34 +-- .../rustc_monomorphize/src/partitioning.rs | 60 ++--- .../src/unstable/convert/stable/ty.rs | 13 +- .../rustc_public_bridge/src/context/impls.rs | 2 +- .../cfi/typeid/itanium_cxx_abi/transform.rs | 7 +- .../rustc_sanitizers/src/kcfi/typeid/mod.rs | 5 +- compiler/rustc_symbol_mangling/src/legacy.rs | 21 +- compiler/rustc_symbol_mangling/src/v0.rs | 32 ++- compiler/rustc_ty_utils/src/abi.rs | 40 +-- compiler/rustc_ty_utils/src/instance.rs | 59 +++-- 34 files changed, 502 insertions(+), 416 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index 0eb493036ce51..8f965a5ef7b12 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -16,9 +16,9 @@ use rustc_abi::{CanonAbi, ExternAbi, X86Call}; use rustc_codegen_ssa::base::is_call_from_compiler_builtins_to_upstream_monomorphization; use rustc_codegen_ssa::errors::CompilerBuiltinsCannotCall; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; -use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::print::with_no_trimmed_paths; +use rustc_middle::ty::{ShimKind, TypeVisitableExt}; use rustc_session::Session; use rustc_span::Spanned; use rustc_target::callconv::{FnAbi, PassMode}; @@ -467,7 +467,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( } // We don't need AsyncDropGlueCtorShim here because it is not `noop func`, // it is `func returning noop future` - InstanceKind::DropGlue(_, None) => { + InstanceKind::Shim(ShimKind::DropGlue(_, None)) => { // empty drop glue - a nop. let dest = target.expect("Non terminating drop_in_place_real???"); let ret_block = fx.get_block(dest); @@ -725,7 +725,7 @@ pub(crate) fn codegen_drop<'tcx>( let ret_block = fx.get_block(target); // AsyncDropGlueCtorShim can't be here - if let ty::InstanceKind::DropGlue(_, None) = drop_instance.def { + if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) = drop_instance.def { // we don't actually need to drop anything fx.bcx.ins().jump(ret_block, &[]); } else { diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index c986666f9c46e..a83bfd1cbad42 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -53,7 +53,7 @@ pub(crate) fn codegen_tls_ref<'tcx>( ) -> CValue<'tcx> { let tls_ptr = if !def_id.is_local() && fx.tcx.needs_thread_local_shim(def_id) { let instance = ty::Instance { - def: ty::InstanceKind::ThreadLocalShim(def_id), + def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(def_id)), args: ty::GenericArgs::empty(), }; let func_ref = fx.get_function_ref(instance); diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 014fd5cf3a0e5..40d5c3b07059f 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -11,7 +11,9 @@ use rustc_middle::middle::exported_symbols::{ ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel, }; use rustc_middle::query::LocalCrate; -use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, Instance, SymbolName, Ty, TyCtxt}; +use rustc_middle::ty::{ + self, GenericArgKind, GenericArgsRef, Instance, ShimKind, SymbolName, Ty, TyCtxt, +}; use rustc_middle::util::Providers; use rustc_session::config::CrateType; use rustc_span::Span; @@ -332,7 +334,10 @@ fn exported_generic_symbols_provider_local<'tcx>( )); } } - MonoItem::Fn(Instance { def: InstanceKind::DropGlue(_, Some(ty)), args }) => { + MonoItem::Fn(Instance { + def: InstanceKind::Shim(ShimKind::DropGlue(_, Some(ty))), + args, + }) => { // A little sanity-check assert_eq!(args.non_erasable_generics().next(), Some(GenericArgKind::Type(ty))); @@ -356,7 +361,7 @@ fn exported_generic_symbols_provider_local<'tcx>( } } MonoItem::Fn(Instance { - def: InstanceKind::AsyncDropGlueCtorShim(_, ty), + def: InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(_, ty)), args, }) => { // A little sanity-check @@ -371,7 +376,10 @@ fn exported_generic_symbols_provider_local<'tcx>( }, )); } - MonoItem::Fn(Instance { def: InstanceKind::AsyncDropGlue(def, ty), args: _ }) => { + MonoItem::Fn(Instance { + def: InstanceKind::Shim(ShimKind::AsyncDropGlue(def, ty)), + args: _, + }) => { symbols.push(( ExportedSymbol::AsyncDropGlue(def, ty), SymbolExportInfo { @@ -578,7 +586,7 @@ pub(crate) fn symbol_name_for_instance_in_crate<'tcx>( rustc_symbol_mangling::symbol_name_for_instance_in_crate( tcx, ty::Instance { - def: ty::InstanceKind::ThreadLocalShim(def_id), + def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(def_id)), args: ty::GenericArgs::empty(), }, instantiating_crate, diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index d4932adeda1f9..8d8b950a125ea 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -618,7 +618,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let ty = self.monomorphize(ty); let drop_fn = Instance::resolve_drop_glue(bx.tcx(), ty); - if let ty::InstanceKind::DropGlue(_, None) = drop_fn.def { + if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) = drop_fn.def { // we don't actually need to drop anything. return helper.funclet_br(self, bx, target, mergeable_succ, &[]); } @@ -934,7 +934,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { match instance.def { // We don't need AsyncDropGlueCtorShim here because it is not `noop func`, // it is `func returning noop future` - ty::InstanceKind::DropGlue(_, None) => { + ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) => { // Empty drop glue; a no-op. let target = target.unwrap(); return helper.funclet_br(self, bx, target, mergeable_succ, &[]); diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index deb8ca12b059d..c1ee7c02e874e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -665,7 +665,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let static_ = if !def_id.is_local() && bx.cx().tcx().needs_thread_local_shim(def_id) { let instance = ty::Instance { - def: ty::InstanceKind::ThreadLocalShim(def_id), + def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(def_id)), args: ty::GenericArgs::empty(), }; let fn_ptr = bx.get_fn_addr(instance); diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index 85da687d8af37..0236b49e497e4 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -428,7 +428,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Determine whether this is a non-capturing closure. That's relevant as their first // argument can be skipped (and that's the only kind of argument skipping we allow). let is_non_capturing_closure = - (matches!(instance.def, ty::InstanceKind::ClosureOnceShim { .. }) + (matches!(instance.def, ty::InstanceKind::Shim(ty::ShimKind::ClosureOnceShim { .. })) || self.tcx.is_closure_like(def_id)) && { let arg = &callee_fn_abi.args[0]; @@ -652,18 +652,18 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { interp_ok(()) } } - ty::InstanceKind::VTableShim(..) - | ty::InstanceKind::ReifyShim(..) - | ty::InstanceKind::ClosureOnceShim { .. } - | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } - | ty::InstanceKind::FnPtrShim(..) - | ty::InstanceKind::DropGlue(..) - | ty::InstanceKind::CloneShim(..) - | ty::InstanceKind::FnPtrAddrShim(..) - | ty::InstanceKind::ThreadLocalShim(..) - | ty::InstanceKind::AsyncDropGlueCtorShim(..) - | ty::InstanceKind::AsyncDropGlue(..) - | ty::InstanceKind::FutureDropPollShim(..) + ty::InstanceKind::Shim(ty::ShimKind::VTableShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnceShim { .. }) + | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { .. }) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(..)) + | ty::InstanceKind::Shim(ty::ShimKind::CloneShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddrShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(..)) | ty::InstanceKind::Item(_) => { // We need MIR for this fn. // Note that this can be an intrinsic, if we are executing its fallback body. diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index b865cafa38647..1aeaaee3a251c 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -607,7 +607,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { enter_trace_span!(M, resolve::resolve_drop_glue, ty = ?place.layout.ty); Instance::resolve_drop_glue(*self.tcx, place.layout.ty) }; - if let ty::InstanceKind::DropGlue(_, None) = instance.def { + if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) = instance.def { // This is the branch we enter if and only if the dropped type has no drop glue // whatsoever. This can happen as a result of monomorphizing a drop of a // generic. In order to make sure that generic and non-generic code behaves diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index 9b78c31871fd7..eefb346d174b4 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -8,7 +8,7 @@ use rustc_span::Symbol; use rustc_target::spec::SanitizerSet; use crate::mono::Visibility; -use crate::ty::{InstanceKind, TyCtxt}; +use crate::ty::{InstanceKind, ShimKind, TyCtxt}; impl<'tcx> TyCtxt<'tcx> { pub fn codegen_instance_attrs( @@ -33,7 +33,7 @@ impl<'tcx> TyCtxt<'tcx> { // // A `ClosureOnceShim` with the track_caller attribute does not have a symbol, // and therefore can be skipped here. - if let InstanceKind::ReifyShim(_, _) = instance_kind + if let InstanceKind::Shim(ShimKind::ReifyShim(_, _)) = instance_kind && attrs.flags.contains(CodegenFnAttrFlags::TRACK_CALLER) { if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) { @@ -54,8 +54,11 @@ impl<'tcx> TyCtxt<'tcx> { } // Ensure closure shims have the optimization properties of their closure applied to them. - if let InstanceKind::ClosureOnceShim { call_once: _, closure, track_caller: _ } = - instance_kind + if let InstanceKind::Shim(ShimKind::ClosureOnceShim { + call_once: _, + closure, + track_caller: _, + }) = instance_kind { let closure_attrs = self.codegen_fn_attrs(closure); attrs.to_mut().optimize = closure_attrs.optimize; diff --git a/compiler/rustc_middle/src/middle/exported_symbols.rs b/compiler/rustc_middle/src/middle/exported_symbols.rs index fb770076f0a26..5942f9dfa1def 100644 --- a/compiler/rustc_middle/src/middle/exported_symbols.rs +++ b/compiler/rustc_middle/src/middle/exported_symbols.rs @@ -75,7 +75,7 @@ impl<'tcx> ExportedSymbol<'tcx> { tcx.symbol_name(ty::Instance::resolve_async_drop_in_place_poll(tcx, def_id, ty)) } ExportedSymbol::ThreadLocalShim(def_id) => tcx.symbol_name(ty::Instance { - def: ty::InstanceKind::ThreadLocalShim(def_id), + def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(def_id)), args: ty::GenericArgs::empty(), }), ExportedSymbol::NoDefId(symbol_name) => symbol_name, diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index c12e72d1dce0f..23e6fc15c2ede 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -32,8 +32,8 @@ use crate::mir::interpret::{AllocRange, Scalar}; use crate::ty::codec::{TyDecoder, TyEncoder}; use crate::ty::print::{FmtPrinter, Printer, pretty_print_const, with_no_trimmed_paths}; use crate::ty::{ - self, GenericArg, GenericArgsRef, Instance, InstanceKind, List, Ty, TyCtxt, TypeVisitableExt, - TypingEnv, UserTypeAnnotationIndex, + self, GenericArg, GenericArgsRef, Instance, InstanceKind, List, ShimKind, Ty, TyCtxt, + TypeVisitableExt, TypingEnv, UserTypeAnnotationIndex, }; mod basic_blocks; @@ -131,6 +131,10 @@ impl<'tcx> MirSource<'tcx> { MirSource { instance, promoted: None } } + pub fn from_shim(shim: ShimKind<'tcx>) -> Self { + MirSource { instance: InstanceKind::Shim(shim), promoted: None } + } + #[inline] pub fn def_id(&self) -> DefId { self.instance.def_id() diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 942c36f343343..1c7d261dd5978 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -218,7 +218,7 @@ impl<'a, 'tcx> MirDumper<'a, 'tcx> { // All drop shims have the same DefId, so we have to add the type // to get unique file names. let shim_disambiguator = match source.instance { - ty::InstanceKind::DropGlue(_, Some(ty)) => { + ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, Some(ty))) => { // Unfortunately, pretty-printed types are not very filename-friendly. // We do some filtering. let mut s = ".".to_owned(); @@ -229,7 +229,7 @@ impl<'a, 'tcx> MirDumper<'a, 'tcx> { })); s } - ty::InstanceKind::AsyncDropGlueCtorShim(_, ty) => { + ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(_, ty)) => { let mut s = ".".to_owned(); s.extend(ty.to_string().chars().filter_map(|c| match c { ' ' => None, @@ -238,7 +238,7 @@ impl<'a, 'tcx> MirDumper<'a, 'tcx> { })); s } - ty::InstanceKind::AsyncDropGlue(_, ty) => { + ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(_, ty)) => { let ty::Coroutine(_, args) = ty.kind() else { bug!(); }; @@ -251,7 +251,7 @@ impl<'a, 'tcx> MirDumper<'a, 'tcx> { })); s } - ty::InstanceKind::FutureDropPollShim(_, proxy_cor, impl_cor) => { + ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(_, proxy_cor, impl_cor)) => { let mut s = ".".to_owned(); s.extend(proxy_cor.to_string().chars().filter_map(|c| match c { ' ' => None, diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index fb89e9ac884a0..35c47b761c5d4 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -347,27 +347,27 @@ macro_rules! make_mir_visitor { ty::InstanceKind::Item(_def_id) => {} ty::InstanceKind::Intrinsic(_def_id) - | ty::InstanceKind::VTableShim(_def_id) - | ty::InstanceKind::ReifyShim(_def_id, _) + | ty::InstanceKind::Shim(ty::ShimKind::VTableShim(_def_id)) + | ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(_def_id, _)) | ty::InstanceKind::Virtual(_def_id, _) - | ty::InstanceKind::ThreadLocalShim(_def_id) - | ty::InstanceKind::ClosureOnceShim { call_once: _def_id, closure: _, track_caller: _ } - | ty::InstanceKind::ConstructCoroutineInClosureShim { + | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(_def_id)) + | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnceShim { call_once: _def_id, closure: _, track_caller: _ }) + | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { coroutine_closure_def_id: _def_id, receiver_by_ref: _, - } - | ty::InstanceKind::DropGlue(_def_id, None) => {} - - ty::InstanceKind::FnPtrShim(_def_id, ty) - | ty::InstanceKind::DropGlue(_def_id, Some(ty)) - | ty::InstanceKind::CloneShim(_def_id, ty) - | ty::InstanceKind::FnPtrAddrShim(_def_id, ty) - | ty::InstanceKind::AsyncDropGlue(_def_id, ty) - | ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, ty) => { + }) + | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_def_id, None)) => {} + + ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim(_def_id, ty)) + | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_def_id, Some(ty))) + | ty::InstanceKind::Shim(ty::ShimKind::CloneShim(_def_id, ty)) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddrShim(_def_id, ty)) + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(_def_id, ty)) + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(_def_id, ty)) => { // FIXME(eddyb) use a better `TyContext` here. self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); } - ty::InstanceKind::FutureDropPollShim(_def_id, proxy_ty, impl_ty) => { + ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(_def_id, proxy_ty, impl_ty)) => { self.visit_ty($(& $mutability)? *proxy_ty, TyContext::Location(location)); self.visit_ty($(& $mutability)? *impl_ty, TyContext::Location(location)); } diff --git a/compiler/rustc_middle/src/mono.rs b/compiler/rustc_middle/src/mono.rs index 2c1a9d1ed7bfb..054b3e9a49680 100644 --- a/compiler/rustc_middle/src/mono.rs +++ b/compiler/rustc_middle/src/mono.rs @@ -22,7 +22,7 @@ use tracing::debug; use crate::dep_graph::dep_node::{make_compile_codegen_unit, make_compile_mono_item}; use crate::dep_graph::{DepNode, WorkProduct, WorkProductId}; use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; -use crate::ty::{self, GenericArgs, Instance, InstanceKind, SymbolName, Ty, TyCtxt}; +use crate::ty::{self, GenericArgs, Instance, InstanceKind, ShimKind, SymbolName, Ty, TyCtxt}; /// Describes how a monomorphization will be instantiated in object files. #[derive(PartialEq)] @@ -173,7 +173,7 @@ impl<'tcx> MonoItem<'tcx> { // incrementality (which wants small CGUs with as many things GloballyShared as possible). // The heuristics implemented here do better than a completely naive approach in the // compiler benchmark suite, but there is no reason to believe they are optimal. - if let InstanceKind::DropGlue(_, Some(ty)) = instance.def { + if let InstanceKind::Shim(ShimKind::DropGlue(_, Some(ty))) = instance.def { if tcx.sess.opts.optimize == OptLevel::No { return InstantiationMode::GloballyShared { may_conflict: false }; } @@ -523,20 +523,20 @@ impl<'tcx> CodegenUnit<'tcx> { match item { MonoItem::Fn(ref instance) => match instance.def { InstanceKind::Item(def) => def.as_local().map(|_| def), - InstanceKind::VTableShim(..) - | InstanceKind::ReifyShim(..) - | InstanceKind::Intrinsic(..) - | InstanceKind::FnPtrShim(..) + InstanceKind::Intrinsic(..) | InstanceKind::Virtual(..) - | InstanceKind::ClosureOnceShim { .. } - | InstanceKind::ConstructCoroutineInClosureShim { .. } - | InstanceKind::DropGlue(..) - | InstanceKind::CloneShim(..) - | InstanceKind::ThreadLocalShim(..) - | InstanceKind::FnPtrAddrShim(..) - | InstanceKind::AsyncDropGlue(..) - | InstanceKind::FutureDropPollShim(..) - | InstanceKind::AsyncDropGlueCtorShim(..) => None, + | InstanceKind::Shim(ShimKind::VTableShim(..)) + | InstanceKind::Shim(ShimKind::ReifyShim(..)) + | InstanceKind::Shim(ShimKind::FnPtrShim(..)) + | InstanceKind::Shim(ShimKind::ClosureOnceShim { .. }) + | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosureShim { .. }) + | InstanceKind::Shim(ShimKind::DropGlue(..)) + | InstanceKind::Shim(ShimKind::CloneShim(..)) + | InstanceKind::Shim(ShimKind::ThreadLocalShim(..)) + | InstanceKind::Shim(ShimKind::FnPtrAddrShim(..)) + | InstanceKind::Shim(ShimKind::AsyncDropGlue(..)) + | InstanceKind::Shim(ShimKind::FutureDropPollShim(..)) + | InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(..)) => None, }, MonoItem::Static(def_id) => def_id.as_local().map(|_| def_id), MonoItem::GlobalAsm(item_id) => Some(item_id.owner_id.def_id.to_def_id()), diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index d4817888468fa..9370890c399ec 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -1400,10 +1400,10 @@ rustc_queries! { } /// Generates a MIR body for the shim. - query mir_shims(key: ty::InstanceKind<'tcx>) -> &'tcx mir::Body<'tcx> { + query mir_shims(key: ty::ShimKind<'tcx>) -> &'tcx mir::Body<'tcx> { arena_cache desc { - "generating MIR shim for `{}`, instance={:?}", + "generating MIR shim for `{}`, kind={:?}", tcx.def_path_str(key.def_id()), key } diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index 346a26a685317..bbb92ee7e716b 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -63,6 +63,12 @@ impl QueryKey for () { } } +impl<'tcx> QueryKey for ty::ShimKind<'tcx> { + fn default_span(&self, tcx: TyCtxt<'_>) -> Span { + tcx.def_span(self.def_id()) + } +} + impl<'tcx> QueryKey for ty::InstanceKind<'tcx> { fn default_span(&self, tcx: TyCtxt<'_>) -> Span { tcx.def_span(self.def_id()) diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 8734d2cde8152..2fc2a4a23c88c 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -75,6 +75,22 @@ pub enum InstanceKind<'tcx> { /// caller. Intrinsic(DefId), + /// Dynamic dispatch to `::fn`. + /// + /// This `InstanceKind` may have a callable MIR as the default implementation. + /// Calls to `Virtual` instances must be codegen'd as virtual calls through the vtable. + /// *This means we might not know exactly what is being called.* + /// + /// If this is reified to a `fn` pointer, a `ReifyShim` is used (see `ReifyShim` above for more + /// details on that). + Virtual(DefId, usize), + + Shim(ShimKind<'tcx>), +} + +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +#[derive(TyEncodable, TyDecodable, StableHash, TypeFoldable, TypeVisitable, Lift)] +pub enum ShimKind<'tcx> { /// `::method` where `method` receives unsizeable `self: Self` (part of the /// `unsized_fn_params` feature). /// @@ -106,16 +122,6 @@ pub enum InstanceKind<'tcx> { /// `DefId` is `FnTrait::call_*`. FnPtrShim(DefId, Ty<'tcx>), - /// Dynamic dispatch to `::fn`. - /// - /// This `InstanceKind` may have a callable MIR as the default implementation. - /// Calls to `Virtual` instances must be codegen'd as virtual calls through the vtable. - /// *This means we might not know exactly what is being called.* - /// - /// If this is reified to a `fn` pointer, a `ReifyShim` is used (see `ReifyShim` above for more - /// details on that). - Virtual(DefId, usize), - /// `<[FnMut/Fn closure] as FnOnce>::call_once`. /// /// The `DefId` is the ID of the `call_once` method in `FnOnce`. @@ -228,10 +234,12 @@ impl<'tcx> Instance<'tcx> { InstanceKind::Item(def) => tcx .upstream_monomorphizations_for(def) .and_then(|monos| monos.get(&self.args).cloned()), - InstanceKind::DropGlue(_, Some(_)) => tcx.upstream_drop_glue_for(self.args), - InstanceKind::AsyncDropGlue(_, _) => None, - InstanceKind::FutureDropPollShim(_, _, _) => None, - InstanceKind::AsyncDropGlueCtorShim(_, _) => { + InstanceKind::Shim(ShimKind::DropGlue(_, Some(_))) => { + tcx.upstream_drop_glue_for(self.args) + } + InstanceKind::Shim(ShimKind::AsyncDropGlue(_, _)) => None, + InstanceKind::Shim(ShimKind::FutureDropPollShim(_, _, _)) => None, + InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(_, _)) => { tcx.upstream_async_drop_glue_for(self.args) } _ => None, @@ -244,45 +252,18 @@ impl<'tcx> InstanceKind<'tcx> { pub fn def_id(self) -> DefId { match self { InstanceKind::Item(def_id) - | InstanceKind::VTableShim(def_id) - | InstanceKind::ReifyShim(def_id, _) - | InstanceKind::FnPtrShim(def_id, _) | InstanceKind::Virtual(def_id, _) - | InstanceKind::Intrinsic(def_id) - | InstanceKind::ThreadLocalShim(def_id) - | InstanceKind::ClosureOnceShim { call_once: def_id, closure: _, track_caller: _ } - | ty::InstanceKind::ConstructCoroutineInClosureShim { - coroutine_closure_def_id: def_id, - receiver_by_ref: _, - } - | InstanceKind::DropGlue(def_id, _) - | InstanceKind::CloneShim(def_id, _) - | InstanceKind::FnPtrAddrShim(def_id, _) - | InstanceKind::FutureDropPollShim(def_id, _, _) - | InstanceKind::AsyncDropGlue(def_id, _) - | InstanceKind::AsyncDropGlueCtorShim(def_id, _) => def_id, + | InstanceKind::Intrinsic(def_id) => def_id, + InstanceKind::Shim(shim) => shim.def_id(), } } /// Returns the `DefId` of instances which might not require codegen locally. pub fn def_id_if_not_guaranteed_local_codegen(self) -> Option { match self { - ty::InstanceKind::Item(def) => Some(def), - ty::InstanceKind::DropGlue(def_id, Some(_)) - | InstanceKind::AsyncDropGlueCtorShim(def_id, _) - | InstanceKind::AsyncDropGlue(def_id, _) - | InstanceKind::FutureDropPollShim(def_id, ..) - | InstanceKind::ThreadLocalShim(def_id) => Some(def_id), - InstanceKind::VTableShim(..) - | InstanceKind::ReifyShim(..) - | InstanceKind::FnPtrShim(..) - | InstanceKind::Virtual(..) - | InstanceKind::Intrinsic(..) - | InstanceKind::ClosureOnceShim { .. } - | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } - | InstanceKind::DropGlue(..) - | InstanceKind::CloneShim(..) - | InstanceKind::FnPtrAddrShim(..) => None, + InstanceKind::Item(def) => Some(def), + InstanceKind::Virtual(..) | InstanceKind::Intrinsic(..) => None, + InstanceKind::Shim(shim) => shim.def_id_if_not_guaranteed_local_codegen(), } } @@ -293,31 +274,28 @@ impl<'tcx> InstanceKind<'tcx> { /// `generates_cgu_internal_copy` for more information. pub fn requires_inline(&self, tcx: TyCtxt<'tcx>) -> bool { use rustc_hir::definitions::DefPathData; - let def_id = match *self { - ty::InstanceKind::Item(def) => def, - ty::InstanceKind::DropGlue(_, Some(ty)) => return ty.is_array(), - ty::InstanceKind::AsyncDropGlueCtorShim(_, ty) => return ty.is_coroutine(), - ty::InstanceKind::FutureDropPollShim(_, _, _) => return false, - ty::InstanceKind::AsyncDropGlue(_, _) => return false, - ty::InstanceKind::ThreadLocalShim(_) => return false, - _ => return true, - }; - matches!( - tcx.def_key(def_id).disambiguated_data.data, - DefPathData::Ctor | DefPathData::Closure - ) + match *self { + InstanceKind::Item(def_id) => matches!( + tcx.def_key(def_id).disambiguated_data.data, + DefPathData::Ctor | DefPathData::Closure + ), + InstanceKind::Shim(shim) => shim.requires_inline(), + InstanceKind::Virtual(..) | InstanceKind::Intrinsic(..) => true, + } } pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool { match *self { InstanceKind::Item(def_id) | InstanceKind::Virtual(def_id, _) - | InstanceKind::VTableShim(def_id) => { + | InstanceKind::Shim(ShimKind::VTableShim(def_id)) => { tcx.body_codegen_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER) } - InstanceKind::ClosureOnceShim { call_once: _, closure: _, track_caller } => { - track_caller - } + InstanceKind::Shim(ShimKind::ClosureOnceShim { + call_once: _, + closure: _, + track_caller, + }) => track_caller, _ => false, } } @@ -330,22 +308,79 @@ impl<'tcx> InstanceKind<'tcx> { /// body should perform necessary instantiations. pub fn has_polymorphic_mir_body(&self) -> bool { match *self { - InstanceKind::CloneShim(..) - | InstanceKind::ThreadLocalShim(..) - | InstanceKind::FnPtrAddrShim(..) - | InstanceKind::FnPtrShim(..) - | InstanceKind::DropGlue(_, Some(_)) - | InstanceKind::FutureDropPollShim(..) - | InstanceKind::AsyncDropGlue(_, _) => false, - InstanceKind::AsyncDropGlueCtorShim(_, _) => false, - InstanceKind::ClosureOnceShim { .. } - | InstanceKind::ConstructCoroutineInClosureShim { .. } - | InstanceKind::DropGlue(..) - | InstanceKind::Item(_) - | InstanceKind::Intrinsic(..) - | InstanceKind::ReifyShim(..) - | InstanceKind::Virtual(..) - | InstanceKind::VTableShim(..) => true, + InstanceKind::Item(_) | InstanceKind::Intrinsic(..) | InstanceKind::Virtual(..) => true, + InstanceKind::Shim(shim) => shim.has_polymorphic_mir_body(), + } + } +} + +impl<'tcx> ShimKind<'tcx> { + #[inline] + pub fn def_id(self) -> DefId { + match self { + ShimKind::VTableShim(def_id) + | ShimKind::ReifyShim(def_id, _) + | ShimKind::FnPtrShim(def_id, _) + | ShimKind::ThreadLocalShim(def_id) + | ShimKind::ClosureOnceShim { call_once: def_id, closure: _, track_caller: _ } + | ShimKind::ConstructCoroutineInClosureShim { + coroutine_closure_def_id: def_id, + receiver_by_ref: _, + } + | ShimKind::DropGlue(def_id, _) + | ShimKind::CloneShim(def_id, _) + | ShimKind::FnPtrAddrShim(def_id, _) + | ShimKind::FutureDropPollShim(def_id, _, _) + | ShimKind::AsyncDropGlue(def_id, _) + | ShimKind::AsyncDropGlueCtorShim(def_id, _) => def_id, + } + } + + /// Returns the `DefId` of instances which might not require codegen locally. + pub fn def_id_if_not_guaranteed_local_codegen(self) -> Option { + match self { + ShimKind::DropGlue(def_id, Some(_)) + | ShimKind::AsyncDropGlueCtorShim(def_id, _) + | ShimKind::AsyncDropGlue(def_id, _) + | ShimKind::FutureDropPollShim(def_id, ..) + | ShimKind::ThreadLocalShim(def_id) => Some(def_id), + ShimKind::VTableShim(..) + | ShimKind::ReifyShim(..) + | ShimKind::FnPtrShim(..) + | ShimKind::ClosureOnceShim { .. } + | ShimKind::ConstructCoroutineInClosureShim { .. } + | ShimKind::DropGlue(..) + | ShimKind::CloneShim(..) + | ShimKind::FnPtrAddrShim(..) => None, + } + } + + pub fn requires_inline(&self) -> bool { + match self { + ShimKind::DropGlue(_, Some(ty)) => ty.is_array(), + ShimKind::AsyncDropGlueCtorShim(_, ty) => ty.is_coroutine(), + ShimKind::FutureDropPollShim(_, _, _) => false, + ShimKind::AsyncDropGlue(_, _) => false, + ShimKind::ThreadLocalShim(_) => false, + _ => true, + } + } + + pub fn has_polymorphic_mir_body(&self) -> bool { + match *self { + ShimKind::CloneShim(..) + | ShimKind::ThreadLocalShim(..) + | ShimKind::FnPtrAddrShim(..) + | ShimKind::FnPtrShim(..) + | ShimKind::DropGlue(_, Some(_)) + | ShimKind::FutureDropPollShim(..) + | ShimKind::AsyncDropGlue(_, _) => false, + ShimKind::AsyncDropGlueCtorShim(_, _) => false, + ShimKind::ClosureOnceShim { .. } + | ShimKind::ConstructCoroutineInClosureShim { .. } + | ShimKind::DropGlue(..) + | ShimKind::ReifyShim(..) + | ShimKind::VTableShim(..) => true, } } } @@ -416,7 +451,11 @@ fn resolve_async_drop_poll<'tcx>(mut cor_ty: Ty<'tcx>) -> Instance<'tcx> { continue; } else { return Instance { - def: ty::InstanceKind::FutureDropPollShim(poll_def_id, first_cor, cor_ty), + def: ty::InstanceKind::Shim(ShimKind::FutureDropPollShim( + poll_def_id, + first_cor, + cor_ty, + )), args: proxy_args, }; } @@ -426,12 +465,16 @@ fn resolve_async_drop_poll<'tcx>(mut cor_ty: Ty<'tcx>) -> Instance<'tcx> { }; if first_cor != cor_ty { return Instance { - def: ty::InstanceKind::FutureDropPollShim(poll_def_id, first_cor, cor_ty), + def: ty::InstanceKind::Shim(ShimKind::FutureDropPollShim( + poll_def_id, + first_cor, + cor_ty, + )), args: proxy_args, }; } else { return Instance { - def: ty::InstanceKind::AsyncDropGlue(poll_def_id, cor_ty), + def: ty::InstanceKind::Shim(ShimKind::AsyncDropGlue(poll_def_id, cor_ty)), args: child_args, }; } @@ -599,11 +642,11 @@ impl<'tcx> Instance<'tcx> { match resolved.def { InstanceKind::Item(def) if resolved.def.requires_caller_location(tcx) => { debug!(" => fn pointer created for function with #[track_caller]"); - resolved.def = InstanceKind::ReifyShim(def, reason); + resolved.def = InstanceKind::Shim(ShimKind::ReifyShim(def, reason)); } InstanceKind::Virtual(def_id, _) => { debug!(" => fn pointer created for virtual call"); - resolved.def = InstanceKind::ReifyShim(def_id, reason); + resolved.def = InstanceKind::Shim(ShimKind::ReifyShim(def_id, reason)); } _ if tcx.sess.is_sanitizer_kcfi_enabled() => { // Reify `::call`-like method implementations @@ -611,7 +654,10 @@ impl<'tcx> Instance<'tcx> { // Reroute through a reify via the *unresolved* instance. The resolved one can't // be directly reified because it's closure-like. The reify can handle the // unresolved instance. - resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args } + resolved = Instance { + def: InstanceKind::Shim(ShimKind::ReifyShim(def_id, reason)), + args, + } // Reify `Trait::method` implementations if the trait is dyn-compatible. } else if let Some(assoc) = tcx.opt_associated_item(def_id) && let AssocContainer::Trait | AssocContainer::TraitImpl(Ok(_)) = @@ -620,7 +666,8 @@ impl<'tcx> Instance<'tcx> { { // If this function could also go in a vtable, we need to `ReifyShim` it with // KCFI because it can only attach one type per function. - resolved.def = InstanceKind::ReifyShim(resolved.def_id(), reason) + resolved.def = + InstanceKind::Shim(ShimKind::ReifyShim(resolved.def_id(), reason)) } } _ => {} @@ -645,7 +692,7 @@ impl<'tcx> Instance<'tcx> { if is_vtable_shim { debug!(" => associated item with unsizeable self: Self"); - return Instance { def: InstanceKind::VTableShim(def_id), args }; + return Instance { def: InstanceKind::Shim(ShimKind::VTableShim(def_id)), args }; } let mut resolved = Instance::expect_resolve(tcx, typing_env, def_id, args, span); @@ -688,19 +735,22 @@ impl<'tcx> Instance<'tcx> { // Create a shim for the `FnOnce/FnMut/Fn` method we are calling // - unlike functions, invoking a closure always goes through a // trait. - resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args }; + resolved = Instance { + def: InstanceKind::Shim(ShimKind::ReifyShim(def_id, reason)), + args, + }; } else { debug!( " => vtable fn pointer created for function with #[track_caller]: {:?}", def ); - resolved.def = InstanceKind::ReifyShim(def, reason); + resolved.def = InstanceKind::Shim(ShimKind::ReifyShim(def, reason)); } } } InstanceKind::Virtual(def_id, _) => { debug!(" => vtable fn pointer created for virtual call"); - resolved.def = InstanceKind::ReifyShim(def_id, reason) + resolved.def = InstanceKind::Shim(ShimKind::ReifyShim(def_id, reason)) } _ => {} } @@ -770,8 +820,11 @@ impl<'tcx> Instance<'tcx> { .def_id; let track_caller = tcx.codegen_fn_attrs(closure_did).flags.contains(CodegenFnAttrFlags::TRACK_CALLER); - let def = - ty::InstanceKind::ClosureOnceShim { call_once, closure: closure_did, track_caller }; + let def = ty::InstanceKind::Shim(ShimKind::ClosureOnceShim { + call_once, + closure: closure_did, + track_caller, + }); let self_ty = Ty::new_closure(tcx, closure_did, args); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 10a5f380d4c80..8e51007edfdfe 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -85,7 +85,7 @@ pub use self::context::{ CtxtInterners, CurrentGcx, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt, TyCtxtFeed, tls, }; pub use self::fold::*; -pub use self::instance::{Instance, InstanceKind, ReifyReason}; +pub use self::instance::{Instance, InstanceKind, ReifyReason, ShimKind}; pub(crate) use self::list::RawList; pub use self::list::{List, ListWithCachedTypeInfo}; pub use self::opaque_types::OpaqueTypeKey; @@ -1802,20 +1802,9 @@ impl<'tcx> TyCtxt<'tcx> { _ => self.optimized_mir(def), } } - ty::InstanceKind::VTableShim(..) - | ty::InstanceKind::ReifyShim(..) - | ty::InstanceKind::Intrinsic(..) - | ty::InstanceKind::FnPtrShim(..) - | ty::InstanceKind::Virtual(..) - | ty::InstanceKind::ClosureOnceShim { .. } - | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } - | ty::InstanceKind::FutureDropPollShim(..) - | ty::InstanceKind::DropGlue(..) - | ty::InstanceKind::CloneShim(..) - | ty::InstanceKind::ThreadLocalShim(..) - | ty::InstanceKind::FnPtrAddrShim(..) - | ty::InstanceKind::AsyncDropGlueCtorShim(..) - | ty::InstanceKind::AsyncDropGlue(..) => self.mir_shims(instance), + ty::InstanceKind::Intrinsic(..) => bug!("intrinsics have no instance MIR"), + ty::InstanceKind::Virtual(..) => bug!("virtual dispatches have no instance MIR"), + ty::InstanceKind::Shim(shim) => self.mir_shims(shim), }; assert!( @@ -1941,7 +1930,7 @@ impl<'tcx> TyCtxt<'tcx> { if args[0].has_placeholders() || args[0].has_non_region_param() { return Err(self.layout_error(LayoutError::TooGeneric(ty()))); } - let instance = InstanceKind::AsyncDropGlue(def_id, Ty::new_coroutine(self, def_id, args)); + let instance = ShimKind::AsyncDropGlue(def_id, Ty::new_coroutine(self, def_id, args)); self.mir_shims(instance) .coroutine_layout_raw() .ok_or_else(|| self.layout_error(LayoutError::Unknown(ty()))) diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index 29875a3530c15..0552bf1dd1636 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -367,35 +367,44 @@ impl<'tcx, P: Printer<'tcx> + std::fmt::Write> Print

for ty::Instance<'tcx> { cx.print_def_path(self.def_id(), self.args)?; match self.def { ty::InstanceKind::Item(_) => {} - ty::InstanceKind::VTableShim(_) => cx.write_str(" - shim(vtable)")?, - ty::InstanceKind::ReifyShim(_, None) => cx.write_str(" - shim(reify)")?, - ty::InstanceKind::ReifyShim(_, Some(ty::ReifyReason::FnPtr)) => { - cx.write_str(" - shim(reify-fnptr)")? - } - ty::InstanceKind::ReifyShim(_, Some(ty::ReifyReason::Vtable)) => { - cx.write_str(" - shim(reify-vtable)")? - } - ty::InstanceKind::ThreadLocalShim(_) => cx.write_str(" - shim(tls)")?, ty::InstanceKind::Intrinsic(_) => cx.write_str(" - intrinsic")?, ty::InstanceKind::Virtual(_, num) => cx.write_str(&format!(" - virtual#{num}"))?, - ty::InstanceKind::FnPtrShim(_, ty) => cx.write_str(&format!(" - shim({ty})"))?, - ty::InstanceKind::ClosureOnceShim { .. } => cx.write_str(" - shim")?, - ty::InstanceKind::ConstructCoroutineInClosureShim { .. } => cx.write_str(" - shim")?, - ty::InstanceKind::DropGlue(_, None) => cx.write_str(" - shim(None)")?, - ty::InstanceKind::DropGlue(_, Some(ty)) => { - cx.write_str(&format!(" - shim(Some({ty}))"))? + ty::InstanceKind::Shim(shim) => { + cx.write_str(" - ")?; + shim.print(cx)?; } - ty::InstanceKind::CloneShim(_, ty) => cx.write_str(&format!(" - shim({ty})"))?, - ty::InstanceKind::FnPtrAddrShim(_, ty) => cx.write_str(&format!(" - shim({ty})"))?, - ty::InstanceKind::FutureDropPollShim(_, proxy_ty, impl_ty) => { - cx.write_str(&format!(" - dropshim({proxy_ty}-{impl_ty})"))? + } + Ok(()) + } +} + +impl<'tcx, P: Printer<'tcx> + std::fmt::Write> Print

for ty::ShimKind<'tcx> { + fn print(&self, cx: &mut P) -> Result<(), PrintError> { + match self { + ty::ShimKind::VTableShim(_) => cx.write_str("shim(vtable)"), + ty::ShimKind::ReifyShim(_, None) => cx.write_str("shim(reify)"), + ty::ShimKind::ReifyShim(_, Some(ty::ReifyReason::FnPtr)) => { + cx.write_str("shim(reify-fnptr)") } - ty::InstanceKind::AsyncDropGlue(_, ty) => cx.write_str(&format!(" - shim({ty})"))?, - ty::InstanceKind::AsyncDropGlueCtorShim(_, ty) => { - cx.write_str(&format!(" - shim(Some({ty}))"))? + ty::ShimKind::ReifyShim(_, Some(ty::ReifyReason::Vtable)) => { + cx.write_str("shim(reify-vtable)") } - }; - Ok(()) + ty::ShimKind::ThreadLocalShim(_) => cx.write_str("shim(tls)"), + ty::ShimKind::FnPtrShim(_, ty) => cx.write_str(&format!("shim({ty})")), + ty::ShimKind::ClosureOnceShim { .. } => cx.write_str("shim"), + ty::ShimKind::ConstructCoroutineInClosureShim { .. } => cx.write_str("shim"), + ty::ShimKind::DropGlue(_, None) => cx.write_str("shim(None)"), + ty::ShimKind::DropGlue(_, Some(ty)) => cx.write_str(&format!("shim(Some({ty}))")), + ty::ShimKind::CloneShim(_, ty) => cx.write_str(&format!("shim({ty})")), + ty::ShimKind::FnPtrAddrShim(_, ty) => cx.write_str(&format!("shim({ty})")), + ty::ShimKind::FutureDropPollShim(_, proxy_ty, impl_ty) => { + cx.write_str(&format!("dropshim({proxy_ty}-{impl_ty})")) + } + ty::ShimKind::AsyncDropGlue(_, ty) => cx.write_str(&format!("shim({ty})")), + ty::ShimKind::AsyncDropGlueCtorShim(_, ty) => { + cx.write_str(&format!("shim(Some({ty}))")) + } + } } } diff --git a/compiler/rustc_mir_transform/src/coroutine/drop.rs b/compiler/rustc_mir_transform/src/coroutine/drop.rs index 5be6887e937a1..41b973476af94 100644 --- a/compiler/rustc_mir_transform/src/coroutine/drop.rs +++ b/compiler/rustc_mir_transform/src/coroutine/drop.rs @@ -206,7 +206,7 @@ pub(super) fn create_coroutine_drop_shim<'tcx>( // Update the body's def to become the drop glue. let coroutine_instance = body.source.instance; let drop_glue = tcx.require_lang_item(LangItem::DropGlue, body.span); - let drop_instance = InstanceKind::DropGlue(drop_glue, Some(coroutine_ty)); + let drop_instance = InstanceKind::Shim(ShimKind::DropGlue(drop_glue, Some(coroutine_ty))); // Temporary change MirSource to coroutine's instance so that dump_mir produces more sensible // filename. diff --git a/compiler/rustc_mir_transform/src/coroutine/mod.rs b/compiler/rustc_mir_transform/src/coroutine/mod.rs index bb57ca1cd90a7..53283680c0966 100644 --- a/compiler/rustc_mir_transform/src/coroutine/mod.rs +++ b/compiler/rustc_mir_transform/src/coroutine/mod.rs @@ -71,7 +71,7 @@ use rustc_index::{Idx, IndexVec, indexvec}; use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::{ - self, CoroutineArgs, CoroutineArgsExt, GenericArgsRef, InstanceKind, Ty, TyCtxt, + self, CoroutineArgs, CoroutineArgsExt, GenericArgsRef, InstanceKind, ShimKind, Ty, TyCtxt, }; use rustc_middle::{bug, span_bug}; use rustc_mir_dataflow::impls::always_storage_live_locals; diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index df71cd48a77fe..a1575a21e9073 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -15,7 +15,7 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::{ - self, Instance, InstanceKind, Ty, TyCtxt, TypeFlags, TypeVisitableExt, Unnormalized, + self, Instance, InstanceKind, ShimKind, Ty, TyCtxt, TypeFlags, TypeVisitableExt, Unnormalized, }; use rustc_session::config::{DebugInfo, OptLevel}; use rustc_span::Spanned; @@ -739,18 +739,21 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>( // the correct param-env for types being dropped. Stall resolving // the MIR for this instance until all of its const params are // substituted. - InstanceKind::DropGlue(_, Some(ty)) if ty.has_type_flags(TypeFlags::HAS_CT_PARAM) => { + InstanceKind::Shim(ShimKind::DropGlue(_, Some(ty))) + if ty.has_type_flags(TypeFlags::HAS_CT_PARAM) => + { debug!("still needs substitution"); return Err("implementation limitation -- HACK for dropping polymorphic type"); } - InstanceKind::AsyncDropGlue(_, ty) | InstanceKind::AsyncDropGlueCtorShim(_, ty) => { + InstanceKind::Shim(ShimKind::AsyncDropGlue(_, ty)) + | InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(_, ty)) => { return if ty.still_further_specializable() { Err("still needs substitution") } else { Ok(()) }; } - InstanceKind::FutureDropPollShim(_, ty, ty2) => { + InstanceKind::Shim(ShimKind::FutureDropPollShim(_, ty, ty2)) => { return if ty.still_further_specializable() || ty2.still_further_specializable() { Err("still needs substitution") } else { @@ -762,15 +765,15 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>( // not get any optimizations run on it. Any subsequent inlining may cause cycles, but we // do not need to catch this here, we can wait until the inliner decides to continue // inlining a second time. - InstanceKind::VTableShim(_) - | InstanceKind::ReifyShim(..) - | InstanceKind::FnPtrShim(..) - | InstanceKind::ClosureOnceShim { .. } - | InstanceKind::ConstructCoroutineInClosureShim { .. } - | InstanceKind::DropGlue(..) - | InstanceKind::CloneShim(..) - | InstanceKind::ThreadLocalShim(..) - | InstanceKind::FnPtrAddrShim(..) => return Ok(()), + InstanceKind::Shim(ShimKind::VTableShim(_)) + | InstanceKind::Shim(ShimKind::ReifyShim(..)) + | InstanceKind::Shim(ShimKind::FnPtrShim(..)) + | InstanceKind::Shim(ShimKind::ClosureOnceShim { .. }) + | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosureShim { .. }) + | InstanceKind::Shim(ShimKind::DropGlue(..)) + | InstanceKind::Shim(ShimKind::CloneShim(..)) + | InstanceKind::Shim(ShimKind::ThreadLocalShim(..)) + | InstanceKind::Shim(ShimKind::FnPtrAddrShim(..)) => return Ok(()), } if inliner.tcx().is_constructor(callee_def_id) { @@ -1370,8 +1373,8 @@ fn try_instance_mir<'tcx>( tcx: TyCtxt<'tcx>, instance: InstanceKind<'tcx>, ) -> Result<&'tcx Body<'tcx>, &'static str> { - if let ty::InstanceKind::DropGlue(_, Some(ty)) | ty::InstanceKind::AsyncDropGlueCtorShim(_, ty) = - instance + if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, Some(ty))) + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(_, ty)) = instance && let ty::Adt(def, args) = ty.kind() { let fields = def.all_fields(); diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 9d031b6548021..0fd1a5f240758 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -4,7 +4,7 @@ use rustc_data_structures::unord::UnordSet; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::limit::Limit; use rustc_middle::mir::TerminatorKind; -use rustc_middle::ty::{self, GenericArgsRef, InstanceKind, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, GenericArgsRef, InstanceKind, ShimKind, TyCtxt, TypeVisitableExt}; use rustc_span::sym; use tracing::{instrument, trace}; @@ -26,24 +26,24 @@ fn should_recurse<'tcx>(tcx: TyCtxt<'tcx>, callee: ty::Instance<'tcx>) -> bool { // These have MIR and if that MIR is inlined, instantiated and then inlining is run // again, a function item can end up getting inlined. Thus we'll be able to cause // a cycle that way - InstanceKind::VTableShim(_) - | InstanceKind::ReifyShim(..) - | InstanceKind::FnPtrShim(..) - | InstanceKind::ClosureOnceShim { .. } - | InstanceKind::ConstructCoroutineInClosureShim { .. } - | InstanceKind::ThreadLocalShim { .. } - | InstanceKind::CloneShim(..) => {} + InstanceKind::Shim(ShimKind::VTableShim(_)) + | InstanceKind::Shim(ShimKind::ReifyShim(..)) + | InstanceKind::Shim(ShimKind::FnPtrShim(..)) + | InstanceKind::Shim(ShimKind::ClosureOnceShim { .. }) + | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosureShim { .. }) + | InstanceKind::Shim(ShimKind::ThreadLocalShim { .. }) + | InstanceKind::Shim(ShimKind::CloneShim(..)) => {} // This shim does not call any other functions, thus there can be no recursion. - InstanceKind::FnPtrAddrShim(..) => return false, + InstanceKind::Shim(ShimKind::FnPtrAddrShim(..)) => return false, // FIXME: A not fully instantiated drop shim can cause ICEs if one attempts to // have its MIR built. Likely oli-obk just screwed up the `ParamEnv`s, so this // needs some more analysis. - InstanceKind::DropGlue(..) - | InstanceKind::FutureDropPollShim(..) - | InstanceKind::AsyncDropGlue(..) - | InstanceKind::AsyncDropGlueCtorShim(..) => { + InstanceKind::Shim(ShimKind::DropGlue(..)) + | InstanceKind::Shim(ShimKind::FutureDropPollShim(..)) + | InstanceKind::Shim(ShimKind::AsyncDropGlue(..)) + | InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(..)) => { if callee.has_param() { return false; } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 6d9b8feea05f4..d6061edb74ce3 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -31,16 +31,15 @@ pub(super) fn provide(providers: &mut Providers) { providers.mir_shims = make_shim; } -fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body<'tcx> { - debug!("make_shim({:?})", instance); +fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, shim: ty::ShimKind<'tcx>) -> Body<'tcx> { + debug!("make_shim({:?})", shim); - let mut result = match instance { - ty::InstanceKind::Item(..) => bug!("item {:?} passed to make_shim", instance), - ty::InstanceKind::VTableShim(def_id) => { + let mut result = match shim { + ty::ShimKind::VTableShim(def_id) => { let adjustment = Adjustment::Deref { source: DerefSource::MutPtr }; - build_call_shim(tcx, instance, Some(adjustment), CallKind::Direct(def_id)) + build_call_shim(tcx, shim, Some(adjustment), CallKind::Direct(def_id)) } - ty::InstanceKind::FnPtrShim(def_id, ty) => { + ty::ShimKind::FnPtrShim(def_id, ty) => { let trait_ = tcx.parent(def_id); // Supports `Fn` or `async Fn` traits. let adjustment = match tcx @@ -53,17 +52,17 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< None => bug!("fn pointer {:?} is not an fn", ty), }; - build_call_shim(tcx, instance, Some(adjustment), CallKind::Indirect(ty)) + build_call_shim(tcx, shim, Some(adjustment), CallKind::Indirect(ty)) } // We are generating a call back to our def-id, which the // codegen backend knows to turn to an actual call, be it // a virtual call, or a direct call to a function for which // indirect calls must be codegen'd differently than direct ones // (such as `#[track_caller]`). - ty::InstanceKind::ReifyShim(def_id, _) => { - build_call_shim(tcx, instance, None, CallKind::Direct(def_id)) + ty::ShimKind::ReifyShim(def_id, _) => { + build_call_shim(tcx, shim, None, CallKind::Direct(def_id)) } - ty::InstanceKind::ClosureOnceShim { call_once: _, closure: _, track_caller: _ } => { + ty::ShimKind::ClosureOnceShim { call_once: _, closure: _, track_caller: _ } => { let fn_mut = tcx.require_lang_item(LangItem::FnMut, DUMMY_SP); let call_mut = tcx .associated_items(fn_mut) @@ -72,15 +71,15 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< .unwrap() .def_id; - build_call_shim(tcx, instance, Some(Adjustment::RefMut), CallKind::Direct(call_mut)) + build_call_shim(tcx, shim, Some(Adjustment::RefMut), CallKind::Direct(call_mut)) } - ty::InstanceKind::ConstructCoroutineInClosureShim { + ty::ShimKind::ConstructCoroutineInClosureShim { coroutine_closure_def_id, receiver_by_ref, } => build_construct_coroutine_by_move_shim(tcx, coroutine_closure_def_id, receiver_by_ref), - ty::InstanceKind::DropGlue(def_id, ty) => { + ty::ShimKind::DropGlue(def_id, ty) => { // FIXME(#91576): Drop shims for coroutines aren't subject to the MIR passes at the end // of this function. Is this intentional? if let Some(&ty::Coroutine(coroutine_def_id, args)) = ty.map(Ty::kind) { @@ -110,7 +109,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< let mut body = EarlyBinder::bind(body.clone()).instantiate(tcx, args).skip_norm_wip(); - debug!("make_shim({:?}) = {:?}", instance, body); + debug!("make_shim({:?}) = {:?}", shim, body); pm::run_passes( tcx, @@ -129,10 +128,10 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< build_drop_shim(tcx, def_id, ty, ty::TypingEnv::post_analysis(tcx, def_id)) } - ty::InstanceKind::ThreadLocalShim(..) => build_thread_local_shim(tcx, instance), - ty::InstanceKind::CloneShim(def_id, ty) => build_clone_shim(tcx, def_id, ty), - ty::InstanceKind::FnPtrAddrShim(def_id, ty) => build_fn_ptr_addr_shim(tcx, def_id, ty), - ty::InstanceKind::FutureDropPollShim(def_id, proxy_ty, impl_ty) => { + ty::ShimKind::ThreadLocalShim(..) => build_thread_local_shim(tcx, shim), + ty::ShimKind::CloneShim(def_id, ty) => build_clone_shim(tcx, def_id, ty), + ty::ShimKind::FnPtrAddrShim(def_id, ty) => build_fn_ptr_addr_shim(tcx, def_id, ty), + ty::ShimKind::FutureDropPollShim(def_id, proxy_ty, impl_ty) => { let mut body = async_destructor_ctor::build_future_drop_poll_shim(tcx, def_id, proxy_ty, impl_ty); @@ -148,10 +147,10 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< pm::Optimizations::Allowed, ); run_optimization_passes(tcx, &mut body); - debug!("make_shim({:?}) = {:?}", instance, body); + debug!("make_shim({:?}) = {:?}", shim, body); return body; } - ty::InstanceKind::AsyncDropGlue(def_id, ty) => { + ty::ShimKind::AsyncDropGlue(def_id, ty) => { let mut body = async_destructor_ctor::build_async_drop_shim(tcx, def_id, ty); // Main pass required here is StateTransform to convert sync drop ladder @@ -170,23 +169,17 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< Some(MirPhase::Runtime(RuntimePhase::PostCleanup)), ); run_optimization_passes(tcx, &mut body); - debug!("make_shim({:?}) = {:?}", instance, body); + debug!("make_shim({:?}) = {:?}", shim, body); return body; } - ty::InstanceKind::AsyncDropGlueCtorShim(def_id, ty) => { + ty::ShimKind::AsyncDropGlueCtorShim(def_id, ty) => { let body = async_destructor_ctor::build_async_destructor_ctor_shim(tcx, def_id, ty); - debug!("make_shim({:?}) = {:?}", instance, body); + debug!("make_shim({:?}) = {:?}", shim, body); return body; } - ty::InstanceKind::Virtual(..) => { - bug!("InstanceKind::Virtual ({:?}) is for direct calls only", instance) - } - ty::InstanceKind::Intrinsic(_) => { - bug!("creating shims from intrinsics ({:?}) is unsupported", instance) - } }; - debug!("make_shim({:?}) = untransformed {:?}", instance, result); + debug!("make_shim({:?}) = untransformed {:?}", shim, result); deref_finder(tcx, &mut result, false); @@ -211,7 +204,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< Some(MirPhase::Runtime(RuntimePhase::Optimized)), ); - debug!("make_shim({:?}) = {:?}", instance, result); + debug!("make_shim({:?}) = {:?}", shim, result); result } @@ -300,7 +293,7 @@ pub fn build_drop_shim<'tcx>( } block(&mut blocks, TerminatorKind::Return); - let source = MirSource::from_instance(ty::InstanceKind::DropGlue(def_id, ty)); + let source = MirSource::from_shim(ty::ShimKind::DropGlue(def_id, ty)); let mut body = new_body(source, blocks, local_decls_for_sig(&sig, span), sig.inputs().len(), span); @@ -480,11 +473,8 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> { } } -fn build_thread_local_shim<'tcx>( - tcx: TyCtxt<'tcx>, - instance: ty::InstanceKind<'tcx>, -) -> Body<'tcx> { - let def_id = instance.def_id(); +fn build_thread_local_shim<'tcx>(tcx: TyCtxt<'tcx>, shim: ty::ShimKind<'tcx>) -> Body<'tcx> { + let def_id = shim.def_id(); let span = tcx.def_span(def_id); let source_info = SourceInfo::outermost(span); @@ -502,7 +492,7 @@ fn build_thread_local_shim<'tcx>( )]); new_body( - MirSource::from_instance(instance), + MirSource::from_shim(shim), blocks, IndexVec::from_raw(vec![LocalDecl::new(tcx.thread_local_ptr_ty(def_id), span)]), 0, @@ -565,7 +555,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { } fn into_mir(self) -> Body<'tcx> { - let source = MirSource::from_instance(ty::InstanceKind::CloneShim( + let source = MirSource::from_shim(ty::ShimKind::CloneShim( self.def_id, self.sig.inputs_and_output[0], )); @@ -776,14 +766,14 @@ impl<'tcx> CloneShimBuilder<'tcx> { #[instrument(level = "debug", skip(tcx), ret)] fn build_call_shim<'tcx>( tcx: TyCtxt<'tcx>, - instance: ty::InstanceKind<'tcx>, + shim: ty::ShimKind<'tcx>, rcvr_adjustment: Option, call_kind: CallKind<'tcx>, ) -> Body<'tcx> { // `FnPtrShim` contains the fn pointer type that a call shim is being built for - this is used // to instantiate into the signature of the shim. It is not necessary for users of this // MIR body to perform further instantiations (see `InstanceKind::has_polymorphic_mir_body`). - let (sig_args, untuple_args) = if let ty::InstanceKind::FnPtrShim(_, ty) = instance { + let (sig_args, untuple_args) = if let ty::ShimKind::FnPtrShim(_, ty) = shim { let sig = tcx.instantiate_bound_regions_with_erased(ty.fn_sig(tcx)); let untuple_args = sig.inputs(); @@ -796,12 +786,12 @@ fn build_call_shim<'tcx>( (None, None) }; - let def_id = instance.def_id(); + let def_id = shim.def_id(); let sig = tcx.fn_sig(def_id); let sig = sig.map_bound(|sig| tcx.instantiate_bound_regions_with_erased(sig)); - assert_eq!(sig_args.is_some(), !instance.has_polymorphic_mir_body()); + assert_eq!(sig_args.is_some(), !shim.has_polymorphic_mir_body()); let mut sig = if let Some(sig_args) = sig_args { sig.instantiate(tcx, &sig_args).skip_norm_wip() } else { @@ -830,14 +820,14 @@ fn build_call_shim<'tcx>( DerefSource::MutRef => Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, fnty), DerefSource::MutPtr => Ty::new_mut_ptr(tcx, fnty), }, - Adjustment::RefMut => bug!("`RefMut` is never used with indirect calls: {instance:?}"), + Adjustment::RefMut => bug!("`RefMut` is never used with indirect calls: {shim:?}"), }; sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); } // FIXME: Avoid having to adjust the signature both here and in // `fn_sig_for_fn_abi`. - if let ty::InstanceKind::VTableShim(..) = instance { + if let ty::ShimKind::VTableShim(..) = shim { // Modify fn(self, ...) to fn(self: *mut Self, ...) let mut inputs_and_output = sig.inputs_and_output.to_vec(); let self_arg = &mut inputs_and_output[0]; @@ -995,7 +985,7 @@ fn build_call_shim<'tcx>( } let mut body = - new_body(MirSource::from_instance(instance), blocks, local_decls, sig.inputs().len(), span); + new_body(MirSource::from_shim(shim), blocks, local_decls, sig.inputs().len(), span); if let ExternAbi::RustCall = sig.abi() { body.spread_arg = Some(Local::new(sig.inputs().len())); @@ -1119,7 +1109,7 @@ fn build_fn_ptr_addr_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'t Some(Terminator { source_info, kind: TerminatorKind::Return, attributes: ThinVec::new() }), false, ); - let source = MirSource::from_instance(ty::InstanceKind::FnPtrAddrShim(def_id, self_ty)); + let source = MirSource::from_shim(ty::ShimKind::FnPtrAddrShim(def_id, self_ty)); new_body(source, IndexVec::from_elem_n(start_block, 1), locals, sig.inputs().len(), span) } @@ -1218,7 +1208,7 @@ fn build_construct_coroutine_by_move_shim<'tcx>( false, ); - let source = MirSource::from_instance(ty::InstanceKind::ConstructCoroutineInClosureShim { + let source = MirSource::from_shim(ty::ShimKind::ConstructCoroutineInClosureShim { coroutine_closure_def_id, receiver_by_ref, }); diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index da88247800372..b23ab7842d51f 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -106,7 +106,7 @@ pub(super) fn build_async_drop_shim<'tcx>( ); block(&mut blocks, TerminatorKind::Return); - let source = MirSource::from_instance(ty::InstanceKind::AsyncDropGlue(def_id, ty)); + let source = MirSource::from_shim(ty::ShimKind::AsyncDropGlue(def_id, ty)); let mut body = new_body(source, blocks, local_decls_for_sig(&sig, span), sig.inputs().len(), span); @@ -175,17 +175,17 @@ pub(super) fn build_future_drop_poll_shim<'tcx>( proxy_ty: Ty<'tcx>, impl_ty: Ty<'tcx>, ) -> Body<'tcx> { - let instance = ty::InstanceKind::FutureDropPollShim(def_id, proxy_ty, impl_ty); + let shim = ty::ShimKind::FutureDropPollShim(def_id, proxy_ty, impl_ty); let ty::Coroutine(coroutine_def_id, _) = impl_ty.kind() else { - bug!("build_future_drop_poll_shim not for coroutine impl type: ({:?})", instance); + bug!("build_future_drop_poll_shim not for coroutine impl type: ({:?})", shim); }; let span = tcx.def_span(def_id); if tcx.is_async_drop_in_place_coroutine(*coroutine_def_id) { - build_adrop_for_adrop_shim(tcx, proxy_ty, impl_ty, span, instance) + build_adrop_for_adrop_shim(tcx, proxy_ty, impl_ty, span, shim) } else { - build_adrop_for_coroutine_shim(tcx, proxy_ty, impl_ty, span, instance) + build_adrop_for_coroutine_shim(tcx, proxy_ty, impl_ty, span, shim) } } @@ -198,16 +198,16 @@ fn build_adrop_for_coroutine_shim<'tcx>( proxy_ty: Ty<'tcx>, impl_ty: Ty<'tcx>, span: Span, - instance: ty::InstanceKind<'tcx>, + shim: ty::ShimKind<'tcx>, ) -> Body<'tcx> { let ty::Coroutine(coroutine_def_id, impl_args) = impl_ty.kind() else { - bug!("build_adrop_for_coroutine_shim not for coroutine impl type: ({:?})", instance); + bug!("build_adrop_for_coroutine_shim not for coroutine impl type: ({:?})", shim); }; let source_info = SourceInfo::outermost(span); let body = tcx.optimized_mir(*coroutine_def_id).future_drop_poll().unwrap(); let mut body: Body<'tcx> = EarlyBinder::bind(body.clone()).instantiate(tcx, impl_args).skip_norm_wip(); - body.source.instance = instance; + body.source.instance = ty::InstanceKind::Shim(shim); body.phase = MirPhase::Runtime(RuntimePhase::Initial); body.var_debug_info.clear(); @@ -291,7 +291,7 @@ fn build_adrop_for_adrop_shim<'tcx>( proxy_ty: Ty<'tcx>, impl_ty: Ty<'tcx>, span: Span, - instance: ty::InstanceKind<'tcx>, + shim: ty::ShimKind<'tcx>, ) -> Body<'tcx> { let source_info = SourceInfo::outermost(span); let proxy_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, proxy_ty); @@ -413,7 +413,7 @@ fn build_adrop_for_adrop_shim<'tcx>( false, )); - let source = MirSource::from_instance(instance); + let source = MirSource::from_shim(shim); let mut body = new_body(source, blocks, locals, sig.inputs().len(), span); body.phase = MirPhase::Runtime(RuntimePhase::Initial); return body; diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 0421edc543151..7c4fce02ff005 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -226,8 +226,8 @@ use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion}; use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::{ - self, GenericArgs, GenericParamDefKind, Instance, InstanceKind, Ty, TyCtxt, TypeFoldable, - TypeVisitable, TypeVisitableExt, TypeVisitor, Unnormalized, VtblEntry, + self, GenericArgs, GenericParamDefKind, Instance, InstanceKind, ShimKind, Ty, TyCtxt, + TypeFoldable, TypeVisitable, TypeVisitableExt, TypeVisitor, Unnormalized, VtblEntry, }; use rustc_middle::util::Providers; use rustc_middle::{bug, span_bug}; @@ -447,7 +447,7 @@ fn collect_items_rec<'tcx>( used_items.push(respan( starting_item.span, MonoItem::Fn(Instance { - def: InstanceKind::ThreadLocalShim(def_id), + def: InstanceKind::Shim(ShimKind::ThreadLocalShim(def_id)), args: GenericArgs::empty(), }), )); @@ -1013,10 +1013,10 @@ fn visit_instance_use<'tcx>( bug!("{:?} being reified", instance); } } - ty::InstanceKind::ThreadLocalShim(..) => { + ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(..)) => { bug!("{:?} being reified", instance); } - ty::InstanceKind::DropGlue(_, None) => { + ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) => { // Don't need to emit noop drop glue if we are calling directly. // // Note that we also optimize away the call to visit_instance_use in vtable construction @@ -1025,18 +1025,18 @@ fn visit_instance_use<'tcx>( output.push(create_fn_mono_item(tcx, instance, source)); } } - ty::InstanceKind::DropGlue(_, Some(_)) - | ty::InstanceKind::FutureDropPollShim(..) - | ty::InstanceKind::AsyncDropGlue(_, _) - | ty::InstanceKind::AsyncDropGlueCtorShim(_, _) - | ty::InstanceKind::VTableShim(..) - | ty::InstanceKind::ReifyShim(..) - | ty::InstanceKind::ClosureOnceShim { .. } - | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } - | ty::InstanceKind::Item(..) - | ty::InstanceKind::FnPtrShim(..) - | ty::InstanceKind::CloneShim(..) - | ty::InstanceKind::FnPtrAddrShim(..) => { + ty::InstanceKind::Item(..) + | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, Some(_))) + | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(_, _)) + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(_, _)) + | ty::InstanceKind::Shim(ty::ShimKind::VTableShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnceShim { .. }) + | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { .. }) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::CloneShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddrShim(..)) => { output.push(create_fn_mono_item(tcx, instance, source)); } } diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index aee7153419883..79b47c8e5944d 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -115,7 +115,7 @@ use rustc_middle::mono::{ MonoItemPartitions, Visibility, }; use rustc_middle::ty::print::{characteristic_def_id_of_type, with_no_trimmed_paths}; -use rustc_middle::ty::{self, InstanceKind, TyCtxt}; +use rustc_middle::ty::{self, InstanceKind, ShimKind, TyCtxt}; use rustc_middle::util::Providers; use rustc_session::CodegenUnits; use rustc_session::config::{DumpMonoStatsFormat, SwitchWithOptPath}; @@ -630,20 +630,22 @@ fn characteristic_def_id_of_mono_item<'tcx>( MonoItem::Fn(instance) => { let def_id = match instance.def { ty::InstanceKind::Item(def) => def, - ty::InstanceKind::VTableShim(..) - | ty::InstanceKind::ReifyShim(..) - | ty::InstanceKind::FnPtrShim(..) - | ty::InstanceKind::ClosureOnceShim { .. } - | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } - | ty::InstanceKind::Intrinsic(..) - | ty::InstanceKind::DropGlue(..) + ty::InstanceKind::Intrinsic(..) | ty::InstanceKind::Virtual(..) - | ty::InstanceKind::CloneShim(..) - | ty::InstanceKind::ThreadLocalShim(..) - | ty::InstanceKind::FnPtrAddrShim(..) - | ty::InstanceKind::FutureDropPollShim(..) - | ty::InstanceKind::AsyncDropGlue(..) - | ty::InstanceKind::AsyncDropGlueCtorShim(..) => return None, + | ty::InstanceKind::Shim(ty::ShimKind::VTableShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnceShim { .. }) + | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { + .. + }) + | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(..)) + | ty::InstanceKind::Shim(ty::ShimKind::CloneShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddrShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(..)) + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(..)) => return None, }; // If this is a method, we want to put it into the same module as @@ -794,27 +796,27 @@ fn mono_item_visibility<'tcx>( let def_id = match instance.def { InstanceKind::Item(def_id) - | InstanceKind::DropGlue(def_id, Some(_)) - | InstanceKind::FutureDropPollShim(def_id, _, _) - | InstanceKind::AsyncDropGlue(def_id, _) - | InstanceKind::AsyncDropGlueCtorShim(def_id, _) => def_id, + | InstanceKind::Shim(ShimKind::DropGlue(def_id, Some(_))) + | InstanceKind::Shim(ShimKind::FutureDropPollShim(def_id, _, _)) + | InstanceKind::Shim(ShimKind::AsyncDropGlue(def_id, _)) + | InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(def_id, _)) => def_id, // We match the visibility of statics here - InstanceKind::ThreadLocalShim(def_id) => { + InstanceKind::Shim(ShimKind::ThreadLocalShim(def_id)) => { return static_visibility(tcx, can_be_internalized, def_id); } // These are all compiler glue and such, never exported, always hidden. - InstanceKind::VTableShim(..) - | InstanceKind::ReifyShim(..) - | InstanceKind::FnPtrShim(..) + InstanceKind::Shim(ShimKind::VTableShim(..)) + | InstanceKind::Shim(ShimKind::ReifyShim(..)) + | InstanceKind::Shim(ShimKind::FnPtrShim(..)) | InstanceKind::Virtual(..) | InstanceKind::Intrinsic(..) - | InstanceKind::ClosureOnceShim { .. } - | InstanceKind::ConstructCoroutineInClosureShim { .. } - | InstanceKind::DropGlue(..) - | InstanceKind::CloneShim(..) - | InstanceKind::FnPtrAddrShim(..) => return Visibility::Hidden, + | InstanceKind::Shim(ShimKind::ClosureOnceShim { .. }) + | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosureShim { .. }) + | InstanceKind::Shim(ShimKind::DropGlue(..)) + | InstanceKind::Shim(ShimKind::CloneShim(..)) + | InstanceKind::Shim(ShimKind::FnPtrAddrShim(..)) => return Visibility::Hidden, }; // Both the `start_fn` lang item and `main` itself should not be exported, @@ -1331,8 +1333,8 @@ pub(crate) fn provide(providers: &mut Providers) { // "Normal" functions size estimate: the number of // statements, plus one for the terminator. InstanceKind::Item(..) - | InstanceKind::DropGlue(..) - | InstanceKind::AsyncDropGlueCtorShim(..) => { + | InstanceKind::Shim(ShimKind::DropGlue(..)) + | InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(..)) => { let mir = tcx.instance_mir(instance.def); mir.basic_blocks .iter() diff --git a/compiler/rustc_public/src/unstable/convert/stable/ty.rs b/compiler/rustc_public/src/unstable/convert/stable/ty.rs index 4218c21f508d3..5807d79c8e03c 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/ty.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/ty.rs @@ -990,18 +990,7 @@ impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> { ty::InstanceKind::Virtual(_def_id, idx) => { crate::mir::mono::InstanceKind::Virtual { idx } } - ty::InstanceKind::VTableShim(..) - | ty::InstanceKind::ReifyShim(..) - | ty::InstanceKind::FnPtrAddrShim(..) - | ty::InstanceKind::ClosureOnceShim { .. } - | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } - | ty::InstanceKind::ThreadLocalShim(..) - | ty::InstanceKind::DropGlue(..) - | ty::InstanceKind::CloneShim(..) - | ty::InstanceKind::FnPtrShim(..) - | ty::InstanceKind::FutureDropPollShim(..) - | ty::InstanceKind::AsyncDropGlue(..) - | ty::InstanceKind::AsyncDropGlueCtorShim(..) => crate::mir::mono::InstanceKind::Shim, + ty::InstanceKind::Shim(..) => crate::mir::mono::InstanceKind::Shim, }; crate::mir::mono::Instance { def, kind } } diff --git a/compiler/rustc_public_bridge/src/context/impls.rs b/compiler/rustc_public_bridge/src/context/impls.rs index c309df59e9eca..87a8661edeb65 100644 --- a/compiler/rustc_public_bridge/src/context/impls.rs +++ b/compiler/rustc_public_bridge/src/context/impls.rs @@ -645,7 +645,7 @@ impl<'tcx, B: Bridge> CompilerCtxt<'tcx, B> { /// Check if this is an empty DropGlue shim. pub fn is_empty_drop_shim(&self, instance: ty::Instance<'tcx>) -> bool { - matches!(instance.def, ty::InstanceKind::DropGlue(_, None)) + matches!(instance.def, ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None))) } /// Convert a non-generic crate item into an instance. 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 0810e327b63e3..6284754016aec 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 @@ -310,7 +310,7 @@ pub(crate) fn transform_instance<'tcx>( // FIXME: account for async-drop-glue if (matches!(instance.def, ty::InstanceKind::Virtual(..)) && tcx.is_lang_item(instance.def_id(), LangItem::DropGlue)) - || matches!(instance.def, ty::InstanceKind::DropGlue(..)) + || matches!(instance.def, ty::InstanceKind::Shim(ty::ShimKind::DropGlue(..))) { // Adjust the type ids of DropGlues // @@ -364,7 +364,7 @@ pub(crate) fn transform_instance<'tcx>( tcx.types.unit }; instance.args = tcx.mk_args_trait(self_ty, instance.args.into_iter().skip(1)); - } else if let ty::InstanceKind::VTableShim(def_id) = instance.def + } else if let ty::InstanceKind::Shim(ty::ShimKind::VTableShim(def_id)) = instance.def && let Some(trait_id) = tcx.trait_of_assoc(def_id) { // Adjust the type ids of VTableShims to the type id expected in the call sites for the @@ -461,7 +461,8 @@ pub(crate) fn transform_instance<'tcx>( fn default_or_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Option { match instance.def { - ty::InstanceKind::Item(def_id) | ty::InstanceKind::FnPtrShim(def_id, _) => { + ty::InstanceKind::Item(def_id) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim(def_id, _)) => { tcx.opt_associated_item(def_id).map(|item| item.def_id) } _ => None, diff --git a/compiler/rustc_sanitizers/src/kcfi/typeid/mod.rs b/compiler/rustc_sanitizers/src/kcfi/typeid/mod.rs index 3243e23fcf981..7df5ec9088a9c 100644 --- a/compiler/rustc_sanitizers/src/kcfi/typeid/mod.rs +++ b/compiler/rustc_sanitizers/src/kcfi/typeid/mod.rs @@ -6,7 +6,7 @@ use std::hash::Hasher; -use rustc_middle::ty::{Instance, InstanceKind, ReifyReason, Ty, TyCtxt}; +use rustc_middle::ty::{Instance, InstanceKind, ReifyReason, ShimKind, Ty, TyCtxt}; use rustc_target::callconv::FnAbi; use twox_hash::XxHash64; @@ -46,7 +46,8 @@ pub fn typeid_for_instance<'tcx>( // // This was implemented for KCFI support in #123106 and #123052 (which introduced the // ReifyReason). The tracking issue for KCFI support for Rust is #123479. - if matches!(instance.def, InstanceKind::ReifyShim(_, Some(ReifyReason::FnPtr))) { + if matches!(instance.def, InstanceKind::Shim(ShimKind::ReifyShim(_, Some(ReifyReason::FnPtr)))) + { options.insert(TypeIdOptions::USE_CONCRETE_SELF); } // A KCFI type metadata identifier is a 32-bit constant produced by taking the lower half of the diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index c13300a735c3c..d67b603b73a68 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -62,13 +62,13 @@ pub(super) fn mangle<'tcx>( let mut p = LegacySymbolMangler { tcx, path: SymbolPath::new(), keep_within_component: false }; p.print_def_path( def_id, - if let ty::InstanceKind::DropGlue(_, _) - | ty::InstanceKind::AsyncDropGlueCtorShim(_, _) - | ty::InstanceKind::FutureDropPollShim(_, _, _) = instance.def + if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, _)) + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(_, _)) + | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(_, _, _)) = instance.def { // Add the name of the dropped type to the symbol name &*instance.args - } else if let ty::InstanceKind::AsyncDropGlue(_, ty) = instance.def { + } else if let ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(_, ty)) = instance.def { let ty::Coroutine(_, cor_args) = ty.kind() else { bug!(); }; @@ -81,13 +81,13 @@ pub(super) fn mangle<'tcx>( .unwrap(); match instance.def { - ty::InstanceKind::ThreadLocalShim(..) => { + ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(..)) => { p.write_str("{{tls-shim}}").unwrap(); } - ty::InstanceKind::VTableShim(..) => { + ty::InstanceKind::Shim(ty::ShimKind::VTableShim(..)) => { p.write_str("{{vtable-shim}}").unwrap(); } - ty::InstanceKind::ReifyShim(_, reason) => { + ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(_, reason)) => { p.write_str("{{reify-shim").unwrap(); match reason { Some(ReifyReason::FnPtr) => p.write_str("-fnptr").unwrap(), @@ -98,14 +98,17 @@ pub(super) fn mangle<'tcx>( } // FIXME(async_closures): This shouldn't be needed when we fix // `Instance::ty`/`Instance::def_id`. - ty::InstanceKind::ConstructCoroutineInClosureShim { receiver_by_ref, .. } => { + ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { + receiver_by_ref, + .. + }) => { p.write_str(if receiver_by_ref { "{{by-move-shim}}" } else { "{{by-ref-shim}}" }) .unwrap(); } _ => {} } - if let ty::InstanceKind::FutureDropPollShim(..) = instance.def { + if let ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(..)) = instance.def { let _ = p.write_str("{{drop-shim}}"); } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index c6624a7820559..b2f5ea1873807 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -49,25 +49,31 @@ pub(super) fn mangle<'tcx>( // Append `::{shim:...#0}` to shims that can coexist with a non-shim instance. let shim_kind = match instance.def { - ty::InstanceKind::ThreadLocalShim(_) => Some("tls"), - ty::InstanceKind::VTableShim(_) => Some("vtable"), - ty::InstanceKind::ReifyShim(_, None) => Some("reify"), - ty::InstanceKind::ReifyShim(_, Some(ReifyReason::FnPtr)) => Some("reify_fnptr"), - ty::InstanceKind::ReifyShim(_, Some(ReifyReason::Vtable)) => Some("reify_vtable"), + ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(_)) => Some("tls"), + ty::InstanceKind::Shim(ty::ShimKind::VTableShim(_)) => Some("vtable"), + ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(_, None)) => Some("reify"), + ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(_, Some(ReifyReason::FnPtr))) => { + Some("reify_fnptr") + } + ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(_, Some(ReifyReason::Vtable))) => { + Some("reify_vtable") + } // FIXME(async_closures): This shouldn't be needed when we fix // `Instance::ty`/`Instance::def_id`. - ty::InstanceKind::ConstructCoroutineInClosureShim { receiver_by_ref: true, .. } => { - Some("by_move") - } - ty::InstanceKind::ConstructCoroutineInClosureShim { receiver_by_ref: false, .. } => { - Some("by_ref") - } - ty::InstanceKind::FutureDropPollShim(_, _, _) => Some("drop"), + ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { + receiver_by_ref: true, + .. + }) => Some("by_move"), + ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { + receiver_by_ref: false, + .. + }) => Some("by_ref"), + ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(_, _, _)) => Some("drop"), _ => None, }; - if let ty::InstanceKind::AsyncDropGlue(_, ty) = instance.def { + if let ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(_, ty)) = instance.def { let ty::Coroutine(_, cor_args) = ty.kind() else { bug!(); }; diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index e782557d126bf..d26750f255198 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -10,7 +10,7 @@ use rustc_middle::query::Providers; use rustc_middle::ty::layout::{ FnAbiError, HasTyCtxt, HasTypingEnv, LayoutCx, LayoutOf, TyAndLayout, fn_can_unwind, }; -use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt, Unnormalized}; +use rustc_middle::ty::{self, InstanceKind, ShimKind, Ty, TyCtxt, Unnormalized}; use rustc_span::DUMMY_SP; use rustc_span::def_id::DefId; use rustc_target::callconv::{ @@ -38,7 +38,7 @@ fn fn_sig_for_fn_abi<'tcx>( instance: ty::Instance<'tcx>, typing_env: ty::TypingEnv<'tcx>, ) -> ty::FnSig<'tcx> { - if let InstanceKind::ThreadLocalShim(..) = instance.def { + if let InstanceKind::Shim(ShimKind::ThreadLocalShim(..)) = instance.def { return tcx.mk_fn_sig_safe_rust_abi([], tcx.thread_local_ptr_ty(instance.def_id())); } @@ -50,7 +50,7 @@ fn fn_sig_for_fn_abi<'tcx>( ); // Modify `fn(self, ...)` to `fn(self: *mut Self, ...)`. - if let ty::InstanceKind::VTableShim(..) = instance.def { + if let ty::InstanceKind::Shim(ty::ShimKind::VTableShim(..)) = instance.def { let mut inputs_and_output = sig.inputs_and_output.to_vec(); inputs_and_output[0] = Ty::new_mut_ptr(tcx, inputs_and_output[0]); sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); @@ -82,22 +82,23 @@ fn fn_sig_for_fn_abi<'tcx>( // a separate def-id for these bodies. let mut coroutine_kind = args.as_coroutine_closure().kind(); - let env_ty = - if let InstanceKind::ConstructCoroutineInClosureShim { receiver_by_ref, .. } = - instance.def - { - coroutine_kind = ty::ClosureKind::FnOnce; - - // Implementations of `FnMut` and `Fn` for coroutine-closures - // still take their receiver by ref. - if receiver_by_ref { - Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, coroutine_ty) - } else { - coroutine_ty - } + let env_ty = if let InstanceKind::Shim(ShimKind::ConstructCoroutineInClosureShim { + receiver_by_ref, + .. + }) = instance.def + { + coroutine_kind = ty::ClosureKind::FnOnce; + + // Implementations of `FnMut` and `Fn` for coroutine-closures + // still take their receiver by ref. + if receiver_by_ref { + Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, coroutine_ty) } else { - tcx.closure_env_ty(coroutine_ty, coroutine_kind, tcx.lifetimes.re_erased) - }; + coroutine_ty + } + } else { + tcx.closure_env_ty(coroutine_ty, coroutine_kind, tcx.lifetimes.re_erased) + }; let sig = tcx.instantiate_bound_regions_with_erased(sig); @@ -264,7 +265,8 @@ impl<'tcx> FnAbiDesc<'tcx> { ) -> Self { let ty::PseudoCanonicalInput { typing_env, value: (instance, extra_args) } = query; let is_virtual_call = matches!(instance.def, ty::InstanceKind::Virtual(..)); - let is_tls_shim_call = matches!(instance.def, ty::InstanceKind::ThreadLocalShim(_)); + let is_tls_shim_call = + matches!(instance.def, ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(_))); Self { layout_cx: LayoutCx::new(tcx, typing_env), sig: tcx.normalize_erasing_regions( diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 7386afbe53771..25edafce89f13 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -38,16 +38,16 @@ fn resolve_instance_raw<'tcx>( } else if tcx.is_lang_item(def_id, LangItem::DropGlue) { let ty = args.type_at(0); - if ty.needs_drop(tcx, typing_env) { + let shim = if ty.needs_drop(tcx, typing_env) { debug!(" => nontrivial drop glue"); match *ty.kind() { ty::Coroutine(coroutine_def_id, ..) => { // FIXME: sync drop of coroutine with async drop (generate both versions?) // Currently just ignored if tcx.optimized_mir(coroutine_def_id).coroutine_drop_async().is_some() { - ty::InstanceKind::DropGlue(def_id, None) + ty::ShimKind::DropGlue(def_id, None) } else { - ty::InstanceKind::DropGlue(def_id, Some(ty)) + ty::ShimKind::DropGlue(def_id, Some(ty)) } } ty::Closure(..) @@ -57,14 +57,15 @@ fn resolve_instance_raw<'tcx>( | ty::Dynamic(..) | ty::Array(..) | ty::Slice(..) - | ty::UnsafeBinder(..) => ty::InstanceKind::DropGlue(def_id, Some(ty)), + | ty::UnsafeBinder(..) => ty::ShimKind::DropGlue(def_id, Some(ty)), // Drop shims can only be built from ADTs. _ => return Ok(None), } } else { debug!(" => trivial drop glue"); - ty::InstanceKind::DropGlue(def_id, None) - } + ty::ShimKind::DropGlue(def_id, None) + }; + ty::InstanceKind::Shim(shim) } else if tcx.is_lang_item(def_id, LangItem::AsyncDropInPlace) { let ty = args.type_at(0); @@ -82,14 +83,14 @@ fn resolve_instance_raw<'tcx>( _ => return Ok(None), } debug!(" => nontrivial async drop glue ctor"); - ty::InstanceKind::AsyncDropGlueCtorShim(def_id, ty) + ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(def_id, ty)) } else { debug!(" => trivial async drop glue ctor"); - ty::InstanceKind::AsyncDropGlueCtorShim(def_id, ty) + ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(def_id, ty)) } } else if tcx.is_async_drop_in_place_coroutine(def_id) { let ty = args.type_at(0); - ty::InstanceKind::AsyncDropGlue(def_id, ty) + ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(def_id, ty)) } else { debug!(" => free item"); ty::InstanceKind::Item(def_id) @@ -279,7 +280,10 @@ fn resolve_associated_item<'tcx>( }; Some(Instance { - def: ty::InstanceKind::CloneShim(trait_item_id, self_ty), + def: ty::InstanceKind::Shim(ty::ShimKind::CloneShim( + trait_item_id, + self_ty, + )), args: rcvr_args, }) } else { @@ -296,7 +300,10 @@ fn resolve_associated_item<'tcx>( return Ok(None); } Some(Instance { - def: ty::InstanceKind::FnPtrAddrShim(trait_item_id, self_ty), + def: ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddrShim( + trait_item_id, + self_ty, + )), args: rcvr_args, }) } else { @@ -326,7 +333,10 @@ fn resolve_associated_item<'tcx>( Some(Instance::resolve_closure(tcx, closure_def_id, args, target_kind)) } ty::FnDef(..) | ty::FnPtr(..) => Some(Instance { - def: ty::InstanceKind::FnPtrShim(trait_item_id, rcvr_args.type_at(0)), + def: ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim( + trait_item_id, + rcvr_args.type_at(0), + )), args: rcvr_args, }), ty::CoroutineClosure(coroutine_closure_def_id, args) => { @@ -339,10 +349,12 @@ fn resolve_associated_item<'tcx>( Some(Instance::new_raw(coroutine_closure_def_id, args)) } else { Some(Instance { - def: ty::InstanceKind::ConstructCoroutineInClosureShim { - coroutine_closure_def_id, - receiver_by_ref: target_kind != ty::ClosureKind::FnOnce, - }, + def: ty::InstanceKind::Shim( + ty::ShimKind::ConstructCoroutineInClosureShim { + coroutine_closure_def_id, + receiver_by_ref: target_kind != ty::ClosureKind::FnOnce, + }, + ), args, }) } @@ -362,10 +374,12 @@ fn resolve_associated_item<'tcx>( // If we're computing `AsyncFnOnce` for a by-ref closure then // construct a new body that has the right return types. Some(Instance { - def: ty::InstanceKind::ConstructCoroutineInClosureShim { - coroutine_closure_def_id, - receiver_by_ref: false, - }, + def: ty::InstanceKind::Shim( + ty::ShimKind::ConstructCoroutineInClosureShim { + coroutine_closure_def_id, + receiver_by_ref: false, + }, + ), args, }) } else { @@ -376,7 +390,10 @@ fn resolve_associated_item<'tcx>( Some(Instance::resolve_closure(tcx, closure_def_id, args, target_kind)) } ty::FnDef(..) | ty::FnPtr(..) => Some(Instance { - def: ty::InstanceKind::FnPtrShim(trait_item_id, rcvr_args.type_at(0)), + def: ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim( + trait_item_id, + rcvr_args.type_at(0), + )), args: rcvr_args, }), _ => bug!( From c329a0e6c966eda4b696f104a2a839841af9a5a4 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Thu, 18 Jun 2026 22:39:32 +0000 Subject: [PATCH 30/42] Strip vestigial `Shim` suffix from `ShimKind` variants --- .../rustc_codegen_cranelift/src/constant.rs | 2 +- .../src/back/symbol_export.rs | 4 +- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 2 +- .../rustc_const_eval/src/interpret/call.rs | 22 ++-- .../src/middle/codegen_fn_attrs.rs | 4 +- .../src/middle/exported_symbols.rs | 2 +- compiler/rustc_middle/src/mir/pretty.rs | 4 +- compiler/rustc_middle/src/mir/visit.rs | 20 +-- compiler/rustc_middle/src/mono.rs | 20 +-- compiler/rustc_middle/src/ty/instance.rs | 116 +++++++++--------- compiler/rustc_middle/src/ty/print/mod.rs | 26 ++-- compiler/rustc_mir_transform/src/inline.rs | 22 ++-- .../rustc_mir_transform/src/inline/cycle.rs | 20 +-- compiler/rustc_mir_transform/src/shim.rs | 39 +++--- .../src/shim/async_destructor_ctor.rs | 2 +- compiler/rustc_monomorphize/src/collector.rs | 22 ++-- .../rustc_monomorphize/src/partitioning.rs | 44 ++++--- .../cfi/typeid/itanium_cxx_abi/transform.rs | 5 +- .../rustc_sanitizers/src/kcfi/typeid/mod.rs | 3 +- compiler/rustc_symbol_mangling/src/legacy.rs | 14 +-- compiler/rustc_symbol_mangling/src/v0.rs | 16 +-- compiler/rustc_ty_utils/src/abi.rs | 8 +- compiler/rustc_ty_utils/src/instance.rs | 19 ++- 23 files changed, 212 insertions(+), 224 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index a83bfd1cbad42..829e7d0dfb59c 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -53,7 +53,7 @@ pub(crate) fn codegen_tls_ref<'tcx>( ) -> CValue<'tcx> { let tls_ptr = if !def_id.is_local() && fx.tcx.needs_thread_local_shim(def_id) { let instance = ty::Instance { - def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(def_id)), + def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(def_id)), args: ty::GenericArgs::empty(), }; let func_ref = fx.get_function_ref(instance); diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 40d5c3b07059f..dfc8c8be5c03f 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -361,7 +361,7 @@ fn exported_generic_symbols_provider_local<'tcx>( } } MonoItem::Fn(Instance { - def: InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(_, ty)), + def: InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(_, ty)), args, }) => { // A little sanity-check @@ -586,7 +586,7 @@ pub(crate) fn symbol_name_for_instance_in_crate<'tcx>( rustc_symbol_mangling::symbol_name_for_instance_in_crate( tcx, ty::Instance { - def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(def_id)), + def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(def_id)), args: ty::GenericArgs::empty(), }, instantiating_crate, diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index c1ee7c02e874e..5dc4617717c11 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -665,7 +665,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let static_ = if !def_id.is_local() && bx.cx().tcx().needs_thread_local_shim(def_id) { let instance = ty::Instance { - def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(def_id)), + def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(def_id)), args: ty::GenericArgs::empty(), }; let fn_ptr = bx.get_fn_addr(instance); diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index 0236b49e497e4..44420b7148478 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -428,7 +428,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Determine whether this is a non-capturing closure. That's relevant as their first // argument can be skipped (and that's the only kind of argument skipping we allow). let is_non_capturing_closure = - (matches!(instance.def, ty::InstanceKind::Shim(ty::ShimKind::ClosureOnceShim { .. })) + (matches!(instance.def, ty::InstanceKind::Shim(ty::ShimKind::ClosureOnce { .. })) || self.tcx.is_closure_like(def_id)) && { let arg = &callee_fn_abi.args[0]; @@ -652,18 +652,18 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { interp_ok(()) } } - ty::InstanceKind::Shim(ty::ShimKind::VTableShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnceShim { .. }) - | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { .. }) - | ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim(..)) + ty::InstanceKind::Shim(ty::ShimKind::VTable(..)) + | ty::InstanceKind::Shim(ty::ShimKind::Reify(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnce { .. }) + | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosure { .. }) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtr(..)) | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(..)) - | ty::InstanceKind::Shim(ty::ShimKind::CloneShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddrShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::Clone(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddr(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(..)) + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(..)) | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(..)) - | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(..)) | ty::InstanceKind::Item(_) => { // We need MIR for this fn. // Note that this can be an intrinsic, if we are executing its fallback body. diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index eefb346d174b4..713c6597c1966 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -33,7 +33,7 @@ impl<'tcx> TyCtxt<'tcx> { // // A `ClosureOnceShim` with the track_caller attribute does not have a symbol, // and therefore can be skipped here. - if let InstanceKind::Shim(ShimKind::ReifyShim(_, _)) = instance_kind + if let InstanceKind::Shim(ShimKind::Reify(_, _)) = instance_kind && attrs.flags.contains(CodegenFnAttrFlags::TRACK_CALLER) { if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) { @@ -54,7 +54,7 @@ impl<'tcx> TyCtxt<'tcx> { } // Ensure closure shims have the optimization properties of their closure applied to them. - if let InstanceKind::Shim(ShimKind::ClosureOnceShim { + if let InstanceKind::Shim(ShimKind::ClosureOnce { call_once: _, closure, track_caller: _, diff --git a/compiler/rustc_middle/src/middle/exported_symbols.rs b/compiler/rustc_middle/src/middle/exported_symbols.rs index 5942f9dfa1def..e23ad3c832ef7 100644 --- a/compiler/rustc_middle/src/middle/exported_symbols.rs +++ b/compiler/rustc_middle/src/middle/exported_symbols.rs @@ -75,7 +75,7 @@ impl<'tcx> ExportedSymbol<'tcx> { tcx.symbol_name(ty::Instance::resolve_async_drop_in_place_poll(tcx, def_id, ty)) } ExportedSymbol::ThreadLocalShim(def_id) => tcx.symbol_name(ty::Instance { - def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(def_id)), + def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(def_id)), args: ty::GenericArgs::empty(), }), ExportedSymbol::NoDefId(symbol_name) => symbol_name, diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 1c7d261dd5978..beab1b1a08e1a 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -229,7 +229,7 @@ impl<'a, 'tcx> MirDumper<'a, 'tcx> { })); s } - ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(_, ty)) => { + ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(_, ty)) => { let mut s = ".".to_owned(); s.extend(ty.to_string().chars().filter_map(|c| match c { ' ' => None, @@ -251,7 +251,7 @@ impl<'a, 'tcx> MirDumper<'a, 'tcx> { })); s } - ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(_, proxy_cor, impl_cor)) => { + ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(_, proxy_cor, impl_cor)) => { let mut s = ".".to_owned(); s.extend(proxy_cor.to_string().chars().filter_map(|c| match c { ' ' => None, diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 35c47b761c5d4..921c54b2828c2 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -347,27 +347,27 @@ macro_rules! make_mir_visitor { ty::InstanceKind::Item(_def_id) => {} ty::InstanceKind::Intrinsic(_def_id) - | ty::InstanceKind::Shim(ty::ShimKind::VTableShim(_def_id)) - | ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(_def_id, _)) + | ty::InstanceKind::Shim(ty::ShimKind::VTable(_def_id)) + | ty::InstanceKind::Shim(ty::ShimKind::Reify(_def_id, _)) | ty::InstanceKind::Virtual(_def_id, _) - | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(_def_id)) - | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnceShim { call_once: _def_id, closure: _, track_caller: _ }) - | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { + | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(_def_id)) + | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnce { call_once: _def_id, closure: _, track_caller: _ }) + | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosure { coroutine_closure_def_id: _def_id, receiver_by_ref: _, }) | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_def_id, None)) => {} - ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim(_def_id, ty)) + ty::InstanceKind::Shim(ty::ShimKind::FnPtr(_def_id, ty)) | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_def_id, Some(ty))) - | ty::InstanceKind::Shim(ty::ShimKind::CloneShim(_def_id, ty)) - | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddrShim(_def_id, ty)) + | ty::InstanceKind::Shim(ty::ShimKind::Clone(_def_id, ty)) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddr(_def_id, ty)) | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(_def_id, ty)) - | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(_def_id, ty)) => { + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(_def_id, ty)) => { // FIXME(eddyb) use a better `TyContext` here. self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); } - ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(_def_id, proxy_ty, impl_ty)) => { + ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(_def_id, proxy_ty, impl_ty)) => { self.visit_ty($(& $mutability)? *proxy_ty, TyContext::Location(location)); self.visit_ty($(& $mutability)? *impl_ty, TyContext::Location(location)); } diff --git a/compiler/rustc_middle/src/mono.rs b/compiler/rustc_middle/src/mono.rs index 054b3e9a49680..6df67257a2ea7 100644 --- a/compiler/rustc_middle/src/mono.rs +++ b/compiler/rustc_middle/src/mono.rs @@ -525,18 +525,18 @@ impl<'tcx> CodegenUnit<'tcx> { InstanceKind::Item(def) => def.as_local().map(|_| def), InstanceKind::Intrinsic(..) | InstanceKind::Virtual(..) - | InstanceKind::Shim(ShimKind::VTableShim(..)) - | InstanceKind::Shim(ShimKind::ReifyShim(..)) - | InstanceKind::Shim(ShimKind::FnPtrShim(..)) - | InstanceKind::Shim(ShimKind::ClosureOnceShim { .. }) - | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosureShim { .. }) + | InstanceKind::Shim(ShimKind::VTable(..)) + | InstanceKind::Shim(ShimKind::Reify(..)) + | InstanceKind::Shim(ShimKind::FnPtr(..)) + | InstanceKind::Shim(ShimKind::ClosureOnce { .. }) + | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosure { .. }) | InstanceKind::Shim(ShimKind::DropGlue(..)) - | InstanceKind::Shim(ShimKind::CloneShim(..)) - | InstanceKind::Shim(ShimKind::ThreadLocalShim(..)) - | InstanceKind::Shim(ShimKind::FnPtrAddrShim(..)) + | InstanceKind::Shim(ShimKind::Clone(..)) + | InstanceKind::Shim(ShimKind::ThreadLocal(..)) + | InstanceKind::Shim(ShimKind::FnPtrAddr(..)) | InstanceKind::Shim(ShimKind::AsyncDropGlue(..)) - | InstanceKind::Shim(ShimKind::FutureDropPollShim(..)) - | InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(..)) => None, + | InstanceKind::Shim(ShimKind::FutureDropPoll(..)) + | InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(..)) => None, }, MonoItem::Static(def_id) => def_id.as_local().map(|_| def_id), MonoItem::GlobalAsm(item_id) => Some(item_id.owner_id.def_id.to_def_id()), diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 2fc2a4a23c88c..30c299aa82b1a 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -96,7 +96,7 @@ pub enum ShimKind<'tcx> { /// /// The generated shim will take `Self` via `*mut Self` - conceptually this is `&owned Self` - /// and dereference the argument to call the original function. - VTableShim(DefId), + VTable(DefId), /// `fn()` pointer where the function itself cannot be turned into a pointer. /// @@ -115,12 +115,12 @@ pub enum ShimKind<'tcx> { /// /// This field will only be populated if we are compiling in a mode that needs these shims /// to be separable, currently only when KCFI is enabled. - ReifyShim(DefId, Option), + Reify(DefId, Option), /// `::call_*` (generated `FnTrait` implementation for `fn()` pointers). /// /// `DefId` is `FnTrait::call_*`. - FnPtrShim(DefId, Ty<'tcx>), + FnPtr(DefId, Ty<'tcx>), /// `<[FnMut/Fn closure] as FnOnce>::call_once`. /// @@ -128,14 +128,14 @@ pub enum ShimKind<'tcx> { /// /// This generates a body that will just borrow the (owned) self type, /// and dispatch to the `FnMut::call_mut` instance for the closure. - ClosureOnceShim { call_once: DefId, closure: DefId, track_caller: bool }, + ClosureOnce { call_once: DefId, closure: DefId, track_caller: bool }, /// `<[FnMut/Fn coroutine-closure] as FnOnce>::call_once` /// /// The body generated here differs significantly from the `ClosureOnceShim`, /// since we need to generate a distinct coroutine type that will move the /// closure's upvars *out* of the closure. - ConstructCoroutineInClosureShim { + ConstructCoroutineInClosure { coroutine_closure_def_id: DefId, // Whether the generated MIR body takes the coroutine by-ref. This is // because the signature of `<{async fn} as FnMut>::call_mut` is: @@ -148,10 +148,10 @@ pub enum ShimKind<'tcx> { /// Compiler-generated accessor for thread locals which returns a reference to the thread local /// the `DefId` defines. This is used to export thread locals from dylibs on platforms lacking /// native support. - ThreadLocalShim(DefId), + ThreadLocal(DefId), /// Proxy shim for async drop of future (def_id, proxy_cor_ty, impl_cor_ty) - FutureDropPollShim(DefId, Ty<'tcx>, Ty<'tcx>), + FutureDropPoll(DefId, Ty<'tcx>, Ty<'tcx>), /// `core::ptr::drop_glue::`. /// @@ -168,20 +168,20 @@ pub enum ShimKind<'tcx> { /// Additionally, arrays, tuples, and closures get a `Clone` shim even if they aren't `Copy`. /// /// The `DefId` is for `Clone::clone`, the `Ty` is the type `T` with the builtin `Clone` impl. - CloneShim(DefId, Ty<'tcx>), + Clone(DefId, Ty<'tcx>), /// Compiler-generated `::addr` implementation. /// /// Automatically generated for all potentially higher-ranked `fn(I) -> R` types. /// /// The `DefId` is for `FnPtr::addr`, the `Ty` is the type `T`. - FnPtrAddrShim(DefId, Ty<'tcx>), + FnPtrAddr(DefId, Ty<'tcx>), /// `core::future::async_drop::async_drop_in_place::<'_, T>`. /// /// The `DefId` is for `core::future::async_drop::async_drop_in_place`, the `Ty` /// is the type `T`. - AsyncDropGlueCtorShim(DefId, Ty<'tcx>), + AsyncDropGlueCtor(DefId, Ty<'tcx>), /// `core::future::async_drop::async_drop_in_place::<'_, T>::{closure}`. /// @@ -238,8 +238,8 @@ impl<'tcx> Instance<'tcx> { tcx.upstream_drop_glue_for(self.args) } InstanceKind::Shim(ShimKind::AsyncDropGlue(_, _)) => None, - InstanceKind::Shim(ShimKind::FutureDropPollShim(_, _, _)) => None, - InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(_, _)) => { + InstanceKind::Shim(ShimKind::FutureDropPoll(_, _, _)) => None, + InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(_, _)) => { tcx.upstream_async_drop_glue_for(self.args) } _ => None, @@ -288,10 +288,10 @@ impl<'tcx> InstanceKind<'tcx> { match *self { InstanceKind::Item(def_id) | InstanceKind::Virtual(def_id, _) - | InstanceKind::Shim(ShimKind::VTableShim(def_id)) => { + | InstanceKind::Shim(ShimKind::VTable(def_id)) => { tcx.body_codegen_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER) } - InstanceKind::Shim(ShimKind::ClosureOnceShim { + InstanceKind::Shim(ShimKind::ClosureOnce { call_once: _, closure: _, track_caller, @@ -318,21 +318,21 @@ impl<'tcx> ShimKind<'tcx> { #[inline] pub fn def_id(self) -> DefId { match self { - ShimKind::VTableShim(def_id) - | ShimKind::ReifyShim(def_id, _) - | ShimKind::FnPtrShim(def_id, _) - | ShimKind::ThreadLocalShim(def_id) - | ShimKind::ClosureOnceShim { call_once: def_id, closure: _, track_caller: _ } - | ShimKind::ConstructCoroutineInClosureShim { + ShimKind::VTable(def_id) + | ShimKind::Reify(def_id, _) + | ShimKind::FnPtr(def_id, _) + | ShimKind::ThreadLocal(def_id) + | ShimKind::ClosureOnce { call_once: def_id, closure: _, track_caller: _ } + | ShimKind::ConstructCoroutineInClosure { coroutine_closure_def_id: def_id, receiver_by_ref: _, } | ShimKind::DropGlue(def_id, _) - | ShimKind::CloneShim(def_id, _) - | ShimKind::FnPtrAddrShim(def_id, _) - | ShimKind::FutureDropPollShim(def_id, _, _) + | ShimKind::Clone(def_id, _) + | ShimKind::FnPtrAddr(def_id, _) + | ShimKind::FutureDropPoll(def_id, _, _) | ShimKind::AsyncDropGlue(def_id, _) - | ShimKind::AsyncDropGlueCtorShim(def_id, _) => def_id, + | ShimKind::AsyncDropGlueCtor(def_id, _) => def_id, } } @@ -340,47 +340,47 @@ impl<'tcx> ShimKind<'tcx> { pub fn def_id_if_not_guaranteed_local_codegen(self) -> Option { match self { ShimKind::DropGlue(def_id, Some(_)) - | ShimKind::AsyncDropGlueCtorShim(def_id, _) + | ShimKind::AsyncDropGlueCtor(def_id, _) | ShimKind::AsyncDropGlue(def_id, _) - | ShimKind::FutureDropPollShim(def_id, ..) - | ShimKind::ThreadLocalShim(def_id) => Some(def_id), - ShimKind::VTableShim(..) - | ShimKind::ReifyShim(..) - | ShimKind::FnPtrShim(..) - | ShimKind::ClosureOnceShim { .. } - | ShimKind::ConstructCoroutineInClosureShim { .. } + | ShimKind::FutureDropPoll(def_id, ..) + | ShimKind::ThreadLocal(def_id) => Some(def_id), + ShimKind::VTable(..) + | ShimKind::Reify(..) + | ShimKind::FnPtr(..) + | ShimKind::ClosureOnce { .. } + | ShimKind::ConstructCoroutineInClosure { .. } | ShimKind::DropGlue(..) - | ShimKind::CloneShim(..) - | ShimKind::FnPtrAddrShim(..) => None, + | ShimKind::Clone(..) + | ShimKind::FnPtrAddr(..) => None, } } pub fn requires_inline(&self) -> bool { match self { ShimKind::DropGlue(_, Some(ty)) => ty.is_array(), - ShimKind::AsyncDropGlueCtorShim(_, ty) => ty.is_coroutine(), - ShimKind::FutureDropPollShim(_, _, _) => false, + ShimKind::AsyncDropGlueCtor(_, ty) => ty.is_coroutine(), + ShimKind::FutureDropPoll(_, _, _) => false, ShimKind::AsyncDropGlue(_, _) => false, - ShimKind::ThreadLocalShim(_) => false, + ShimKind::ThreadLocal(_) => false, _ => true, } } pub fn has_polymorphic_mir_body(&self) -> bool { match *self { - ShimKind::CloneShim(..) - | ShimKind::ThreadLocalShim(..) - | ShimKind::FnPtrAddrShim(..) - | ShimKind::FnPtrShim(..) + ShimKind::Clone(..) + | ShimKind::ThreadLocal(..) + | ShimKind::FnPtrAddr(..) + | ShimKind::FnPtr(..) | ShimKind::DropGlue(_, Some(_)) - | ShimKind::FutureDropPollShim(..) + | ShimKind::FutureDropPoll(..) | ShimKind::AsyncDropGlue(_, _) => false, - ShimKind::AsyncDropGlueCtorShim(_, _) => false, - ShimKind::ClosureOnceShim { .. } - | ShimKind::ConstructCoroutineInClosureShim { .. } + ShimKind::AsyncDropGlueCtor(_, _) => false, + ShimKind::ClosureOnce { .. } + | ShimKind::ConstructCoroutineInClosure { .. } | ShimKind::DropGlue(..) - | ShimKind::ReifyShim(..) - | ShimKind::VTableShim(..) => true, + | ShimKind::Reify(..) + | ShimKind::VTable(..) => true, } } } @@ -451,7 +451,7 @@ fn resolve_async_drop_poll<'tcx>(mut cor_ty: Ty<'tcx>) -> Instance<'tcx> { continue; } else { return Instance { - def: ty::InstanceKind::Shim(ShimKind::FutureDropPollShim( + def: ty::InstanceKind::Shim(ShimKind::FutureDropPoll( poll_def_id, first_cor, cor_ty, @@ -465,7 +465,7 @@ fn resolve_async_drop_poll<'tcx>(mut cor_ty: Ty<'tcx>) -> Instance<'tcx> { }; if first_cor != cor_ty { return Instance { - def: ty::InstanceKind::Shim(ShimKind::FutureDropPollShim( + def: ty::InstanceKind::Shim(ShimKind::FutureDropPoll( poll_def_id, first_cor, cor_ty, @@ -642,11 +642,11 @@ impl<'tcx> Instance<'tcx> { match resolved.def { InstanceKind::Item(def) if resolved.def.requires_caller_location(tcx) => { debug!(" => fn pointer created for function with #[track_caller]"); - resolved.def = InstanceKind::Shim(ShimKind::ReifyShim(def, reason)); + resolved.def = InstanceKind::Shim(ShimKind::Reify(def, reason)); } InstanceKind::Virtual(def_id, _) => { debug!(" => fn pointer created for virtual call"); - resolved.def = InstanceKind::Shim(ShimKind::ReifyShim(def_id, reason)); + resolved.def = InstanceKind::Shim(ShimKind::Reify(def_id, reason)); } _ if tcx.sess.is_sanitizer_kcfi_enabled() => { // Reify `::call`-like method implementations @@ -655,7 +655,7 @@ impl<'tcx> Instance<'tcx> { // be directly reified because it's closure-like. The reify can handle the // unresolved instance. resolved = Instance { - def: InstanceKind::Shim(ShimKind::ReifyShim(def_id, reason)), + def: InstanceKind::Shim(ShimKind::Reify(def_id, reason)), args, } // Reify `Trait::method` implementations if the trait is dyn-compatible. @@ -667,7 +667,7 @@ impl<'tcx> Instance<'tcx> { // If this function could also go in a vtable, we need to `ReifyShim` it with // KCFI because it can only attach one type per function. resolved.def = - InstanceKind::Shim(ShimKind::ReifyShim(resolved.def_id(), reason)) + InstanceKind::Shim(ShimKind::Reify(resolved.def_id(), reason)) } } _ => {} @@ -692,7 +692,7 @@ impl<'tcx> Instance<'tcx> { if is_vtable_shim { debug!(" => associated item with unsizeable self: Self"); - return Instance { def: InstanceKind::Shim(ShimKind::VTableShim(def_id)), args }; + return Instance { def: InstanceKind::Shim(ShimKind::VTable(def_id)), args }; } let mut resolved = Instance::expect_resolve(tcx, typing_env, def_id, args, span); @@ -736,7 +736,7 @@ impl<'tcx> Instance<'tcx> { // - unlike functions, invoking a closure always goes through a // trait. resolved = Instance { - def: InstanceKind::Shim(ShimKind::ReifyShim(def_id, reason)), + def: InstanceKind::Shim(ShimKind::Reify(def_id, reason)), args, }; } else { @@ -744,13 +744,13 @@ impl<'tcx> Instance<'tcx> { " => vtable fn pointer created for function with #[track_caller]: {:?}", def ); - resolved.def = InstanceKind::Shim(ShimKind::ReifyShim(def, reason)); + resolved.def = InstanceKind::Shim(ShimKind::Reify(def, reason)); } } } InstanceKind::Virtual(def_id, _) => { debug!(" => vtable fn pointer created for virtual call"); - resolved.def = InstanceKind::Shim(ShimKind::ReifyShim(def_id, reason)) + resolved.def = InstanceKind::Shim(ShimKind::Reify(def_id, reason)) } _ => {} } @@ -820,7 +820,7 @@ impl<'tcx> Instance<'tcx> { .def_id; let track_caller = tcx.codegen_fn_attrs(closure_did).flags.contains(CodegenFnAttrFlags::TRACK_CALLER); - let def = ty::InstanceKind::Shim(ShimKind::ClosureOnceShim { + let def = ty::InstanceKind::Shim(ShimKind::ClosureOnce { call_once, closure: closure_did, track_caller, diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index 0552bf1dd1636..bec1ffc642769 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -381,29 +381,27 @@ impl<'tcx, P: Printer<'tcx> + std::fmt::Write> Print

for ty::Instance<'tcx> { impl<'tcx, P: Printer<'tcx> + std::fmt::Write> Print

for ty::ShimKind<'tcx> { fn print(&self, cx: &mut P) -> Result<(), PrintError> { match self { - ty::ShimKind::VTableShim(_) => cx.write_str("shim(vtable)"), - ty::ShimKind::ReifyShim(_, None) => cx.write_str("shim(reify)"), - ty::ShimKind::ReifyShim(_, Some(ty::ReifyReason::FnPtr)) => { + ty::ShimKind::VTable(_) => cx.write_str("shim(vtable)"), + ty::ShimKind::Reify(_, None) => cx.write_str("shim(reify)"), + ty::ShimKind::Reify(_, Some(ty::ReifyReason::FnPtr)) => { cx.write_str("shim(reify-fnptr)") } - ty::ShimKind::ReifyShim(_, Some(ty::ReifyReason::Vtable)) => { + ty::ShimKind::Reify(_, Some(ty::ReifyReason::Vtable)) => { cx.write_str("shim(reify-vtable)") } - ty::ShimKind::ThreadLocalShim(_) => cx.write_str("shim(tls)"), - ty::ShimKind::FnPtrShim(_, ty) => cx.write_str(&format!("shim({ty})")), - ty::ShimKind::ClosureOnceShim { .. } => cx.write_str("shim"), - ty::ShimKind::ConstructCoroutineInClosureShim { .. } => cx.write_str("shim"), + ty::ShimKind::ThreadLocal(_) => cx.write_str("shim(tls)"), + ty::ShimKind::FnPtr(_, ty) => cx.write_str(&format!("shim({ty})")), + ty::ShimKind::ClosureOnce { .. } => cx.write_str("shim"), + ty::ShimKind::ConstructCoroutineInClosure { .. } => cx.write_str("shim"), ty::ShimKind::DropGlue(_, None) => cx.write_str("shim(None)"), ty::ShimKind::DropGlue(_, Some(ty)) => cx.write_str(&format!("shim(Some({ty}))")), - ty::ShimKind::CloneShim(_, ty) => cx.write_str(&format!("shim({ty})")), - ty::ShimKind::FnPtrAddrShim(_, ty) => cx.write_str(&format!("shim({ty})")), - ty::ShimKind::FutureDropPollShim(_, proxy_ty, impl_ty) => { + ty::ShimKind::Clone(_, ty) => cx.write_str(&format!("shim({ty})")), + ty::ShimKind::FnPtrAddr(_, ty) => cx.write_str(&format!("shim({ty})")), + ty::ShimKind::FutureDropPoll(_, proxy_ty, impl_ty) => { cx.write_str(&format!("dropshim({proxy_ty}-{impl_ty})")) } ty::ShimKind::AsyncDropGlue(_, ty) => cx.write_str(&format!("shim({ty})")), - ty::ShimKind::AsyncDropGlueCtorShim(_, ty) => { - cx.write_str(&format!("shim(Some({ty}))")) - } + ty::ShimKind::AsyncDropGlueCtor(_, ty) => cx.write_str(&format!("shim(Some({ty}))")), } } } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index a1575a21e9073..e4ce2fb1ad3d2 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -746,14 +746,14 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>( return Err("implementation limitation -- HACK for dropping polymorphic type"); } InstanceKind::Shim(ShimKind::AsyncDropGlue(_, ty)) - | InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(_, ty)) => { + | InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(_, ty)) => { return if ty.still_further_specializable() { Err("still needs substitution") } else { Ok(()) }; } - InstanceKind::Shim(ShimKind::FutureDropPollShim(_, ty, ty2)) => { + InstanceKind::Shim(ShimKind::FutureDropPoll(_, ty, ty2)) => { return if ty.still_further_specializable() || ty2.still_further_specializable() { Err("still needs substitution") } else { @@ -765,15 +765,15 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>( // not get any optimizations run on it. Any subsequent inlining may cause cycles, but we // do not need to catch this here, we can wait until the inliner decides to continue // inlining a second time. - InstanceKind::Shim(ShimKind::VTableShim(_)) - | InstanceKind::Shim(ShimKind::ReifyShim(..)) - | InstanceKind::Shim(ShimKind::FnPtrShim(..)) - | InstanceKind::Shim(ShimKind::ClosureOnceShim { .. }) - | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosureShim { .. }) + InstanceKind::Shim(ShimKind::VTable(_)) + | InstanceKind::Shim(ShimKind::Reify(..)) + | InstanceKind::Shim(ShimKind::FnPtr(..)) + | InstanceKind::Shim(ShimKind::ClosureOnce { .. }) + | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosure { .. }) | InstanceKind::Shim(ShimKind::DropGlue(..)) - | InstanceKind::Shim(ShimKind::CloneShim(..)) - | InstanceKind::Shim(ShimKind::ThreadLocalShim(..)) - | InstanceKind::Shim(ShimKind::FnPtrAddrShim(..)) => return Ok(()), + | InstanceKind::Shim(ShimKind::Clone(..)) + | InstanceKind::Shim(ShimKind::ThreadLocal(..)) + | InstanceKind::Shim(ShimKind::FnPtrAddr(..)) => return Ok(()), } if inliner.tcx().is_constructor(callee_def_id) { @@ -1374,7 +1374,7 @@ fn try_instance_mir<'tcx>( instance: InstanceKind<'tcx>, ) -> Result<&'tcx Body<'tcx>, &'static str> { if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, Some(ty))) - | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(_, ty)) = instance + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(_, ty)) = instance && let ty::Adt(def, args) = ty.kind() { let fields = def.all_fields(); diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 0fd1a5f240758..ee63dd966baf6 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -26,24 +26,24 @@ fn should_recurse<'tcx>(tcx: TyCtxt<'tcx>, callee: ty::Instance<'tcx>) -> bool { // These have MIR and if that MIR is inlined, instantiated and then inlining is run // again, a function item can end up getting inlined. Thus we'll be able to cause // a cycle that way - InstanceKind::Shim(ShimKind::VTableShim(_)) - | InstanceKind::Shim(ShimKind::ReifyShim(..)) - | InstanceKind::Shim(ShimKind::FnPtrShim(..)) - | InstanceKind::Shim(ShimKind::ClosureOnceShim { .. }) - | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosureShim { .. }) - | InstanceKind::Shim(ShimKind::ThreadLocalShim { .. }) - | InstanceKind::Shim(ShimKind::CloneShim(..)) => {} + InstanceKind::Shim(ShimKind::VTable(_)) + | InstanceKind::Shim(ShimKind::Reify(..)) + | InstanceKind::Shim(ShimKind::FnPtr(..)) + | InstanceKind::Shim(ShimKind::ClosureOnce { .. }) + | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosure { .. }) + | InstanceKind::Shim(ShimKind::ThreadLocal { .. }) + | InstanceKind::Shim(ShimKind::Clone(..)) => {} // This shim does not call any other functions, thus there can be no recursion. - InstanceKind::Shim(ShimKind::FnPtrAddrShim(..)) => return false, + InstanceKind::Shim(ShimKind::FnPtrAddr(..)) => return false, // FIXME: A not fully instantiated drop shim can cause ICEs if one attempts to // have its MIR built. Likely oli-obk just screwed up the `ParamEnv`s, so this // needs some more analysis. InstanceKind::Shim(ShimKind::DropGlue(..)) - | InstanceKind::Shim(ShimKind::FutureDropPollShim(..)) + | InstanceKind::Shim(ShimKind::FutureDropPoll(..)) | InstanceKind::Shim(ShimKind::AsyncDropGlue(..)) - | InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(..)) => { + | InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(..)) => { if callee.has_param() { return false; } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index d6061edb74ce3..436b99811ae60 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -35,11 +35,11 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, shim: ty::ShimKind<'tcx>) -> Body<'tcx> { debug!("make_shim({:?})", shim); let mut result = match shim { - ty::ShimKind::VTableShim(def_id) => { + ty::ShimKind::VTable(def_id) => { let adjustment = Adjustment::Deref { source: DerefSource::MutPtr }; build_call_shim(tcx, shim, Some(adjustment), CallKind::Direct(def_id)) } - ty::ShimKind::FnPtrShim(def_id, ty) => { + ty::ShimKind::FnPtr(def_id, ty) => { let trait_ = tcx.parent(def_id); // Supports `Fn` or `async Fn` traits. let adjustment = match tcx @@ -59,10 +59,10 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, shim: ty::ShimKind<'tcx>) -> Body<'tcx> { // a virtual call, or a direct call to a function for which // indirect calls must be codegen'd differently than direct ones // (such as `#[track_caller]`). - ty::ShimKind::ReifyShim(def_id, _) => { + ty::ShimKind::Reify(def_id, _) => { build_call_shim(tcx, shim, None, CallKind::Direct(def_id)) } - ty::ShimKind::ClosureOnceShim { call_once: _, closure: _, track_caller: _ } => { + ty::ShimKind::ClosureOnce { call_once: _, closure: _, track_caller: _ } => { let fn_mut = tcx.require_lang_item(LangItem::FnMut, DUMMY_SP); let call_mut = tcx .associated_items(fn_mut) @@ -74,10 +74,9 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, shim: ty::ShimKind<'tcx>) -> Body<'tcx> { build_call_shim(tcx, shim, Some(Adjustment::RefMut), CallKind::Direct(call_mut)) } - ty::ShimKind::ConstructCoroutineInClosureShim { - coroutine_closure_def_id, - receiver_by_ref, - } => build_construct_coroutine_by_move_shim(tcx, coroutine_closure_def_id, receiver_by_ref), + ty::ShimKind::ConstructCoroutineInClosure { coroutine_closure_def_id, receiver_by_ref } => { + build_construct_coroutine_by_move_shim(tcx, coroutine_closure_def_id, receiver_by_ref) + } ty::ShimKind::DropGlue(def_id, ty) => { // FIXME(#91576): Drop shims for coroutines aren't subject to the MIR passes at the end @@ -128,10 +127,10 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, shim: ty::ShimKind<'tcx>) -> Body<'tcx> { build_drop_shim(tcx, def_id, ty, ty::TypingEnv::post_analysis(tcx, def_id)) } - ty::ShimKind::ThreadLocalShim(..) => build_thread_local_shim(tcx, shim), - ty::ShimKind::CloneShim(def_id, ty) => build_clone_shim(tcx, def_id, ty), - ty::ShimKind::FnPtrAddrShim(def_id, ty) => build_fn_ptr_addr_shim(tcx, def_id, ty), - ty::ShimKind::FutureDropPollShim(def_id, proxy_ty, impl_ty) => { + ty::ShimKind::ThreadLocal(..) => build_thread_local_shim(tcx, shim), + ty::ShimKind::Clone(def_id, ty) => build_clone_shim(tcx, def_id, ty), + ty::ShimKind::FnPtrAddr(def_id, ty) => build_fn_ptr_addr_shim(tcx, def_id, ty), + ty::ShimKind::FutureDropPoll(def_id, proxy_ty, impl_ty) => { let mut body = async_destructor_ctor::build_future_drop_poll_shim(tcx, def_id, proxy_ty, impl_ty); @@ -173,7 +172,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, shim: ty::ShimKind<'tcx>) -> Body<'tcx> { return body; } - ty::ShimKind::AsyncDropGlueCtorShim(def_id, ty) => { + ty::ShimKind::AsyncDropGlueCtor(def_id, ty) => { let body = async_destructor_ctor::build_async_destructor_ctor_shim(tcx, def_id, ty); debug!("make_shim({:?}) = {:?}", shim, body); return body; @@ -555,10 +554,8 @@ impl<'tcx> CloneShimBuilder<'tcx> { } fn into_mir(self) -> Body<'tcx> { - let source = MirSource::from_shim(ty::ShimKind::CloneShim( - self.def_id, - self.sig.inputs_and_output[0], - )); + let source = + MirSource::from_shim(ty::ShimKind::Clone(self.def_id, self.sig.inputs_and_output[0])); new_body(source, self.blocks, self.local_decls, self.sig.inputs().len(), self.span) } @@ -773,7 +770,7 @@ fn build_call_shim<'tcx>( // `FnPtrShim` contains the fn pointer type that a call shim is being built for - this is used // to instantiate into the signature of the shim. It is not necessary for users of this // MIR body to perform further instantiations (see `InstanceKind::has_polymorphic_mir_body`). - let (sig_args, untuple_args) = if let ty::ShimKind::FnPtrShim(_, ty) = shim { + let (sig_args, untuple_args) = if let ty::ShimKind::FnPtr(_, ty) = shim { let sig = tcx.instantiate_bound_regions_with_erased(ty.fn_sig(tcx)); let untuple_args = sig.inputs(); @@ -827,7 +824,7 @@ fn build_call_shim<'tcx>( // FIXME: Avoid having to adjust the signature both here and in // `fn_sig_for_fn_abi`. - if let ty::ShimKind::VTableShim(..) = shim { + if let ty::ShimKind::VTable(..) = shim { // Modify fn(self, ...) to fn(self: *mut Self, ...) let mut inputs_and_output = sig.inputs_and_output.to_vec(); let self_arg = &mut inputs_and_output[0]; @@ -1109,7 +1106,7 @@ fn build_fn_ptr_addr_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'t Some(Terminator { source_info, kind: TerminatorKind::Return, attributes: ThinVec::new() }), false, ); - let source = MirSource::from_shim(ty::ShimKind::FnPtrAddrShim(def_id, self_ty)); + let source = MirSource::from_shim(ty::ShimKind::FnPtrAddr(def_id, self_ty)); new_body(source, IndexVec::from_elem_n(start_block, 1), locals, sig.inputs().len(), span) } @@ -1208,7 +1205,7 @@ fn build_construct_coroutine_by_move_shim<'tcx>( false, ); - let source = MirSource::from_shim(ty::ShimKind::ConstructCoroutineInClosureShim { + let source = MirSource::from_shim(ty::ShimKind::ConstructCoroutineInClosure { coroutine_closure_def_id, receiver_by_ref, }); diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index b23ab7842d51f..f6217f1234bfc 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -175,7 +175,7 @@ pub(super) fn build_future_drop_poll_shim<'tcx>( proxy_ty: Ty<'tcx>, impl_ty: Ty<'tcx>, ) -> Body<'tcx> { - let shim = ty::ShimKind::FutureDropPollShim(def_id, proxy_ty, impl_ty); + let shim = ty::ShimKind::FutureDropPoll(def_id, proxy_ty, impl_ty); let ty::Coroutine(coroutine_def_id, _) = impl_ty.kind() else { bug!("build_future_drop_poll_shim not for coroutine impl type: ({:?})", shim); }; diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 7c4fce02ff005..20aaeba4c8c65 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -447,7 +447,7 @@ fn collect_items_rec<'tcx>( used_items.push(respan( starting_item.span, MonoItem::Fn(Instance { - def: InstanceKind::Shim(ShimKind::ThreadLocalShim(def_id)), + def: InstanceKind::Shim(ShimKind::ThreadLocal(def_id)), args: GenericArgs::empty(), }), )); @@ -1013,7 +1013,7 @@ fn visit_instance_use<'tcx>( bug!("{:?} being reified", instance); } } - ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(..)) => { + ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(..)) => { bug!("{:?} being reified", instance); } ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) => { @@ -1027,16 +1027,16 @@ fn visit_instance_use<'tcx>( } ty::InstanceKind::Item(..) | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, Some(_))) - | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(..)) | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(_, _)) - | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(_, _)) - | ty::InstanceKind::Shim(ty::ShimKind::VTableShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnceShim { .. }) - | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { .. }) - | ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::CloneShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddrShim(..)) => { + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(_, _)) + | ty::InstanceKind::Shim(ty::ShimKind::VTable(..)) + | ty::InstanceKind::Shim(ty::ShimKind::Reify(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnce { .. }) + | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosure { .. }) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtr(..)) + | ty::InstanceKind::Shim(ty::ShimKind::Clone(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddr(..)) => { output.push(create_fn_mono_item(tcx, instance, source)); } } diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 79b47c8e5944d..bf4a2bdd15107 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -632,20 +632,18 @@ fn characteristic_def_id_of_mono_item<'tcx>( ty::InstanceKind::Item(def) => def, ty::InstanceKind::Intrinsic(..) | ty::InstanceKind::Virtual(..) - | ty::InstanceKind::Shim(ty::ShimKind::VTableShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnceShim { .. }) - | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { - .. - }) + | ty::InstanceKind::Shim(ty::ShimKind::VTable(..)) + | ty::InstanceKind::Shim(ty::ShimKind::Reify(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtr(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnce { .. }) + | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosure { .. }) | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(..)) - | ty::InstanceKind::Shim(ty::ShimKind::CloneShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddrShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::Clone(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddr(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(..)) | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(..)) - | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(..)) => return None, + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(..)) => return None, }; // If this is a method, we want to put it into the same module as @@ -797,26 +795,26 @@ fn mono_item_visibility<'tcx>( let def_id = match instance.def { InstanceKind::Item(def_id) | InstanceKind::Shim(ShimKind::DropGlue(def_id, Some(_))) - | InstanceKind::Shim(ShimKind::FutureDropPollShim(def_id, _, _)) + | InstanceKind::Shim(ShimKind::FutureDropPoll(def_id, _, _)) | InstanceKind::Shim(ShimKind::AsyncDropGlue(def_id, _)) - | InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(def_id, _)) => def_id, + | InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(def_id, _)) => def_id, // We match the visibility of statics here - InstanceKind::Shim(ShimKind::ThreadLocalShim(def_id)) => { + InstanceKind::Shim(ShimKind::ThreadLocal(def_id)) => { return static_visibility(tcx, can_be_internalized, def_id); } // These are all compiler glue and such, never exported, always hidden. - InstanceKind::Shim(ShimKind::VTableShim(..)) - | InstanceKind::Shim(ShimKind::ReifyShim(..)) - | InstanceKind::Shim(ShimKind::FnPtrShim(..)) + InstanceKind::Shim(ShimKind::VTable(..)) + | InstanceKind::Shim(ShimKind::Reify(..)) + | InstanceKind::Shim(ShimKind::FnPtr(..)) | InstanceKind::Virtual(..) | InstanceKind::Intrinsic(..) - | InstanceKind::Shim(ShimKind::ClosureOnceShim { .. }) - | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosureShim { .. }) + | InstanceKind::Shim(ShimKind::ClosureOnce { .. }) + | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosure { .. }) | InstanceKind::Shim(ShimKind::DropGlue(..)) - | InstanceKind::Shim(ShimKind::CloneShim(..)) - | InstanceKind::Shim(ShimKind::FnPtrAddrShim(..)) => return Visibility::Hidden, + | InstanceKind::Shim(ShimKind::Clone(..)) + | InstanceKind::Shim(ShimKind::FnPtrAddr(..)) => return Visibility::Hidden, }; // Both the `start_fn` lang item and `main` itself should not be exported, @@ -1334,7 +1332,7 @@ pub(crate) fn provide(providers: &mut Providers) { // statements, plus one for the terminator. InstanceKind::Item(..) | InstanceKind::Shim(ShimKind::DropGlue(..)) - | InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(..)) => { + | InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(..)) => { let mir = tcx.instance_mir(instance.def); mir.basic_blocks .iter() 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 6284754016aec..e901e1cf98e7e 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 @@ -364,7 +364,7 @@ pub(crate) fn transform_instance<'tcx>( tcx.types.unit }; instance.args = tcx.mk_args_trait(self_ty, instance.args.into_iter().skip(1)); - } else if let ty::InstanceKind::Shim(ty::ShimKind::VTableShim(def_id)) = instance.def + } else if let ty::InstanceKind::Shim(ty::ShimKind::VTable(def_id)) = instance.def && let Some(trait_id) = tcx.trait_of_assoc(def_id) { // Adjust the type ids of VTableShims to the type id expected in the call sites for the @@ -461,8 +461,7 @@ pub(crate) fn transform_instance<'tcx>( fn default_or_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Option { match instance.def { - ty::InstanceKind::Item(def_id) - | ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim(def_id, _)) => { + ty::InstanceKind::Item(def_id) | ty::InstanceKind::Shim(ty::ShimKind::FnPtr(def_id, _)) => { tcx.opt_associated_item(def_id).map(|item| item.def_id) } _ => None, diff --git a/compiler/rustc_sanitizers/src/kcfi/typeid/mod.rs b/compiler/rustc_sanitizers/src/kcfi/typeid/mod.rs index 7df5ec9088a9c..23aa088c68ffa 100644 --- a/compiler/rustc_sanitizers/src/kcfi/typeid/mod.rs +++ b/compiler/rustc_sanitizers/src/kcfi/typeid/mod.rs @@ -46,8 +46,7 @@ pub fn typeid_for_instance<'tcx>( // // This was implemented for KCFI support in #123106 and #123052 (which introduced the // ReifyReason). The tracking issue for KCFI support for Rust is #123479. - if matches!(instance.def, InstanceKind::Shim(ShimKind::ReifyShim(_, Some(ReifyReason::FnPtr)))) - { + if matches!(instance.def, InstanceKind::Shim(ShimKind::Reify(_, Some(ReifyReason::FnPtr)))) { options.insert(TypeIdOptions::USE_CONCRETE_SELF); } // A KCFI type metadata identifier is a 32-bit constant produced by taking the lower half of the diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index d67b603b73a68..2513e7f958a21 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -63,8 +63,8 @@ pub(super) fn mangle<'tcx>( p.print_def_path( def_id, if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, _)) - | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(_, _)) - | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(_, _, _)) = instance.def + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(_, _)) + | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(_, _, _)) = instance.def { // Add the name of the dropped type to the symbol name &*instance.args @@ -81,13 +81,13 @@ pub(super) fn mangle<'tcx>( .unwrap(); match instance.def { - ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(..)) => { + ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(..)) => { p.write_str("{{tls-shim}}").unwrap(); } - ty::InstanceKind::Shim(ty::ShimKind::VTableShim(..)) => { + ty::InstanceKind::Shim(ty::ShimKind::VTable(..)) => { p.write_str("{{vtable-shim}}").unwrap(); } - ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(_, reason)) => { + ty::InstanceKind::Shim(ty::ShimKind::Reify(_, reason)) => { p.write_str("{{reify-shim").unwrap(); match reason { Some(ReifyReason::FnPtr) => p.write_str("-fnptr").unwrap(), @@ -98,7 +98,7 @@ pub(super) fn mangle<'tcx>( } // FIXME(async_closures): This shouldn't be needed when we fix // `Instance::ty`/`Instance::def_id`. - ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { + ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosure { receiver_by_ref, .. }) => { @@ -108,7 +108,7 @@ pub(super) fn mangle<'tcx>( _ => {} } - if let ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(..)) = instance.def { + if let ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(..)) = instance.def { let _ = p.write_str("{{drop-shim}}"); } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index b2f5ea1873807..b259774468c91 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -49,27 +49,27 @@ pub(super) fn mangle<'tcx>( // Append `::{shim:...#0}` to shims that can coexist with a non-shim instance. let shim_kind = match instance.def { - ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(_)) => Some("tls"), - ty::InstanceKind::Shim(ty::ShimKind::VTableShim(_)) => Some("vtable"), - ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(_, None)) => Some("reify"), - ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(_, Some(ReifyReason::FnPtr))) => { + ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(_)) => Some("tls"), + ty::InstanceKind::Shim(ty::ShimKind::VTable(_)) => Some("vtable"), + ty::InstanceKind::Shim(ty::ShimKind::Reify(_, None)) => Some("reify"), + ty::InstanceKind::Shim(ty::ShimKind::Reify(_, Some(ReifyReason::FnPtr))) => { Some("reify_fnptr") } - ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(_, Some(ReifyReason::Vtable))) => { + ty::InstanceKind::Shim(ty::ShimKind::Reify(_, Some(ReifyReason::Vtable))) => { Some("reify_vtable") } // FIXME(async_closures): This shouldn't be needed when we fix // `Instance::ty`/`Instance::def_id`. - ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { + ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosure { receiver_by_ref: true, .. }) => Some("by_move"), - ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { + ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosure { receiver_by_ref: false, .. }) => Some("by_ref"), - ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(_, _, _)) => Some("drop"), + ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(_, _, _)) => Some("drop"), _ => None, }; diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index d26750f255198..1d24dba913bcb 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -38,7 +38,7 @@ fn fn_sig_for_fn_abi<'tcx>( instance: ty::Instance<'tcx>, typing_env: ty::TypingEnv<'tcx>, ) -> ty::FnSig<'tcx> { - if let InstanceKind::Shim(ShimKind::ThreadLocalShim(..)) = instance.def { + if let InstanceKind::Shim(ShimKind::ThreadLocal(..)) = instance.def { return tcx.mk_fn_sig_safe_rust_abi([], tcx.thread_local_ptr_ty(instance.def_id())); } @@ -50,7 +50,7 @@ fn fn_sig_for_fn_abi<'tcx>( ); // Modify `fn(self, ...)` to `fn(self: *mut Self, ...)`. - if let ty::InstanceKind::Shim(ty::ShimKind::VTableShim(..)) = instance.def { + if let ty::InstanceKind::Shim(ty::ShimKind::VTable(..)) = instance.def { let mut inputs_and_output = sig.inputs_and_output.to_vec(); inputs_and_output[0] = Ty::new_mut_ptr(tcx, inputs_and_output[0]); sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); @@ -82,7 +82,7 @@ fn fn_sig_for_fn_abi<'tcx>( // a separate def-id for these bodies. let mut coroutine_kind = args.as_coroutine_closure().kind(); - let env_ty = if let InstanceKind::Shim(ShimKind::ConstructCoroutineInClosureShim { + let env_ty = if let InstanceKind::Shim(ShimKind::ConstructCoroutineInClosure { receiver_by_ref, .. }) = instance.def @@ -266,7 +266,7 @@ impl<'tcx> FnAbiDesc<'tcx> { let ty::PseudoCanonicalInput { typing_env, value: (instance, extra_args) } = query; let is_virtual_call = matches!(instance.def, ty::InstanceKind::Virtual(..)); let is_tls_shim_call = - matches!(instance.def, ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(_))); + matches!(instance.def, ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(_))); Self { layout_cx: LayoutCx::new(tcx, typing_env), sig: tcx.normalize_erasing_regions( diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 25edafce89f13..34a3a96f89c40 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -83,10 +83,10 @@ fn resolve_instance_raw<'tcx>( _ => return Ok(None), } debug!(" => nontrivial async drop glue ctor"); - ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(def_id, ty)) + ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(def_id, ty)) } else { debug!(" => trivial async drop glue ctor"); - ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(def_id, ty)) + ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(def_id, ty)) } } else if tcx.is_async_drop_in_place_coroutine(def_id) { let ty = args.type_at(0); @@ -280,10 +280,7 @@ fn resolve_associated_item<'tcx>( }; Some(Instance { - def: ty::InstanceKind::Shim(ty::ShimKind::CloneShim( - trait_item_id, - self_ty, - )), + def: ty::InstanceKind::Shim(ty::ShimKind::Clone(trait_item_id, self_ty)), args: rcvr_args, }) } else { @@ -300,7 +297,7 @@ fn resolve_associated_item<'tcx>( return Ok(None); } Some(Instance { - def: ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddrShim( + def: ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddr( trait_item_id, self_ty, )), @@ -333,7 +330,7 @@ fn resolve_associated_item<'tcx>( Some(Instance::resolve_closure(tcx, closure_def_id, args, target_kind)) } ty::FnDef(..) | ty::FnPtr(..) => Some(Instance { - def: ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim( + def: ty::InstanceKind::Shim(ty::ShimKind::FnPtr( trait_item_id, rcvr_args.type_at(0), )), @@ -350,7 +347,7 @@ fn resolve_associated_item<'tcx>( } else { Some(Instance { def: ty::InstanceKind::Shim( - ty::ShimKind::ConstructCoroutineInClosureShim { + ty::ShimKind::ConstructCoroutineInClosure { coroutine_closure_def_id, receiver_by_ref: target_kind != ty::ClosureKind::FnOnce, }, @@ -375,7 +372,7 @@ fn resolve_associated_item<'tcx>( // construct a new body that has the right return types. Some(Instance { def: ty::InstanceKind::Shim( - ty::ShimKind::ConstructCoroutineInClosureShim { + ty::ShimKind::ConstructCoroutineInClosure { coroutine_closure_def_id, receiver_by_ref: false, }, @@ -390,7 +387,7 @@ fn resolve_associated_item<'tcx>( Some(Instance::resolve_closure(tcx, closure_def_id, args, target_kind)) } ty::FnDef(..) | ty::FnPtr(..) => Some(Instance { - def: ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim( + def: ty::InstanceKind::Shim(ty::ShimKind::FnPtr( trait_item_id, rcvr_args.type_at(0), )), From d06469a60bcee336a64499d0f799cb8f02903643 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Thu, 18 Jun 2026 22:43:45 +0000 Subject: [PATCH 31/42] Remove `MirSource::from_instance` helper that is only used in one place It used to be much more prevalent before I extracted shims as their own enum. --- compiler/rustc_middle/src/mir/mod.rs | 4 ---- compiler/rustc_mir_transform/src/coroutine/by_move_body.rs | 6 ++++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 23e6fc15c2ede..3facba24d3fd7 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -127,10 +127,6 @@ impl<'tcx> MirSource<'tcx> { MirSource { instance: InstanceKind::Item(def_id), promoted: None } } - pub fn from_instance(instance: InstanceKind<'tcx>) -> Self { - MirSource { instance, promoted: None } - } - pub fn from_shim(shim: ShimKind<'tcx>) -> Self { MirSource { instance: InstanceKind::Shim(shim), promoted: None } } diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs index 411f090e34921..5933892ecd886 100644 --- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs +++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs @@ -223,8 +223,10 @@ pub(crate) fn coroutine_by_move_body_def_id<'tcx>( None, &mut PerParentDisambiguatorState::new(parent_def_id), ); - by_move_body.source = - mir::MirSource::from_instance(InstanceKind::Item(body_def.def_id().to_def_id())); + by_move_body.source = mir::MirSource { + instance: InstanceKind::Item(body_def.def_id().to_def_id()), + promoted: None, + }; if let Some(dumper) = MirDumper::new(tcx, "built", &by_move_body) { dumper.set_disambiguator(&"after").dump_mir(&by_move_body); From 7d42183eeb7f5d9b46a7a7caa79f8a8fe8073c07 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Mon, 22 Jun 2026 23:58:33 +0300 Subject: [PATCH 32/42] Add support for infers in delegation's generics --- compiler/rustc_ast_lowering/src/delegation.rs | 97 +- .../src/delegation/generics.rs | 498 ++++--- .../rustc_ast_lowering/src/diagnostics.rs | 9 + compiler/rustc_ast_lowering/src/lib.rs | 3 + compiler/rustc_hir/src/hir.rs | 28 +- compiler/rustc_hir_analysis/src/delegation.rs | 240 ++- .../rustc_hir_analysis/src/diagnostics.rs | 8 - .../src/hir_ty_lowering/generics.rs | 44 +- tests/pretty/delegation-self-rename.pp | 13 +- .../generics/free-fn-to-trait-infer.rs | 19 - .../generics/free-fn-to-trait-infer.stderr | 27 - .../generics/free-to-trait-static-reuse.rs | 8 - .../free-to-trait-static-reuse.stderr | 107 +- .../generics/generics-gen-args-errors.rs | 13 +- .../generics/generics-gen-args-errors.stderr | 210 ++- tests/ui/delegation/generics/infers.rs | 356 +++++ tests/ui/delegation/generics/infers.stderr | 1296 +++++++++++++++++ .../generics/trait-impl-wrong-args-count.rs | 5 + .../trait-impl-wrong-args-count.stderr | 122 +- .../unelided-lifetime-in-sig-ice-156848.rs | 6 +- ...unelided-lifetime-in-sig-ice-156848.stderr | 27 - tests/ui/delegation/self-ty-ice-156388.rs | 3 +- tests/ui/delegation/self-ty-ice-156388.stderr | 10 +- tests/ui/delegation/target-expr.rs | 1 - tests/ui/delegation/target-expr.stderr | 21 +- .../ui/delegation/unsupported.current.stderr | 10 +- tests/ui/delegation/unsupported.next.stderr | 10 +- tests/ui/delegation/unsupported.rs | 1 - 28 files changed, 2416 insertions(+), 776 deletions(-) delete mode 100644 tests/ui/delegation/generics/free-fn-to-trait-infer.rs delete mode 100644 tests/ui/delegation/generics/free-fn-to-trait-infer.stderr create mode 100644 tests/ui/delegation/generics/infers.rs create mode 100644 tests/ui/delegation/generics/infers.stderr delete mode 100644 tests/ui/delegation/generics/unelided-lifetime-in-sig-ice-156848.stderr diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 3ead3b86cb591..fc466246bf137 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -194,7 +194,7 @@ impl<'hir> LoweringContext<'_, 'hir> { return self.generate_delegation_error(span, delegation); } - let mut generics = self.uplift_delegation_generics(delegation, sig_id, is_method); + let mut generics = self.uplift_delegation_generics(delegation, sig_id); let (body_id, call_expr_id, unused_target_expr) = self.lower_delegation_body( delegation, @@ -404,10 +404,10 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::InferDelegationSig::Output(self.arena.alloc(hir::DelegationInfo { call_expr_id, call_path_res: self.get_resolution_id(call_path_node_id), - child_args_segment_id: generics.child.args_segment_id, - parent_args_segment_id: generics.parent.args_segment_id, - self_ty_id: generics.self_ty_id, - propagate_self_ty: generics.propagate_self_ty, + child_seg_id: generics.child.args_segment_id, + child_seg_id_for_sig: generics.child.segment_id_for_sig(), + parent_seg_id_for_sig: generics.parent.segment_id_for_sig(), + self_ty_propagation_kind: generics.self_ty_propagation_kind, group_id: { let id = match source { DelegationSource::Single => None, @@ -625,20 +625,40 @@ impl<'hir> LoweringContext<'_, 'hir> { }), ); - hir::QPath::Resolved(ty, self.arena.alloc(new_path)) - } - hir::QPath::TypeRelative(ty, segment) => { - let segment = self.process_segment(span, segment, &mut generics.child); + // Explicitly create `Self` self-type in case of infers or static + // free-to-trait reuses. + let ty = match generics.self_ty_propagation_kind { + Some(hir::DelegationSelfTyPropagationKind::SelfParam) => { + let self_param = generics.parent.generics.find_self_param(); + let path = self.create_generic_arg_path(self_param); + let kind = hir::TyKind::Path(path); + + let ty = match ty { + Some(ty) => hir::Ty { kind, ..ty.clone() }, + None => hir::Ty { kind, hir_id: self.next_id(), span }, + }; + + Some(&*self.arena.alloc(ty)) + } + _ => ty, + }; - hir::QPath::TypeRelative(ty, self.arena.alloc(segment)) + hir::QPath::Resolved(ty, self.arena.alloc(new_path)) } + hir::QPath::TypeRelative(..) => unreachable!("until inherent methods are supported"), }; - generics.self_ty_id = match new_path { - hir::QPath::Resolved(ty, _) => ty, - hir::QPath::TypeRelative(ty, _) => Some(ty), + if let Some(hir::DelegationSelfTyPropagationKind::SelfTy(id)) = + generics.self_ty_propagation_kind.as_mut() + { + *id = match new_path { + hir::QPath::Resolved(ty, _) => { + ty.expect("must contain self type as `SelfTy` propagation kind is specified") + } + hir::QPath::TypeRelative(ty, _) => ty, + } + .hir_id; } - .map(|ty| ty.hir_id); let callee_path = self.arena.alloc(self.mk_expr(hir::ExprKind::Path(new_path), span)); let args = self.arena.alloc_from_iter(args); @@ -662,25 +682,38 @@ impl<'hir> LoweringContext<'_, 'hir> { segment: &hir::PathSegment<'hir>, result: &mut GenericsGenerationResult<'hir>, ) -> hir::PathSegment<'hir> { - let details = result.generics.args_propagation_details(); - - // Always uplift generic params, because if they are not empty then they - // should be generated in delegation. - let generics = result.generics.into_hir_generics(self, span); - let segment = if details.should_propagate { - let args = generics.into_generic_args(self, span); - - // Needed for better error messages (`trait-impl-wrong-args-count.rs` test). - let args = if args.is_empty() { None } else { Some(args) }; - - hir::PathSegment { args, ..segment.clone() } - } else { - segment.clone() - }; + let infer_indices = result.generics.infer_indices(); + result.generics.into_hir_generics(self, span); + + let mut segment = segment.clone(); + let mut args_iter = result.generics.create_args_iterator(); + + let new_args = segment + .args + .filter(|args| !args.is_empty()) + .map(|args| { + self.arena.alloc_from_iter(args.args.iter().enumerate().map(|(idx, arg)| { + if infer_indices.contains(&idx) { + args_iter.next(self, |_| arg.hir_id()).expect("arg must exist for infer") + } else { + *arg + } + })) + }) + .unwrap_or_else(|| self.arena.alloc_from_iter(args_iter.consume_all(self))); + + // Needed for better error messages (`trait-impl-wrong-args-count.rs` test). + segment.args = (!new_args.is_empty()).then(|| { + &*self.arena.alloc(hir::GenericArgs { + args: new_args, + constraints: &[], + parenthesized: hir::GenericArgsParentheses::No, + span_ext: segment.args.map_or(span, |args| args.span_ext), + }) + }); - if details.use_args_in_sig_inheritance { - result.args_segment_id = Some(segment.hir_id); - } + result.args_segment_id = segment.hir_id; + result.use_for_sig_inheritance = !result.generics.is_trait_impl(); segment } diff --git a/compiler/rustc_ast_lowering/src/delegation/generics.rs b/compiler/rustc_ast_lowering/src/delegation/generics.rs index f8e3528750035..79a3961c22a53 100644 --- a/compiler/rustc_ast_lowering/src/delegation/generics.rs +++ b/compiler/rustc_ast_lowering/src/delegation/generics.rs @@ -1,6 +1,7 @@ use hir::HirId; use hir::def::{DefKind, Res}; use rustc_ast::*; +use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::ty::GenericParamDefKind; @@ -9,21 +10,7 @@ use rustc_span::symbol::kw; use rustc_span::{Ident, Span, sym}; use crate::LoweringContext; - -#[derive(Clone, Copy)] -pub(super) enum DelegationGenericsKind { - /// User-specified args are present: `reuse foo::;`. - UserSpecified, - /// The default case when no user-specified args are present: `reuse Trait::foo;`. - Default, - /// In free-to-trait reuse, when user specified args for trait `reuse Trait::::foo;` - /// in this case we need to both generate `Self` and process user args. - SelfAndUserSpecified, - /// In delegations from trait impl to other entities like free functions or trait functions, - /// we want to generate a function whose generics matches generics of signature function - /// in trait. - TraitImpl(bool /* Has user-specified args */), -} +use crate::diagnostics::DelegationInfersMismatch; #[derive(Debug, Clone, Copy)] pub(super) enum GenericsPosition { @@ -31,30 +18,30 @@ pub(super) enum GenericsPosition { Child, } +#[derive(Debug)] +pub(super) enum GenericArgSlot { + UserSpecified, + Generate(T, Option /* Infer arg index from AST */), +} + pub(super) struct DelegationGenerics { - generics: T, - kind: DelegationGenericsKind, + data: T, pos: GenericsPosition, + trait_impl: bool, } -impl<'hir> DelegationGenerics<&'hir [ty::GenericParamDef]> { - fn default(generics: &'hir [ty::GenericParamDef], pos: GenericsPosition) -> Self { - DelegationGenerics { generics, pos, kind: DelegationGenericsKind::Default } - } - - fn user_specified(generics: &'hir [ty::GenericParamDef], pos: GenericsPosition) -> Self { - DelegationGenerics { generics, pos, kind: DelegationGenericsKind::UserSpecified } - } +type TyGenerics<'hir> = Vec>; - fn trait_impl( - generics: &'hir [ty::GenericParamDef], - user_specified: bool, +impl<'hir> DelegationGenerics> { + fn generate_all( + params: &'hir [ty::GenericParamDef], pos: GenericsPosition, + trait_impl: bool, ) -> Self { DelegationGenerics { - generics, + data: params.iter().map(|p| GenericArgSlot::Generate(p, None)).collect(), pos, - kind: DelegationGenericsKind::TraitImpl(user_specified), + trait_impl, } } } @@ -70,103 +57,176 @@ impl<'hir> DelegationGenerics<&'hir [ty::GenericParamDef]> { /// (i.e., method call scenarios), in such a case this approach helps /// a lot as if `into_hir_generics` will not be called then uplifting will not happen. pub(super) enum HirOrTyGenerics<'hir> { - Ty(DelegationGenerics<&'hir [ty::GenericParamDef]>), + Ty(DelegationGenerics>), Hir(DelegationGenerics<&'hir hir::Generics<'hir>>), } pub(super) struct GenericsGenerationResult<'hir> { pub(super) generics: HirOrTyGenerics<'hir>, - pub(super) args_segment_id: Option, + pub(super) args_segment_id: HirId, + pub(super) use_for_sig_inheritance: bool, +} + +impl GenericsGenerationResult<'_> { + pub(super) fn segment_id_for_sig(&self) -> Option { + self.use_for_sig_inheritance.then(|| self.args_segment_id) + } } pub(super) struct GenericsGenerationResults<'hir> { pub(super) parent: GenericsGenerationResult<'hir>, pub(super) child: GenericsGenerationResult<'hir>, - pub(super) self_ty_id: Option, - pub(super) propagate_self_ty: bool, + pub(super) self_ty_propagation_kind: Option, } -pub(super) struct GenericArgsPropagationDetails { - pub(super) should_propagate: bool, - pub(super) use_args_in_sig_inheritance: bool, +pub(super) struct DelegationGenericArgsIterator<'hir> { + index: usize = Default::default(), + params: &'hir [hir::GenericParam<'hir>], } -impl DelegationGenericsKind { - fn args_propagation_details(self) -> GenericArgsPropagationDetails { - match self { - DelegationGenericsKind::UserSpecified - | DelegationGenericsKind::SelfAndUserSpecified => GenericArgsPropagationDetails { - should_propagate: false, - use_args_in_sig_inheritance: true, - }, - DelegationGenericsKind::TraitImpl(user_specified) => GenericArgsPropagationDetails { - should_propagate: !user_specified, - use_args_in_sig_inheritance: false, - }, - DelegationGenericsKind::Default => GenericArgsPropagationDetails { - should_propagate: true, - use_args_in_sig_inheritance: false, - }, +/// During generic args propagation we need to create generic args +/// (and their `HirId`s) on demand, as some of generic args can not be used +/// and in this case an assert of an unseen `HirId` will be triggered. Moreover, +/// when replacing infers with generated generic params we should reuse existing +/// `HirId` of replaced infer, thus this iterator abstracts the way `HirId`s are +/// created for new generic args. +impl<'hir> DelegationGenericArgsIterator<'hir> { + pub(super) fn next( + &mut self, + ctx: &mut LoweringContext<'_, 'hir>, + hir_id_factory: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> HirId, + ) -> Option> { + let p = loop { + if self.index >= self.params.len() { + return None; + } + + let p = self.params[self.index]; + self.index += 1; + + // Skip self generic arg, we do not need to propagate it. + if p.name.ident().name == kw::SelfUpper || p.is_impl_trait() { + continue; + } + + break p; + }; + + let hir_id = hir_id_factory(ctx); + + Some(match p.kind { + hir::GenericParamKind::Lifetime { .. } => { + hir::GenericArg::Lifetime(ctx.arena.alloc(hir::Lifetime { + hir_id, + ident: p.name.ident(), + kind: hir::LifetimeKind::Param(p.def_id), + source: hir::LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full }, + syntax: hir::LifetimeSyntax::ExplicitBound, + })) + } + hir::GenericParamKind::Type { .. } => hir::GenericArg::Type(ctx.arena.alloc(hir::Ty { + hir_id, + span: p.span, + kind: hir::TyKind::Path(ctx.create_generic_arg_path(&p)), + })), + hir::GenericParamKind::Const { .. } => { + hir::GenericArg::Const(ctx.arena.alloc(hir::ConstArg { + hir_id, + kind: hir::ConstArgKind::Path(ctx.create_generic_arg_path(&p)), + span: p.span, + })) + } + }) + } + + pub(super) fn consume_all( + mut self, + ctx: &mut LoweringContext<'_, 'hir>, + ) -> Vec> { + let mut args = vec![]; + while let Some(arg) = self.next(ctx, |ctx| ctx.next_id()) { + args.push(arg); } + + args } } impl<'hir> HirOrTyGenerics<'hir> { - pub(super) fn into_hir_generics( - &mut self, - ctx: &mut LoweringContext<'_, 'hir>, - span: Span, - ) -> &mut HirOrTyGenerics<'hir> { + pub(super) fn into_hir_generics(&mut self, ctx: &mut LoweringContext<'_, 'hir>, span: Span) { if let HirOrTyGenerics::Ty(ty) = self { let rename_self = matches!(ty.pos, GenericsPosition::Child); - let params = ctx.uplift_delegation_generic_params(span, ty.generics, rename_self); + let params = ctx.uplift_delegation_generic_params(span, &ty.data, rename_self); *self = HirOrTyGenerics::Hir(DelegationGenerics { - generics: params, - kind: ty.kind, + data: params, pos: ty.pos, + trait_impl: ty.trait_impl, }); } - - self } fn hir_generics_or_empty(&self) -> &'hir hir::Generics<'hir> { match self { HirOrTyGenerics::Ty(_) => hir::Generics::empty(), - HirOrTyGenerics::Hir(hir) => hir.generics, + HirOrTyGenerics::Hir(hir) => hir.data, } } - pub(super) fn into_generic_args( - &self, - ctx: &mut LoweringContext<'_, 'hir>, - span: Span, - ) -> &'hir hir::GenericArgs<'hir> { + pub(super) fn create_args_iterator(&self) -> DelegationGenericArgsIterator<'hir> { match self { HirOrTyGenerics::Ty(_) => { - bug!("Attempting to get generic args before uplifting to HIR") + bug!("attempting to get generic args before uplifting to HIR") } HirOrTyGenerics::Hir(hir) => { - let add_lifetimes = matches!(hir.pos, GenericsPosition::Parent); - ctx.create_generics_args_from_params(hir.generics.params, add_lifetimes, span) + DelegationGenericArgsIterator { params: hir.data.params, .. } } } } - pub(super) fn args_propagation_details(&self) -> GenericArgsPropagationDetails { + pub(super) fn infer_indices(&self) -> FxHashSet { match self { - HirOrTyGenerics::Ty(ty) => ty.kind.args_propagation_details(), - HirOrTyGenerics::Hir(hir) => hir.kind.args_propagation_details(), + HirOrTyGenerics::Ty(ty) => ty + .data + .iter() + .flat_map(|slot| match slot { + GenericArgSlot::Generate(_, Some(idx)) => Some(*idx), + _ => None, + }) + .collect(), + HirOrTyGenerics::Hir(_) => bug!("accessed infer indices on uplifted generics"), + } + } + + pub(super) fn is_trait_impl(&self) -> bool { + match self { + HirOrTyGenerics::Ty(ty) => ty.trait_impl, + HirOrTyGenerics::Hir(hir) => hir.trait_impl, + } + } + + pub(super) fn find_self_param(&self) -> &'hir hir::GenericParam<'hir> { + match self { + HirOrTyGenerics::Ty(_) => { + bug!("accessed ty-level generics while searching for uplifted `Self` param") + } + HirOrTyGenerics::Hir(hir) => hir + .data + .params + .iter() + .find(|p| p.name.ident().name == kw::SelfUpper) + .expect("`Self` generic param is not found while expected"), } } } impl<'hir> GenericsGenerationResult<'hir> { - fn new( - generics: DelegationGenerics<&'hir [ty::GenericParamDef]>, - ) -> GenericsGenerationResult<'hir> { - GenericsGenerationResult { generics: HirOrTyGenerics::Ty(generics), args_segment_id: None } + fn new(generics: DelegationGenerics>) -> GenericsGenerationResult<'hir> { + GenericsGenerationResult { + generics: HirOrTyGenerics::Ty(generics), + args_segment_id: HirId::INVALID, + use_for_sig_inheritance: false, + } } } @@ -208,13 +268,30 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, delegation: &Delegation, sig_id: DefId, - is_method: bool, ) -> GenericsGenerationResults<'hir> { let delegation_parent_kind = self.tcx.def_kind(self.tcx.local_parent(self.owner.def_id)); let segments = &delegation.path.segments; let len = segments.len(); - let child_user_specified = segments[len - 1].args.is_some(); + + let get_user_args = |idx: usize| -> Option<&AngleBracketedArgs> { + let segment = &segments[idx]; + + let Some(args) = segment.args.as_ref() else { return None }; + let GenericArgs::AngleBracketed(args) = args else { + self.tcx.dcx().span_delayed_bug( + segment.span(), + "expected angle-bracketed generic args in delegation segment", + ); + + return None; + }; + + // Treat empty args `reuse foo::<> as bar` as `reuse foo as bar`, + // the same logic applied when we call function `fn f(t: T)` + // like that `f::<>(())`, in HIR no `<>` will be generated. + (!args.args.is_empty()).then(|| args) + }; let sig_params = &self.tcx.generics_of(sig_id).own_params[..]; @@ -223,23 +300,15 @@ impl<'hir> LoweringContext<'_, 'hir> { if matches!(delegation_parent_kind, DefKind::Impl { of_trait: true }) { // Considering parent generics, during signature inheritance // we will take those args that are in trait impl header trait ref. - let parent = DelegationGenerics::trait_impl(&[], true, GenericsPosition::Parent); - let parent = GenericsGenerationResult::new(parent); + let parent = + DelegationGenerics { data: vec![], pos: GenericsPosition::Child, trait_impl: true }; - let child = DelegationGenerics::trait_impl( - sig_params, - child_user_specified, - GenericsPosition::Child, - ); + let parent = GenericsGenerationResult::new(parent); + let child = DelegationGenerics::generate_all(sig_params, GenericsPosition::Child, true); let child = GenericsGenerationResult::new(child); - return GenericsGenerationResults { - parent, - child, - self_ty_id: None, - propagate_self_ty: false, - }; + return GenericsGenerationResults { parent, child, self_ty_propagation_kind: None }; } let delegation_in_free_ctx = @@ -248,7 +317,13 @@ impl<'hir> LoweringContext<'_, 'hir> { let sig_parent = self.tcx.parent(sig_id); let sig_in_trait = matches!(self.tcx.def_kind(sig_parent), DefKind::Trait); let free_to_trait_delegation = delegation_in_free_ctx && sig_in_trait; - let generate_self = free_to_trait_delegation && is_method && delegation.qself.is_none(); + + let qself_is_infer = + delegation.qself.as_ref().is_some_and(|qself| qself.ty.is_maybe_parenthesised_infer()); + + let qself_is_none = delegation.qself.is_none(); + + let generate_self = free_to_trait_delegation && (qself_is_none || qself_is_infer); let can_add_generics_to_parent = len >= 2 && self.get_resolution_id(segments[len - 2].id).is_some_and(|def_id| { @@ -256,57 +331,137 @@ impl<'hir> LoweringContext<'_, 'hir> { }); let parent_generics = if can_add_generics_to_parent { - let sig_parent_params = &self.tcx.generics_of(sig_parent).own_params[..]; - - if segments[len - 2].args.is_some() { - if generate_self { - // Take only first Self parameter, it is trait so Self must be present. - DelegationGenerics { - kind: DelegationGenericsKind::SelfAndUserSpecified, - generics: &sig_parent_params[..1], - pos: GenericsPosition::Parent, - } - } else { - DelegationGenerics::user_specified(&[], GenericsPosition::Parent) + let sig_parent_params = &self.tcx.generics_of(sig_parent).own_params; + + if let Some(args) = get_user_args(len - 2) { + DelegationGenerics { + data: self.create_slots_from_args( + args, + &sig_parent_params[usize::from(!generate_self)..], + generate_self, + ), + pos: GenericsPosition::Parent, + trait_impl: false, } } else { - let skip_self = usize::from(!generate_self); - DelegationGenerics::default( - &sig_parent_params[skip_self..], + DelegationGenerics::generate_all( + &sig_parent_params[usize::from(!generate_self)..], GenericsPosition::Parent, + false, ) } } else { - DelegationGenerics::default(&[], GenericsPosition::Parent) + DelegationGenerics { data: vec![], pos: GenericsPosition::Parent, trait_impl: false } }; - let child_generics = if child_user_specified { + let child_generics = if let Some(args) = get_user_args(len - 1) { let synth_params_index = sig_params.iter().position(|p| p.kind.is_synthetic()).unwrap_or(sig_params.len()); - DelegationGenerics::user_specified( - &sig_params[synth_params_index..], - GenericsPosition::Child, - ) + let mut slots = + self.create_slots_from_args(args, &sig_params[..synth_params_index], false); + + for synth_param in &sig_params[synth_params_index..] { + slots.push(GenericArgSlot::Generate(synth_param, None)); + } + + DelegationGenerics { data: slots, pos: GenericsPosition::Child, trait_impl: false } } else { - DelegationGenerics::default(sig_params, GenericsPosition::Child) + DelegationGenerics::generate_all(sig_params, GenericsPosition::Child, false) }; GenericsGenerationResults { parent: GenericsGenerationResult::new(parent_generics), child: GenericsGenerationResult::new(child_generics), - self_ty_id: None, - propagate_self_ty: free_to_trait_delegation && !generate_self, + self_ty_propagation_kind: match free_to_trait_delegation { + true => Some(match qself_is_none { + true => hir::DelegationSelfTyPropagationKind::SelfParam, + false => match qself_is_infer { + true => hir::DelegationSelfTyPropagationKind::SelfParam, + // HirId is filled during generic args propagation. + false => hir::DelegationSelfTyPropagationKind::SelfTy(HirId::INVALID), + }, + }), + false => None, + }, + } + } + + /// Generates generic argument slots for user-specified `args` and + /// generic `params` of the signature function. This function checks whether + /// there are infers (`kw::UnderscoreLifetime` or `kw::Underscore`) in + /// user-specified args, and if so we add `Generate` slot meaning we have to + /// generate generic param for delegation and propagate it instead of this infer. + /// We zip over user-specified args and signature generic params, so if there are more + /// infers than generic params then we will not process all infers thus not generating + /// more generic params then needed (anyway it is an error). + fn create_slots_from_args( + &self, + args: &AngleBracketedArgs, + params: &'hir [ty::GenericParamDef], + add_first_self: bool, + ) -> TyGenerics<'hir> { + let mut slots = vec![]; + if add_first_self { + slots.push(GenericArgSlot::Generate(¶ms[0], None)); + } + + let params = ¶ms[usize::from(add_first_self)..]; + for (idx, (arg, param)) in args.args.iter().zip(params).enumerate() { + let AngleBracketedArg::Arg(arg) = arg else { continue }; + + let is_infer = match arg { + GenericArg::Lifetime(lt) => lt.ident.name == kw::UnderscoreLifetime, + GenericArg::Type(ty) => ty.is_maybe_parenthesised_infer(), + GenericArg::Const(_) => false, + }; + + // If `'_` is used instead of `_` (or vice versa) we emit a meaningful + // error instead of processing this infer or leaving it as is for signature + // inheritance. + if is_infer + && matches!( + (arg, ¶m.kind), + ( + GenericArg::Lifetime(_), + GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } + ) | ( + GenericArg::Type(_) | GenericArg::Const(_), + GenericParamDefKind::Lifetime { .. } + ) + ) + { + let (actual, expected) = if matches!(arg, GenericArg::Lifetime(..)) { + (kw::UnderscoreLifetime, kw::Underscore) + } else { + (kw::Underscore, kw::UnderscoreLifetime) + }; + + self.tcx.dcx().emit_err(DelegationInfersMismatch { + span: arg.span(), + actual, + expected, + }); + } + + slots.push(match is_infer { + true => GenericArgSlot::Generate(param, Some(idx)), + false => GenericArgSlot::UserSpecified, + }); } + + slots } fn uplift_delegation_generic_params( &mut self, span: Span, - params: &'hir [ty::GenericParamDef], + params: &[GenericArgSlot<&ty::GenericParamDef>], rename_self: bool, ) -> &'hir hir::Generics<'hir> { - let params = self.arena.alloc_from_iter(params.iter().map(|p| { + let params = self.arena.alloc_from_iter(params.iter().flat_map(|p| { + let GenericArgSlot::Generate(p, _) = p else { return None }; + let def_kind = match p.kind { GenericParamDefKind::Lifetime => DefKind::LifetimeParam, GenericParamDefKind::Type { .. } => DefKind::TyParam, @@ -354,7 +509,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // `lower_node_id` routine so param's id is added to `self.children`. let hir_id = self.lower_node_id(node_id); - hir::GenericParam { + Some(hir::GenericParam { hir_id, colon_span: Some(span), def_id, @@ -363,7 +518,7 @@ impl<'hir> LoweringContext<'_, 'hir> { pure_wrt_drop: p.pure_wrt_drop, source: hir::GenericParamSource::Generics, span, - } + }) })); // HACK: for now we generate predicates such that all lifetimes are early bound, @@ -413,77 +568,32 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - fn create_generics_args_from_params( + pub(super) fn create_generic_arg_path( &mut self, - params: &[hir::GenericParam<'hir>], - add_lifetimes: bool, - span: Span, - ) -> &'hir hir::GenericArgs<'hir> { - self.arena.alloc(hir::GenericArgs { - args: self.arena.alloc_from_iter(params.iter().filter_map(|p| { - // Skip self generic arg, we do not need to propagate it. - if p.name.ident().name == kw::SelfUpper || p.is_impl_trait() { - return None; - } - - let create_path = |this: &mut Self| { - let res = Res::Def( - match p.kind { - hir::GenericParamKind::Lifetime { .. } => DefKind::LifetimeParam, - hir::GenericParamKind::Type { .. } => DefKind::TyParam, - hir::GenericParamKind::Const { .. } => DefKind::ConstParam, - }, - p.def_id.to_def_id(), - ); - - hir::QPath::Resolved( - None, - self.arena.alloc(hir::Path { - segments: this.arena.alloc_slice(&[hir::PathSegment { - args: None, - hir_id: this.next_id(), - ident: p.name.ident(), - infer_args: false, - res, - }]), - res, - span: p.span, - }), - ) - }; - - match p.kind { - hir::GenericParamKind::Lifetime { .. } => match add_lifetimes { - true => Some(hir::GenericArg::Lifetime(self.arena.alloc(hir::Lifetime { - hir_id: self.next_id(), - ident: p.name.ident(), - kind: hir::LifetimeKind::Param(p.def_id), - source: hir::LifetimeSource::Path { - angle_brackets: hir::AngleBrackets::Full, - }, - syntax: hir::LifetimeSyntax::ExplicitBound, - }))), - false => None, - }, - hir::GenericParamKind::Type { .. } => { - Some(hir::GenericArg::Type(self.arena.alloc(hir::Ty { - hir_id: self.next_id(), - span: p.span, - kind: hir::TyKind::Path(create_path(self)), - }))) - } - hir::GenericParamKind::Const { .. } => { - Some(hir::GenericArg::Const(self.arena.alloc(hir::ConstArg { - hir_id: self.next_id(), - kind: hir::ConstArgKind::Path(create_path(self)), - span: p.span, - }))) - } - } - })), - constraints: &[], - parenthesized: hir::GenericArgsParentheses::No, - span_ext: span, - }) + p: &hir::GenericParam<'hir>, + ) -> hir::QPath<'hir> { + let res = Res::Def( + match p.kind { + hir::GenericParamKind::Lifetime { .. } => DefKind::LifetimeParam, + hir::GenericParamKind::Type { .. } => DefKind::TyParam, + hir::GenericParamKind::Const { .. } => DefKind::ConstParam, + }, + p.def_id.to_def_id(), + ); + + hir::QPath::Resolved( + None, + self.arena.alloc(hir::Path { + segments: self.arena.alloc_slice(&[hir::PathSegment { + args: None, + hir_id: self.next_id(), + ident: p.name.ident(), + infer_args: false, + res, + }]), + res, + span: p.span, + }), + ) } } diff --git a/compiler/rustc_ast_lowering/src/diagnostics.rs b/compiler/rustc_ast_lowering/src/diagnostics.rs index 31f094209a946..238a16d9b859d 100644 --- a/compiler/rustc_ast_lowering/src/diagnostics.rs +++ b/compiler/rustc_ast_lowering/src/diagnostics.rs @@ -560,3 +560,12 @@ pub(crate) struct DelegationAttemptedBlockWithDefsDeletion { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag("wrong infer used: expected {$expected}, found: {$actual}")] +pub(crate) struct DelegationInfersMismatch { + #[primary_span] + pub span: Span, + pub expected: Symbol, + pub actual: Symbol, +} diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index b8d708d42ff10..06e83a7486100 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -31,6 +31,9 @@ //! in the HIR, especially for multiple identifiers. // tidy-alphabetical-start +#![feature(const_default)] +#![feature(const_trait_impl)] +#![feature(default_field_values)] #![feature(deref_patterns)] #![recursion_limit = "256"] // tidy-alphabetical-end diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 8d886e7ac6fbf..cd7a9a6cd721c 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3854,14 +3854,34 @@ pub enum OpaqueTyOrigin { }, } +#[derive(Debug, Clone, Copy, PartialEq, Eq, StableHash)] +pub enum DelegationSelfTyPropagationKind { + /// Used when self type is explicitly specified in free-to-trait reuse + /// `reuse <() as Trait>::foo;`. + SelfTy(HirId /* Self ty id */), + /// Used when infer instead of a self type is specified or self type + /// is not specified at all: `reuse Trait::foo; reuse <_ as Trait>::foo;`. + SelfParam, +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, StableHash)] pub struct DelegationInfo { pub call_expr_id: HirId, pub call_path_res: Option, - pub parent_args_segment_id: Option, - pub child_args_segment_id: Option, - pub self_ty_id: Option, - pub propagate_self_ty: bool, + + /// Id of the child segment in delegation: `reuse Trait::foo`, + /// `child_seg_id` points to `foo`. + pub child_seg_id: HirId, + + /// Ids of parent and child segments, `Some` when we need to take + /// generic args of those segments for signature/predicates inheritance. + /// `None` in trait impl case or when error delegation is generated, meaning + /// we should not access those segments for generic args lowering. + /// When `child_seg_id_for_sig` is Some it always equals `child_seg_id`. + pub parent_seg_id_for_sig: Option, + pub child_seg_id_for_sig: Option, + + pub self_ty_propagation_kind: Option, pub group_id: Option<(LocalExpnId, bool /* unused_target_expr */)>, } diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index 7f3edd7f09231..de2315edb7e8f 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -5,16 +5,15 @@ use std::debug_assert_matches; use rustc_data_structures::fx::FxHashMap; -use rustc_hir::PathSegment; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::{DelegationSelfTyPropagationKind, PathSegment}; use rustc_middle::ty::{ self, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; use rustc_span::{ErrorGuaranteed, Span, kw}; use crate::collect::ItemCtxt; -use crate::diagnostics::DelegationSelfTypeNotSpecified; use crate::hir_ty_lowering::HirTyLowerer; type RemapTable = FxHashMap; @@ -65,8 +64,9 @@ impl<'tcx> TypeFolder> for ParamIndexRemapper<'tcx> { } } +#[derive(Debug)] enum SelfPositionKind { - AfterLifetimes(bool /* Should propagate self ty */), + AfterLifetimes(Option), Zero, None, } @@ -83,8 +83,8 @@ fn create_self_position_kind( | (FnKind::AssocTrait, FnKind::Free) => SelfPositionKind::Zero, (FnKind::Free, FnKind::AssocTrait) => { - let propagate_self_ty = tcx.hir_delegation_info(delegation_id).propagate_self_ty; - SelfPositionKind::AfterLifetimes(propagate_self_ty) + let kind = tcx.hir_delegation_info(delegation_id).self_ty_propagation_kind; + SelfPositionKind::AfterLifetimes(kind) } _ => SelfPositionKind::None, @@ -268,28 +268,6 @@ fn get_parent_and_inheritance_kind<'tcx>( } } -fn get_delegation_self_ty_or_err(tcx: TyCtxt<'_>, delegation_id: LocalDefId) -> Ty<'_> { - tcx.hir_delegation_info(delegation_id) - .self_ty_id - .map(|id| { - let ctx = ItemCtxt::new(tcx, delegation_id); - ctx.lower_ty(tcx.hir_node(id).expect_ty()) - }) - .unwrap_or_else(|| { - // It is possible to attempt to get self type when it is used in signature - // (i.e., `fn default() -> Self`), so emit error here in addition to possible - // `mismatched types` error (see #156388). - let err = DelegationSelfTypeNotSpecified { span: tcx.def_span(delegation_id) }; - tcx.dcx().emit_err(err); - - Ty::new_error_with_message( - tcx, - tcx.def_span(delegation_id), - "the self type must be specified", - ) - }) -} - fn get_delegation_self_ty<'tcx>(tcx: TyCtxt<'tcx>, delegation_id: LocalDefId) -> Option> { let sig_id = tcx.hir_opt_delegation_sig_id(delegation_id).expect("Delegation must have sig_id"); let (caller_kind, callee_kind) = (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id)); @@ -302,14 +280,24 @@ fn get_delegation_self_ty<'tcx>(tcx: TyCtxt<'tcx>, delegation_id: LocalDefId) -> | (FnKind::AssocTrait, FnKind::AssocTrait) => { match create_self_position_kind(tcx, delegation_id, sig_id) { SelfPositionKind::None => None, - SelfPositionKind::AfterLifetimes(propagate_self_ty) => { - if propagate_self_ty { - Some(get_delegation_self_ty_or_err(tcx, delegation_id)) - } else { - // Both sig parent and child lifetimes are in included in this count. - let index = tcx.generics_of(delegation_id).own_counts().lifetimes; - Some(Ty::new_param(tcx, index as u32, kw::SelfUpper)) - } + SelfPositionKind::AfterLifetimes(propagation_kind) => { + Some(match propagation_kind { + Some(kind) => match kind { + DelegationSelfTyPropagationKind::SelfTy(self_ty_id) => { + let ctx = ItemCtxt::new(tcx, delegation_id); + ctx.lower_ty(tcx.hir_node(self_ty_id).expect_ty()) + } + DelegationSelfTyPropagationKind::SelfParam => { + let index = tcx.generics_of(delegation_id).own_counts().lifetimes; + Ty::new_param(tcx, index as u32, kw::SelfUpper) + } + }, + None => Ty::new_error_with_message( + tcx, + tcx.def_span(delegation_id), + "self propagation kind must be specified for `AfterLifetimes` variant", + ), + }) } SelfPositionKind::Zero => Some(Ty::new_param(tcx, 0, kw::SelfUpper)), } @@ -348,137 +336,69 @@ fn create_generic_args<'tcx>( sig_id: DefId, delegation_id: LocalDefId, mut parent_args: &[ty::GenericArg<'tcx>], - child_args: &[ty::GenericArg<'tcx>], + mut child_args: &[ty::GenericArg<'tcx>], ) -> Vec> { - let (caller_kind, callee_kind) = (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id)); - + let delegation_generics = tcx.generics_of(delegation_id); let delegation_args = ty::GenericArgs::identity_for_item(tcx, delegation_id); - let deleg_parent_args_without_self_count = - get_delegation_parent_args_count_without_self(tcx, delegation_id, sig_id); - - let delegation_generics = tcx.generics_of(delegation_id); let real_args_count = delegation_args.len() - delegation_generics.own_synthetic_params_count(); let synth_args = &delegation_args[real_args_count..]; - let delegation_args = &delegation_args[..real_args_count]; - - let args = match (caller_kind, callee_kind) { - (FnKind::Free, FnKind::Free) - | (FnKind::Free, FnKind::AssocTrait) - | (FnKind::AssocInherentImpl, FnKind::Free) - | (FnKind::AssocTrait, FnKind::Free) - | (FnKind::AssocTrait, FnKind::AssocTrait) => delegation_args, - (FnKind::AssocTraitImpl, FnKind::AssocTrait) => { - // Special case, as user specifies Trait args in trait impl header, we want to treat - // them as parent args. We always generate a function whose generics match - // child generics in trait. - let parent = tcx.local_parent(delegation_id); - parent_args = - tcx.impl_trait_header(parent).trait_ref.instantiate_identity().skip_norm_wip().args; - - assert!(child_args.is_empty(), "Child args can not be used in trait impl case"); - - tcx.mk_args(&delegation_args[delegation_generics.parent_count..]) - } - - (FnKind::AssocInherentImpl, FnKind::AssocTrait) => { - let self_ty = - tcx.type_of(tcx.local_parent(delegation_id)).instantiate_identity().skip_norm_wip(); + let mut delegation_parent_args = + &delegation_args[delegation_generics.has_self as usize..delegation_generics.parent_count]; - tcx.mk_args_from_iter( - std::iter::once(ty::GenericArg::from(self_ty)) - .chain(delegation_args.iter().copied()), - ) - } + let delegation_args = &delegation_args[delegation_generics.parent_count..]; - // For trait impl's `sig_id` is always equal to the corresponding trait method. - // For inherent methods delegation is not yet supported. - (FnKind::AssocTraitImpl, _) - | (_, FnKind::AssocTraitImpl) - | (_, FnKind::AssocInherentImpl) => unreachable!(), - }; + let kinds = (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id)); + if matches!(kinds, (FnKind::AssocTraitImpl, FnKind::AssocTrait)) { + // Special case, as user specifies Trait args in trait impl header, we want to treat + // them as parent args. We always generate a function whose generics match + // child generics in trait. + let parent = tcx.local_parent(delegation_id); - let mut new_args = vec![]; + parent_args = + tcx.impl_trait_header(parent).trait_ref.instantiate_identity().skip_norm_wip().args; - let self_pos_kind = create_self_position_kind(tcx, delegation_id, sig_id); - let mut lifetimes_end_pos; + child_args = + &delegation_args[delegation_args.len() - delegation_generics.own_params.len()..]; - if !parent_args.is_empty() { - let parent_args_lifetimes_count = - parent_args.iter().filter(|a| a.as_region().is_some()).count(); - - match self_pos_kind { - SelfPositionKind::AfterLifetimes { .. } => { - new_args.extend(&parent_args[1..1 + parent_args_lifetimes_count]); + delegation_parent_args = &[]; + } - lifetimes_end_pos = parent_args_lifetimes_count; + let self_type = get_delegation_self_ty(tcx, delegation_id).map(|t| t.into()); - new_args.push(parent_args[0]); + // Remove `Self` from parent args (it is always at the `0th` index) as it is + // added manually. + if self_type.is_some() && !parent_args.is_empty() { + parent_args = &parent_args[1..]; + } - new_args.extend(&parent_args[1 + parent_args_lifetimes_count..]); + let (zero_self, after_lifetimes_self) = + match create_self_position_kind(tcx, delegation_id, sig_id) { + SelfPositionKind::AfterLifetimes(_) => { + assert!(self_type.is_some()); + (None, self_type) } SelfPositionKind::Zero => { - lifetimes_end_pos = 1 /* Self */ + parent_args_lifetimes_count; - new_args.extend_from_slice(parent_args); - - for i in 0..deleg_parent_args_without_self_count { - new_args.insert(1 + i, args[1 + i]); - } - - lifetimes_end_pos += deleg_parent_args_without_self_count; + assert!(self_type.is_some()); + (self_type, None) } - // If we have parent args then we obtained them from trait, then self must be somewhere - SelfPositionKind::None => unreachable!(), + SelfPositionKind::None => (None, None), }; - } else { - let self_impact = matches!(self_pos_kind, SelfPositionKind::Zero) as usize; - - lifetimes_end_pos = self_impact - + deleg_parent_args_without_self_count - + &args[self_impact + deleg_parent_args_without_self_count..] - .iter() - .filter(|a| a.as_region().is_some()) - .count(); - - new_args.extend_from_slice(args); - - // Parent args are empty, then if we should propagate self ty (meaning Self generic - // param was not generated) then we should insert it, as it won't be in `args`. - if matches!(self_pos_kind, SelfPositionKind::AfterLifetimes(true)) { - new_args.insert( - lifetimes_end_pos, - ty::GenericArg::from(get_delegation_self_ty_or_err(tcx, delegation_id)), - ); - } - } - - if !child_args.is_empty() { - let child_lifetimes_count = child_args.iter().filter(|a| a.as_region().is_some()).count(); - - for i in 0..child_lifetimes_count { - new_args.insert(lifetimes_end_pos + i, child_args[i]); - } - new_args.extend_from_slice(&child_args[child_lifetimes_count..]); - } else if !parent_args.is_empty() { - let child_args = &delegation_args[delegation_generics.parent_count..]; - - let child_lifetimes_count = - child_args.iter().take_while(|a| a.as_region().is_some()).count(); - - for i in 0..child_lifetimes_count { - new_args.insert(lifetimes_end_pos + i, child_args[i]); - } - - // If self_ty is propagated it means that Self generic param was not generated. - let skip_self = matches!(self_pos_kind, SelfPositionKind::AfterLifetimes(false)); - new_args.extend(&child_args[child_lifetimes_count + skip_self as usize..]); - } - - new_args.extend(synth_args); - - new_args + let zero_self = zero_self.as_ref().into_iter(); + let after_lifetimes_self = after_lifetimes_self.as_ref().into_iter(); + + zero_self + .chain(delegation_parent_args) + .chain(parent_args.iter().filter(|a| a.as_region().is_some())) + .chain(child_args.iter().filter(|a| a.as_region().is_some())) + .chain(after_lifetimes_self) + .chain(parent_args.iter().filter(|a| a.as_region().is_none())) + .chain(child_args.iter().filter(|a| a.as_region().is_none())) + .chain(synth_args) + .copied() + .collect::>() } pub(crate) fn inherit_predicates_for_delegation_item<'tcx>( @@ -541,7 +461,10 @@ pub(crate) fn inherit_predicates_for_delegation_item<'tcx>( let (parent_args, child_args) = tcx.delegation_user_specified_args(def_id); let (folder, args) = create_folder_and_args(tcx, def_id, sig_id, parent_args, child_args); let self_pos_kind = create_self_position_kind(tcx, def_id, sig_id); - let filter_self_preds = matches!(self_pos_kind, SelfPositionKind::AfterLifetimes(true)); + let filter_self_preds = matches!( + self_pos_kind, + SelfPositionKind::AfterLifetimes(Some(DelegationSelfTyPropagationKind::SelfTy(..))) + ); let collector = PredicatesCollector { tcx, preds: vec![], args, folder, filter_self_preds }; let (parent, inh_kind) = get_parent_and_inheritance_kind(tcx, def_id, sig_id); @@ -640,18 +563,21 @@ pub(crate) fn delegation_user_specified_args<'tcx>( let ctx = ItemCtxt::new_for_delegation(tcx, delegation_id); let lowerer = ctx.lowerer(); + let parent_args = info + .parent_seg_id_for_sig + .and_then(get_segment) + .filter(|(_, def_id)| matches!(tcx.def_kind(*def_id), DefKind::Trait)) + .map(|(segment, def_id)| { + let self_ty = get_delegation_self_ty(tcx, delegation_id); - let parent_args = info.parent_args_segment_id.and_then(get_segment).map(|(segment, def_id)| { - let self_ty = get_delegation_self_ty(tcx, delegation_id); - - lowerer - .lower_generic_args_of_path(segment.ident.span, def_id, &[], segment, self_ty) - .0 - .as_slice() - }); + lowerer + .lower_generic_args_of_path(segment.ident.span, def_id, &[], segment, self_ty) + .0 + .as_slice() + }); let child_args = info - .child_args_segment_id + .child_seg_id_for_sig .and_then(get_segment) .filter(|(_, def_id)| matches!(tcx.def_kind(*def_id), DefKind::Fn | DefKind::AssocFn)) .map(|(segment, def_id)| { diff --git a/compiler/rustc_hir_analysis/src/diagnostics.rs b/compiler/rustc_hir_analysis/src/diagnostics.rs index 5997f16b42917..1bfc495071284 100644 --- a/compiler/rustc_hir_analysis/src/diagnostics.rs +++ b/compiler/rustc_hir_analysis/src/diagnostics.rs @@ -1582,14 +1582,6 @@ pub(crate) struct UnsupportedDelegation<'a> { pub callee_span: Span, } -#[derive(Diagnostic)] -#[diag("delegation self type is not specified")] -#[help("consider explicitly specifying self type: `reuse ::function`")] -pub(crate) struct DelegationSelfTypeNotSpecified { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag("inferred lifetimes are not allowed in delegations as we need to inherit signature")] pub(crate) struct ElidedLifetimesAreNotAllowedInDelegations { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index a26d84291e42d..0187a22d564cb 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -6,7 +6,7 @@ use rustc_errors::{ }; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; -use rustc_hir::{self as hir, GenericArg}; +use rustc_hir::{self as hir, DelegationInfo, GenericArg}; use rustc_middle::ty::{ self, GenericArgsRef, GenericParamDef, GenericParamDefKind, IsSuggestable, Ty, }; @@ -430,8 +430,17 @@ pub(crate) fn check_generic_arg_count( prohibit_assoc_item_constraint(cx, c, None); } - let explicit_late_bound = - prohibit_explicit_late_bound_lifetimes(cx, gen_params, gen_args, gen_pos); + let tcx = cx.tcx(); + let parent_def = tcx.hir_get_parent_item(seg.hir_id).def_id; + + // Suppress this warning for delegations as it is compiler generated and lifetimes are + // propagated while late-bound lifetimes may be present. + let explicit_late_bound = match tcx.hir_opt_delegation_info(parent_def) { + Some(DelegationInfo { child_seg_id, .. }) if seg.hir_id == *child_seg_id => { + ExplicitLateBound::No + } + _ => prohibit_explicit_late_bound_lifetimes(cx, gen_params, gen_args, gen_pos), + }; let mut invalid_args = vec![]; @@ -458,7 +467,7 @@ pub(crate) fn check_generic_arg_count( }; let reported = cx.dcx().emit_err(WrongNumberOfGenericArgs::new( - cx.tcx(), + tcx, gen_args_info, seg, gen_params, @@ -536,20 +545,19 @@ pub(crate) fn check_generic_arg_count( .map(|param| param.name) .collect(); if constraint_names == param_names { - let has_assoc_ty_with_same_name = - if let DefKind::Trait = cx.tcx().def_kind(def_id) { - gen_args.constraints.iter().any(|constraint| { - traits::supertrait_def_ids(cx.tcx(), def_id).any(|trait_did| { - cx.probe_trait_that_defines_assoc_item( - trait_did, - ty::AssocTag::Type, - constraint.ident, - ) - }) + let has_assoc_ty_with_same_name = if let DefKind::Trait = tcx.def_kind(def_id) { + gen_args.constraints.iter().any(|constraint| { + traits::supertrait_def_ids(tcx, def_id).any(|trait_did| { + cx.probe_trait_that_defines_assoc_item( + trait_did, + ty::AssocTag::Type, + constraint.ident, + ) }) - } else { - false - }; + }) + } else { + false + }; // We set this to true and delay emitting `WrongNumberOfGenericArgs` // to provide a succinct error for cases like issue #113073, // but only if when we don't have any assoc type with the same name with a @@ -573,7 +581,7 @@ pub(crate) fn check_generic_arg_count( let reported = gen_args.has_err().unwrap_or_else(|| { cx.dcx() .create_err(WrongNumberOfGenericArgs::new( - cx.tcx(), + tcx, gen_args_info, seg, gen_params, diff --git a/tests/pretty/delegation-self-rename.pp b/tests/pretty/delegation-self-rename.pp index 7f7afc403607b..526021c061178 100644 --- a/tests/pretty/delegation-self-rename.pp +++ b/tests/pretty/delegation-self-rename.pp @@ -19,15 +19,18 @@ #[attr = Inline(Hint)] fn foo<'a, Self, A, const B: _, const B2: _, T, U, impl FnOnce() -> usize>(self: _, arg1: _) -> _ where - 'a:'a { Trait::<'a, A, B>::foo::(self, arg1) } + 'a:'a { >::foo::(self, arg1) } #[attr = Inline(Hint)] fn bar usize>(self: _, arg1: _) - -> _ { Trait::<'static, (), true>::foo::(self, arg1) } + -> + _ { + >::foo::(self, arg1) +} #[attr = Inline(Hint)] fn foo2<'a, This, A, const B: _, const B2: _, T, U, impl FnOnce() -> usize>(arg0: _, arg1: _) -> _ where - 'a:'a { foo::(arg0, arg1) } + 'a:'a { foo::<'a, This, A, B, B2, T, U>(arg0, arg1) } #[attr = Inline(Hint)] fn bar2 usize>(arg0: _, arg1: _) -> _ { bar::(arg0, arg1) } @@ -36,7 +39,7 @@ #[attr = Inline(Hint)] fn foo3<'a, This, A, const B: _, const B2: _, T, U, impl FnOnce() -> usize>(arg0: _, arg1: _) -> _ where - 'a:'a { foo2::(arg0, arg1) } + 'a:'a { foo2::<'a, This, A, B, B2, T, U>(arg0, arg1) } #[attr = Inline(Hint)] fn bar3 usize>(arg0: _, arg1: _) -> _ { bar2::(arg0, arg1) } @@ -47,7 +50,7 @@ #[attr = Inline(Hint)] fn foo4<'a, This, A, const B: _, const B2: _, T, U, impl FnOnce() -> usize>(arg0: _, arg1: _) -> _ where - 'a:'a { <() as Trait2>::foo3::(arg0, arg1) } + 'a:'a { <() as Trait2>::foo3::<'a, This, A, B, B2, T, U>(arg0, arg1) } #[attr = Inline(Hint)] fn bar4 usize>(arg0: _, arg1: _) -> _ { <() as Trait2>::bar3::(arg0, arg1) } diff --git a/tests/ui/delegation/generics/free-fn-to-trait-infer.rs b/tests/ui/delegation/generics/free-fn-to-trait-infer.rs deleted file mode 100644 index 0a0665b752681..0000000000000 --- a/tests/ui/delegation/generics/free-fn-to-trait-infer.rs +++ /dev/null @@ -1,19 +0,0 @@ -//@ compile-flags: -Z deduplicate-diagnostics=yes - -#![feature(fn_delegation)] - -trait Trait { - fn foo(&self, _: U, _: T) {} -} - -impl Trait for u8 {} - -reuse Trait::<_>::foo:: as generic_arguments1; -//~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions -reuse >::foo as generic_arguments2; -//~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions -reuse <_ as Trait<_>>::foo as generic_arguments3; -//~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions -//~| ERROR the placeholder `_` is not allowed within types on item signatures for functions - -fn main() {} diff --git a/tests/ui/delegation/generics/free-fn-to-trait-infer.stderr b/tests/ui/delegation/generics/free-fn-to-trait-infer.stderr deleted file mode 100644 index f1e9231cc4050..0000000000000 --- a/tests/ui/delegation/generics/free-fn-to-trait-infer.stderr +++ /dev/null @@ -1,27 +0,0 @@ -error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/free-fn-to-trait-infer.rs:11:15 - | -LL | reuse Trait::<_>::foo:: as generic_arguments1; - | ^ not allowed in type signatures - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/free-fn-to-trait-infer.rs:13:20 - | -LL | reuse >::foo as generic_arguments2; - | ^ not allowed in type signatures - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/free-fn-to-trait-infer.rs:15:8 - | -LL | reuse <_ as Trait<_>>::foo as generic_arguments3; - | ^ not allowed in type signatures - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/free-fn-to-trait-infer.rs:15:19 - | -LL | reuse <_ as Trait<_>>::foo as generic_arguments3; - | ^ not allowed in type signatures - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0121`. diff --git a/tests/ui/delegation/generics/free-to-trait-static-reuse.rs b/tests/ui/delegation/generics/free-to-trait-static-reuse.rs index e3d0bdbc7e9b0..3f52209ded317 100644 --- a/tests/ui/delegation/generics/free-to-trait-static-reuse.rs +++ b/tests/ui/delegation/generics/free-to-trait-static-reuse.rs @@ -20,17 +20,9 @@ reuse ::static_method as bar { self + 1 } reuse ::static_method::<'static, Vec, false> as bar2; reuse Trait::static_method as error { self - 123 } -//~^ ERROR: type annotations needed -//~| ERROR: delegation self type is not specified reuse Trait::<'static, i32, 123>::static_method as error2; -//~^ ERROR: type annotations needed -//~| ERROR: delegation self type is not specified reuse Trait::<'static, i32, 123>::static_method::<'static, String, false> as error3; -//~^ ERROR: type annotations needed -//~| ERROR: delegation self type is not specified reuse Trait::static_method::<'static, Vec, false> as error4 { self + 4 } -//~^ ERROR: type annotations needed -//~| ERROR: delegation self type is not specified reuse ::static_method as error5; //~^ ERROR: the trait bound `String: Trait<'a, T, X>` is not satisfied diff --git a/tests/ui/delegation/generics/free-to-trait-static-reuse.stderr b/tests/ui/delegation/generics/free-to-trait-static-reuse.stderr index 8d87b9376acd4..04f5e60044cdc 100644 --- a/tests/ui/delegation/generics/free-to-trait-static-reuse.stderr +++ b/tests/ui/delegation/generics/free-to-trait-static-reuse.stderr @@ -1,43 +1,11 @@ -error: delegation self type is not specified - --> $DIR/free-to-trait-static-reuse.rs:22:14 - | -LL | reuse Trait::static_method as error { self - 123 } - | ^^^^^^^^^^^^^ - | - = help: consider explicitly specifying self type: `reuse ::function` - -error: delegation self type is not specified - --> $DIR/free-to-trait-static-reuse.rs:25:35 - | -LL | reuse Trait::<'static, i32, 123>::static_method as error2; - | ^^^^^^^^^^^^^ - | - = help: consider explicitly specifying self type: `reuse ::function` - -error: delegation self type is not specified - --> $DIR/free-to-trait-static-reuse.rs:28:35 - | -LL | reuse Trait::<'static, i32, 123>::static_method::<'static, String, false> as error3; - | ^^^^^^^^^^^^^ - | - = help: consider explicitly specifying self type: `reuse ::function` - -error: delegation self type is not specified - --> $DIR/free-to-trait-static-reuse.rs:31:14 - | -LL | reuse Trait::static_method::<'static, Vec, false> as error4 { self + 4 } - | ^^^^^^^^^^^^^ - | - = help: consider explicitly specifying self type: `reuse ::function` - error[E0277]: the trait bound `Struct: Bound` is not satisfied - --> $DIR/free-to-trait-static-reuse.rs:39:49 + --> $DIR/free-to-trait-static-reuse.rs:31:49 | LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {} | ^^^^^^ unsatisfied trait bound | help: the trait `Bound` is not implemented for `Struct` - --> $DIR/free-to-trait-static-reuse.rs:38:1 + --> $DIR/free-to-trait-static-reuse.rs:30:1 | LL | struct Struct; | ^^^^^^^^^^^^^ @@ -55,68 +23,8 @@ LL | where LL | Self: Bound, | ^^^^^^^^ required by this bound in `Trait` -error[E0283]: type annotations needed - --> $DIR/free-to-trait-static-reuse.rs:22:14 - | -LL | reuse Trait::static_method as error { self - 123 } - | ^^^^^^^^^^^^^ cannot infer type - | -note: multiple `impl`s satisfying `_: Trait<'a, T, X>` found - --> $DIR/free-to-trait-static-reuse.rs:14:1 - | -LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0283]: type annotations needed - --> $DIR/free-to-trait-static-reuse.rs:25:35 - | -LL | reuse Trait::<'static, i32, 123>::static_method as error2; - | ^^^^^^^^^^^^^ cannot infer type - | -note: multiple `impl`s satisfying `_: Trait<'static, i32, 123>` found - --> $DIR/free-to-trait-static-reuse.rs:14:1 - | -LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0283]: type annotations needed - --> $DIR/free-to-trait-static-reuse.rs:28:35 - | -LL | reuse Trait::<'static, i32, 123>::static_method::<'static, String, false> as error3; - | ^^^^^^^^^^^^^ cannot infer type - | -note: multiple `impl`s satisfying `_: Trait<'static, i32, 123>` found - --> $DIR/free-to-trait-static-reuse.rs:14:1 - | -LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0283]: type annotations needed - --> $DIR/free-to-trait-static-reuse.rs:31:14 - | -LL | reuse Trait::static_method::<'static, Vec, false> as error4 { self + 4 } - | ^^^^^^^^^^^^^ cannot infer type - | -note: multiple `impl`s satisfying `_: Trait<'a, T, X>` found - --> $DIR/free-to-trait-static-reuse.rs:14:1 - | -LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0277]: the trait bound `String: Trait<'a, T, X>` is not satisfied - --> $DIR/free-to-trait-static-reuse.rs:35:8 + --> $DIR/free-to-trait-static-reuse.rs:27:8 | LL | reuse ::static_method as error5; | ^^^^^^ the trait `Trait<'a, T, X>` is not implemented for `String` @@ -131,13 +39,13 @@ LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Struct` error[E0277]: the trait bound `Struct: Bound` is not satisfied - --> $DIR/free-to-trait-static-reuse.rs:42:8 + --> $DIR/free-to-trait-static-reuse.rs:34:8 | LL | reuse ::static_method as error6; | ^^^^^^ unsatisfied trait bound | help: the trait `Bound` is not implemented for `Struct` - --> $DIR/free-to-trait-static-reuse.rs:38:1 + --> $DIR/free-to-trait-static-reuse.rs:30:1 | LL | struct Struct; | ^^^^^^^^^^^^^ @@ -155,7 +63,6 @@ LL | { LL | fn static_method<'c: 'c, U, const B: bool>(x: usize) {} | ------------- required by a bound in this associated function -error: aborting due to 11 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0277, E0283. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/delegation/generics/generics-gen-args-errors.rs b/tests/ui/delegation/generics/generics-gen-args-errors.rs index 4e1ac0a5e4176..6a8d1674fe184 100644 --- a/tests/ui/delegation/generics/generics-gen-args-errors.rs +++ b/tests/ui/delegation/generics/generics-gen-args-errors.rs @@ -44,8 +44,6 @@ mod test_2 { fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} reuse foo::<> as bar1; - //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions - //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature reuse foo:: as bar2; //~^ ERROR: function takes 3 generic arguments but 2 generic arguments were supplied @@ -54,9 +52,9 @@ mod test_2 { reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3; //~^ ERROR: use of undeclared lifetime name `'asdasd` - //~| ERROR: function takes 2 lifetime arguments but 5 lifetime arguments were supplied - //~| ERROR: function takes 3 generic arguments but 2 generic arguments were supplied - //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + //~| ERROR: function takes 2 lifetime arguments but 6 lifetime arguments were supplied + //~| ERROR: function takes 3 generic arguments but 1 generic argument was supplied + //~| ERROR: wrong infer used: expected '_, found: _ reuse foo:: as bar4; //~^ ERROR: cannot find type `asdasd` in this scope @@ -131,12 +129,13 @@ mod test_3 { //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; - //~^ ERROR: trait takes 3 lifetime arguments but 1 lifetime argument was supplied - //~| ERROR: trait takes 2 generic arguments but 5 generic arguments were supplied + //~^ ERROR: trait takes 3 lifetime arguments but 2 lifetime arguments were supplied + //~| ERROR: trait takes 2 generic arguments but 4 generic arguments were supplied //~| ERROR: method takes 2 generic arguments but 5 generic arguments were supplied //~| ERROR: method takes 1 lifetime argument but 0 lifetime arguments were supplied //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + //~| ERROR: wrong infer used: expected '_, found: _ } fn main() {} diff --git a/tests/ui/delegation/generics/generics-gen-args-errors.stderr b/tests/ui/delegation/generics/generics-gen-args-errors.stderr index 7aa1766dfef89..c08e23e6c016a 100644 --- a/tests/ui/delegation/generics/generics-gen-args-errors.stderr +++ b/tests/ui/delegation/generics/generics-gen-args-errors.stderr @@ -38,7 +38,7 @@ LL | reuse foo:: as xd; = note: nested items are independent from their parent item for everything except for privacy and name resolution error[E0261]: use of undeclared lifetime name `'asdasd` - --> $DIR/generics-gen-args-errors.rs:55:29 + --> $DIR/generics-gen-args-errors.rs:53:29 | LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3; | ^^^^^^^ undeclared lifetime @@ -49,7 +49,7 @@ LL | reuse foo'asdasd, ::<'static, _, 'asdasd, 'static, 'static, 'static, _> | ++++++++ error[E0261]: use of undeclared lifetime name `'a` - --> $DIR/generics-gen-args-errors.rs:77:50 + --> $DIR/generics-gen-args-errors.rs:75:50 | LL | reuse foo::<"asdasd", asd, "askdn", 'static, 'a> as bar7; | ^^ undeclared lifetime @@ -103,65 +103,77 @@ LL | fn check() { | +++++ error[E0425]: cannot find type `asdasd` in this scope - --> $DIR/generics-gen-args-errors.rs:61:39 + --> $DIR/generics-gen-args-errors.rs:59:39 | LL | reuse foo:: as bar4; | ^^^^^^ not found in this scope error[E0425]: cannot find type `asd` in this scope - --> $DIR/generics-gen-args-errors.rs:71:22 + --> $DIR/generics-gen-args-errors.rs:69:22 | LL | reuse foo::<1, 2,asd,String, { let x = 0; }> as bar6; | ^^^ not found in this scope error[E0425]: cannot find type `asd` in this scope - --> $DIR/generics-gen-args-errors.rs:77:27 + --> $DIR/generics-gen-args-errors.rs:75:27 | LL | reuse foo::<"asdasd", asd, "askdn", 'static, 'a> as bar7; | ^^^ not found in this scope error[E0425]: cannot find type `asd` in this scope - --> $DIR/generics-gen-args-errors.rs:94:19 + --> $DIR/generics-gen-args-errors.rs:92:19 | LL | reuse Trait::::foo as bar1; | ^^^ not found in this scope error[E0425]: cannot find type `asd` in this scope - --> $DIR/generics-gen-args-errors.rs:94:24 + --> $DIR/generics-gen-args-errors.rs:92:24 | LL | reuse Trait::::foo as bar1; | ^^^ not found in this scope error[E0425]: cannot find type `asd` in this scope - --> $DIR/generics-gen-args-errors.rs:94:29 + --> $DIR/generics-gen-args-errors.rs:92:29 | LL | reuse Trait::::foo as bar1; | ^^^ not found in this scope error[E0425]: cannot find type `asd` in this scope - --> $DIR/generics-gen-args-errors.rs:94:34 + --> $DIR/generics-gen-args-errors.rs:92:34 | LL | reuse Trait::::foo as bar1; | ^^^ not found in this scope error[E0425]: cannot find type `asd` in this scope - --> $DIR/generics-gen-args-errors.rs:94:39 + --> $DIR/generics-gen-args-errors.rs:92:39 | LL | reuse Trait::::foo as bar1; | ^^^ not found in this scope error[E0425]: cannot find type `asdasa` in this scope - --> $DIR/generics-gen-args-errors.rs:94:44 + --> $DIR/generics-gen-args-errors.rs:92:44 | LL | reuse Trait::::foo as bar1; | ^^^^^^ not found in this scope error[E0425]: cannot find type `DDDD` in this scope - --> $DIR/generics-gen-args-errors.rs:124:34 + --> $DIR/generics-gen-args-errors.rs:122:34 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | ^^^^ not found in this scope +error: wrong infer used: expected '_, found: _ + --> $DIR/generics-gen-args-errors.rs:53:26 + | +LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3; + | ^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/generics-gen-args-errors.rs:131:33 + | +LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; + | ^ + error[E0107]: function takes 2 lifetime arguments but 0 lifetime arguments were supplied --> $DIR/generics-gen-args-errors.rs:33:15 | @@ -184,20 +196,8 @@ error: inferred lifetimes are not allowed in delegations as we need to inherit s LL | reuse foo:: as xd; | ^^^ -error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:46:11 - | -LL | reuse foo::<> as bar1; - | ^^^ - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/generics-gen-args-errors.rs:46:11 - | -LL | reuse foo::<> as bar1; - | ^^^ not allowed in type signatures - error[E0107]: function takes 2 lifetime arguments but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:50:11 + --> $DIR/generics-gen-args-errors.rs:48:11 | LL | reuse foo:: as bar2; | ^^^ expected 2 lifetime arguments @@ -213,7 +213,7 @@ LL | reuse foo::<'a, 'b, String, String> as bar2; | +++++++ error[E0107]: function takes 3 generic arguments but 2 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:50:11 + --> $DIR/generics-gen-args-errors.rs:48:11 | LL | reuse foo:: as bar2; | ^^^ ------ ------ supplied 2 generic arguments @@ -231,16 +231,16 @@ LL | reuse foo:: as bar2; | +++ error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:50:11 + --> $DIR/generics-gen-args-errors.rs:48:11 | LL | reuse foo:: as bar2; | ^^^ -error[E0107]: function takes 2 lifetime arguments but 5 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:55:11 +error[E0107]: function takes 2 lifetime arguments but 6 lifetime arguments were supplied + --> $DIR/generics-gen-args-errors.rs:53:11 | LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3; - | ^^^ --------------------------- help: remove the lifetime arguments + | ^^^------------------------------------------------- help: remove the lifetime arguments | | | expected 2 lifetime arguments | @@ -250,30 +250,24 @@ note: function defined here, with 2 lifetime parameters: `'a`, `'b` LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} | ^^^ -- -- -error[E0107]: function takes 3 generic arguments but 2 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:55:11 +error[E0107]: function takes 3 generic arguments but 1 generic argument was supplied + --> $DIR/generics-gen-args-errors.rs:53:11 | LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3; - | ^^^ expected 3 generic arguments ------- - supplied 2 generic arguments + | ^^^ expected 3 generic arguments - supplied 1 generic argument | note: function defined here, with 3 generic parameters: `T`, `U`, `N` --> $DIR/generics-gen-args-errors.rs:44:8 | LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} | ^^^ - - -------------- -help: add missing generic argument +help: add missing generic arguments | -LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _, N> as bar3; - | +++ - -error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:55:11 - | -LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3; - | ^^^ +LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _, U, N> as bar3; + | ++++++ error[E0107]: function takes 2 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/generics-gen-args-errors.rs:61:11 + --> $DIR/generics-gen-args-errors.rs:59:11 | LL | reuse foo:: as bar4; | ^^^ ------ supplied 1 lifetime argument @@ -291,13 +285,13 @@ LL | reuse foo:: as bar4; | +++++++++ error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:61:11 + --> $DIR/generics-gen-args-errors.rs:59:11 | LL | reuse foo:: as bar4; | ^^^ error[E0107]: function takes 2 lifetime arguments but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:66:11 + --> $DIR/generics-gen-args-errors.rs:64:11 | LL | reuse foo::<1, 2, _, 4, 5, _> as bar5; | ^^^ expected 2 lifetime arguments @@ -313,10 +307,10 @@ LL | reuse foo::<'a, 'b, 1, 2, _, 4, 5, _> as bar5; | +++++++ error[E0107]: function takes 3 generic arguments but 6 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:66:11 + --> $DIR/generics-gen-args-errors.rs:64:11 | LL | reuse foo::<1, 2, _, 4, 5, _> as bar5; - | ^^^ --------- help: remove the unnecessary generic arguments + | ^^^------------------- help: remove the unnecessary generic arguments | | | expected 3 generic arguments | @@ -327,13 +321,13 @@ LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} | ^^^ - - -------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:66:11 + --> $DIR/generics-gen-args-errors.rs:64:11 | LL | reuse foo::<1, 2, _, 4, 5, _> as bar5; | ^^^ error[E0107]: function takes 2 lifetime arguments but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:71:11 + --> $DIR/generics-gen-args-errors.rs:69:11 | LL | reuse foo::<1, 2,asd,String, { let x = 0; }> as bar6; | ^^^ expected 2 lifetime arguments @@ -349,7 +343,7 @@ LL | reuse foo::<'a, 'b, 1, 2,asd,String, { let x = 0; }> as bar6; | +++++++ error[E0107]: function takes 3 generic arguments but 5 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:71:11 + --> $DIR/generics-gen-args-errors.rs:69:11 | LL | reuse foo::<1, 2,asd,String, { let x = 0; }> as bar6; | ^^^ ----------------------- help: remove the unnecessary generic arguments @@ -363,25 +357,25 @@ LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} | ^^^ - - -------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:71:11 + --> $DIR/generics-gen-args-errors.rs:69:11 | LL | reuse foo::<1, 2,asd,String, { let x = 0; }> as bar6; | ^^^ error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:77:11 + --> $DIR/generics-gen-args-errors.rs:75:11 | LL | reuse foo::<"asdasd", asd, "askdn", 'static, 'a> as bar7; | ^^^ error[E0747]: constant provided when a type was expected - --> $DIR/generics-gen-args-errors.rs:77:17 + --> $DIR/generics-gen-args-errors.rs:75:17 | LL | reuse foo::<"asdasd", asd, "askdn", 'static, 'a> as bar7; | ^^^^^^^^ error[E0107]: function takes 2 lifetime arguments but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:83:11 + --> $DIR/generics-gen-args-errors.rs:81:11 | LL | reuse foo::<{}, {}, {}> as bar8; | ^^^ expected 2 lifetime arguments @@ -397,19 +391,19 @@ LL | reuse foo::<'a, 'b, {}, {}, {}> as bar8; | +++++++ error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:83:11 + --> $DIR/generics-gen-args-errors.rs:81:11 | LL | reuse foo::<{}, {}, {}> as bar8; | ^^^ error[E0107]: trait takes 3 lifetime arguments but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:94:11 + --> $DIR/generics-gen-args-errors.rs:92:11 | LL | reuse Trait::::foo as bar1; | ^^^^^ expected 3 lifetime arguments | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ -- -- -- @@ -419,7 +413,7 @@ LL | reuse Trait::<'b, 'c, 'a, asd, asd, asd, asd, asd, asdasa>::foo as bar1 | +++++++++++ error[E0107]: trait takes 2 generic arguments but 6 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:94:11 + --> $DIR/generics-gen-args-errors.rs:92:11 | LL | reuse Trait::::foo as bar1; | ^^^^^ ----------------------- help: remove the unnecessary generic arguments @@ -427,19 +421,19 @@ LL | reuse Trait::::foo as bar1; | expected 2 generic arguments | note: trait defined here, with 2 generic parameters: `T`, `N` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ - -------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:94:11 + --> $DIR/generics-gen-args-errors.rs:92:11 | LL | reuse Trait::::foo as bar1; | ^^^^^ error[E0107]: trait takes 3 lifetime arguments but 2 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:105:11 + --> $DIR/generics-gen-args-errors.rs:103:11 | LL | reuse Trait::<'static, 'static>::foo as bar2; | ^^^^^ ------- ------- supplied 2 lifetime arguments @@ -447,7 +441,7 @@ LL | reuse Trait::<'static, 'static>::foo as bar2; | expected 3 lifetime arguments | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ -- -- -- @@ -457,25 +451,25 @@ LL | reuse Trait::<'static, 'static, 'static>::foo as bar2; | +++++++++ error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:105:11 + --> $DIR/generics-gen-args-errors.rs:103:11 | LL | reuse Trait::<'static, 'static>::foo as bar2; | ^^^^^ error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/generics-gen-args-errors.rs:105:11 + --> $DIR/generics-gen-args-errors.rs:103:11 | LL | reuse Trait::<'static, 'static>::foo as bar2; | ^^^^^ not allowed in type signatures error[E0107]: trait takes 3 lifetime arguments but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:109:11 + --> $DIR/generics-gen-args-errors.rs:107:11 | LL | reuse Trait::<1, 2, 3, 4, 5>::foo as bar3; | ^^^^^ expected 3 lifetime arguments | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ -- -- -- @@ -485,7 +479,7 @@ LL | reuse Trait::<'b, 'c, 'a, 1, 2, 3, 4, 5>::foo as bar3; | +++++++++++ error[E0107]: trait takes 2 generic arguments but 5 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:109:11 + --> $DIR/generics-gen-args-errors.rs:107:11 | LL | reuse Trait::<1, 2, 3, 4, 5>::foo as bar3; | ^^^^^ --------- help: remove the unnecessary generic arguments @@ -493,25 +487,25 @@ LL | reuse Trait::<1, 2, 3, 4, 5>::foo as bar3; | expected 2 generic arguments | note: trait defined here, with 2 generic parameters: `T`, `N` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ - -------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:109:11 + --> $DIR/generics-gen-args-errors.rs:107:11 | LL | reuse Trait::<1, 2, 3, 4, 5>::foo as bar3; | ^^^^^ error[E0107]: trait takes 3 lifetime arguments but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:114:11 + --> $DIR/generics-gen-args-errors.rs:112:11 | LL | reuse Trait::<1, 2, true>::foo as bar4; | ^^^^^ expected 3 lifetime arguments | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ -- -- -- @@ -521,7 +515,7 @@ LL | reuse Trait::<'b, 'c, 'a, 1, 2, true>::foo as bar4; | +++++++++++ error[E0107]: trait takes 2 generic arguments but 3 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:114:11 + --> $DIR/generics-gen-args-errors.rs:112:11 | LL | reuse Trait::<1, 2, true>::foo as bar4; | ^^^^^ ------ help: remove the unnecessary generic argument @@ -529,19 +523,19 @@ LL | reuse Trait::<1, 2, true>::foo as bar4; | expected 2 generic arguments | note: trait defined here, with 2 generic parameters: `T`, `N` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ - -------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:114:11 + --> $DIR/generics-gen-args-errors.rs:112:11 | LL | reuse Trait::<1, 2, true>::foo as bar4; | ^^^^^ error[E0107]: trait takes 3 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/generics-gen-args-errors.rs:119:11 + --> $DIR/generics-gen-args-errors.rs:117:11 | LL | reuse Trait::<'static>::foo as bar5; | ^^^^^ ------- supplied 1 lifetime argument @@ -549,7 +543,7 @@ LL | reuse Trait::<'static>::foo as bar5; | expected 3 lifetime arguments | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ -- -- -- @@ -559,19 +553,19 @@ LL | reuse Trait::<'static, 'static, 'static>::foo as bar5; | ++++++++++++++++++ error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:119:11 + --> $DIR/generics-gen-args-errors.rs:117:11 | LL | reuse Trait::<'static>::foo as bar5; | ^^^^^ error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/generics-gen-args-errors.rs:119:11 + --> $DIR/generics-gen-args-errors.rs:117:11 | LL | reuse Trait::<'static>::foo as bar5; | ^^^^^ not allowed in type signatures error[E0107]: trait takes 3 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/generics-gen-args-errors.rs:124:11 + --> $DIR/generics-gen-args-errors.rs:122:11 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | ^^^^^ - supplied 1 lifetime argument @@ -579,7 +573,7 @@ LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | expected 3 lifetime arguments | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ -- -- -- @@ -589,7 +583,7 @@ LL | reuse Trait::<1, 'static, 'static, 2, 'static, DDDD>::foo::<1, 2, 3, 4, | ++++++++++++++++++ error[E0107]: trait takes 2 generic arguments but 3 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:124:11 + --> $DIR/generics-gen-args-errors.rs:122:11 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | ^^^^^ --------------- help: remove the unnecessary generic argument @@ -597,25 +591,25 @@ LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | expected 2 generic arguments | note: trait defined here, with 2 generic parameters: `T`, `N` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ - -------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:124:11 + --> $DIR/generics-gen-args-errors.rs:122:11 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | ^^^^^ error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:124:41 + --> $DIR/generics-gen-args-errors.rs:122:41 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | ^^^ expected 1 lifetime argument | note: method defined here, with 1 lifetime parameter: `'d` - --> $DIR/generics-gen-args-errors.rs:91:12 + --> $DIR/generics-gen-args-errors.rs:89:12 | LL | fn foo<'d: 'd, U, const M: bool>(self) {} | ^^^ -- @@ -625,7 +619,7 @@ LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<'d, 1, 2, 3, 4, 5, 6> as bar6 | +++ error[E0107]: method takes 2 generic arguments but 6 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:124:41 + --> $DIR/generics-gen-args-errors.rs:122:41 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | ^^^ ------------ help: remove the unnecessary generic arguments @@ -633,73 +627,73 @@ LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | expected 2 generic arguments | note: method defined here, with 2 generic parameters: `U`, `M` - --> $DIR/generics-gen-args-errors.rs:91:12 + --> $DIR/generics-gen-args-errors.rs:89:12 | LL | fn foo<'d: 'd, U, const M: bool>(self) {} | ^^^ - ------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:124:41 + --> $DIR/generics-gen-args-errors.rs:122:41 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | ^^^ -error[E0107]: trait takes 3 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/generics-gen-args-errors.rs:133:11 +error[E0107]: trait takes 3 lifetime arguments but 2 lifetime arguments were supplied + --> $DIR/generics-gen-args-errors.rs:131:11 | LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; - | ^^^^^ ----- supplied 1 lifetime argument + | ^^^^^ ----- ----- supplied 2 lifetime arguments | | | expected 3 lifetime arguments | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ -- -- -- -help: add missing lifetime arguments +help: add missing lifetime argument | -LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; - | ++++++++++++++++++ +LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; + | ++++ -error[E0107]: trait takes 2 generic arguments but 5 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:133:11 +error[E0107]: trait takes 2 generic arguments but 4 generic arguments were supplied + --> $DIR/generics-gen-args-errors.rs:131:11 | LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; - | ^^^^^ --- help: remove the unnecessary generic argument + | ^^^^^ ------------------------- help: remove the unnecessary generic arguments | | | expected 2 generic arguments | note: trait defined here, with 2 generic parameters: `T`, `N` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ - -------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:133:11 + --> $DIR/generics-gen-args-errors.rs:131:11 | LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; | ^^^^^ error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:133:59 + --> $DIR/generics-gen-args-errors.rs:131:59 | LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; | ^^^ expected 1 lifetime argument | note: method defined here, with 1 lifetime parameter: `'d` - --> $DIR/generics-gen-args-errors.rs:91:12 + --> $DIR/generics-gen-args-errors.rs:89:12 | LL | fn foo<'d: 'd, U, const M: bool>(self) {} | ^^^ -- help: add missing lifetime argument | -LL | reuse Trait::::foo::<'d, 1, 2, 3, _, 6> as bar7; +LL | reuse Trait::::foo::<'a, 1, 2, 3, _, 6> as bar7; | +++ error[E0107]: method takes 2 generic arguments but 5 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:133:59 + --> $DIR/generics-gen-args-errors.rs:131:59 | LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; | ^^^ --------- help: remove the unnecessary generic arguments @@ -707,13 +701,13 @@ LL | reuse Trait::::foo::<1, 2, 3, _, | expected 2 generic arguments | note: method defined here, with 2 generic parameters: `U`, `M` - --> $DIR/generics-gen-args-errors.rs:91:12 + --> $DIR/generics-gen-args-errors.rs:89:12 | LL | fn foo<'d: 'd, U, const M: bool>(self) {} | ^^^ - ------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:133:59 + --> $DIR/generics-gen-args-errors.rs:131:59 | LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; | ^^^ @@ -789,12 +783,12 @@ LL | reuse foo:: as xd; | + + error[E0747]: constant provided when a type was expected - --> $DIR/generics-gen-args-errors.rs:83:17 + --> $DIR/generics-gen-args-errors.rs:81:17 | LL | reuse foo::<{}, {}, {}> as bar8; | ^^ -error: aborting due to 75 previous errors +error: aborting due to 74 previous errors Some errors have detailed explanations: E0107, E0121, E0261, E0401, E0423, E0425, E0747. For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/delegation/generics/infers.rs b/tests/ui/delegation/generics/infers.rs new file mode 100644 index 0000000000000..d9205f510a7b4 --- /dev/null +++ b/tests/ui/delegation/generics/infers.rs @@ -0,0 +1,356 @@ +//@ compile-flags: -Z deduplicate-diagnostics=yes + +#![feature(fn_delegation)] + +// Some interesting cases: +mod selected_tests { + mod different_infers { + fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + + // Should differentiate between lifetime and types/consts infers. + reuse foo::<_, '_, '_, '_> as bar; + //~^ ERROR: wrong infer used: expected '_, found: _ + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + } + + mod self_type { + trait Trait<'a, X> { + fn method<'b: 'b, const M: usize>(&self) {} + fn r#static<'b, Y, const B: bool>() {} + } + + impl<'a, X> Trait<'a, X> for () {} + + reuse Trait::<'_, _>::method::<'_, _> as foo; + + reuse <_ as Trait<'_, _>>::method::<'_, _> as foo1; + reuse <() as Trait<'_, _>>::method::<'_, _> as foo2; + + reuse <_ as Trait<'_, _>>::r#static::<_, _> as foo3; + reuse <() as Trait<'_, _>>::r#static::<_, _> as foo4; + + reuse Trait::<'_, _>::r#static::<_, _> as foo5; + } + + mod late_bound_lifetimes { + fn foo<'a, 'b, 'c: 'c, 'd>(_: &'a &'b &'c &'d ()) {} + + // 'c corresponds to infer. + reuse foo::<'_> as foo1; + + // Only 'c is generated in desugaring, second infer remains just infer in call path. + reuse foo::<'_, '_> as foo2; + //~^ ERROR: function takes 1 lifetime argument but 2 lifetime arguments were supplied + + reuse foo as foo3; + reuse foo::<'static> as foo4; + } + + mod non_angle_bracketed_args { + fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + + reuse foo::('_, _, _, _) as bar; + //~^ ERROR: lifetimes must be followed by `+` to form a trait object type + //~| ERROR: at least one trait is required for an object type + //~| ERROR: parenthesized type parameters may only be used with a `Fn` trait [E0214] + //~| ERROR: function takes 1 lifetime argument but 0 lifetime arguments were supplied [E0107] + //~| ERROR: function takes 3 generic arguments but 4 generic arguments were supplied [E0107] + //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + //~| ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + } +} + +// All other stuff: +mod legacy_tests { + trait Trait { + fn foo(&self, _: U, _: T) {} + } + + impl Trait for u8 {} + + reuse Trait::<_>::foo:: as generic_arguments1; + reuse >::foo as generic_arguments2; + reuse <_ as Trait<_>>::foo as generic_arguments3; +} + +mod free_to_free { + fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + + reuse foo::<> as foo1; + reuse foo::<'_, _, _, _> as foo2; + reuse foo::<'static, String, _, _> as foo3; + reuse foo::<'_, _, 123, _> as foo4; + + reuse foo::<'_, '_, '_, _, _, _,> as foo5; + //~^ ERROR: function takes 3 generic arguments but 5 generic arguments were supplied + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + //~^ ERROR: function takes 3 generic arguments but 6 generic arguments were supplied [E0107] + //~| ERROR: function takes 1 lifetime argument but 3 lifetime arguments were supplied + //~| ERROR: wrong infer used: expected '_, found: _ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse foo::<_, '_, _, _> as foo7; + //~^ ERROR: wrong infer used: expected '_, found: _ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse foo::<'_, '_, '_, '_> as foo8; + //~^ ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse foo::<_> as foo9; + //~^ ERROR: function takes 3 generic arguments but 0 generic arguments were supplied + //~| ERROR: wrong infer used: expected '_, found: _ + + reuse foo::, _, _, ()> as foo10; + //~^ ERROR: function takes 1 lifetime argument but 0 lifetime arguments were supplied [E0107] + //~| ERROR: function takes 3 generic arguments but 4 generic arguments were supplied [E0107] + //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + //~| ERROR: struct takes 0 lifetime arguments but 1 lifetime argument was supplied [E0107] + //~| ERROR: struct takes at least 1 generic argument but 0 generic arguments were supplied [E0107] + + reuse foo::, _, _, ()> as foo11; + //~^ ERROR: function takes 1 lifetime argument but 0 lifetime arguments were supplied [E0107] + //~| ERROR: function takes 3 generic arguments but 4 generic arguments were supplied [E0107] + //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + //~| ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + + reuse foo::<'____, ___, _, ___> as foo12; + //~^ ERROR: use of undeclared lifetime name `'____` [E0261] + //~| ERROR: cannot find type `___` in this scope [E0425] + //~| ERROR: cannot find type `___` in this scope [E0425] + + reuse foo::<'_, Vec<_>, Vec>, _> as foo13; + //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + //~| ERROR: type provided when a constant was expected [E0747] + + reuse foo::<'_, unresolved_, _, _> as foo14; + //~^ ERROR: cannot find type `unresolved_` in this scope + + reuse foo::<_, _, _> as foo15; + //~^ ERROR: function takes 3 generic arguments but 2 generic arguments were supplied + //~| ERROR: wrong infer used: expected '_, found: _ +} + +mod free_to_trait { + pub trait Trait<'a, 'b, X, const C: usize, Y> { + fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + } + + struct X; + impl<'a, 'b, Some, Params, X, const C: usize, Y> Trait<'a, 'b, X, C, Y> for X {} + //~^ ERROR: the type parameter `Some` is not constrained by the impl trait, self type, or predicates [E0207] + //~| ERROR: the type parameter `Params` is not constrained by the impl trait, self type, or predicates [E0207] + + mod child_only { + use super::*; + + reuse Trait::foo::<> as foo1; + reuse Trait::foo::<'_, _, _, _> as foo2; + reuse Trait::foo::<'static, String, _, _> as foo3; + reuse Trait::foo::<'_, _, 123, _> as foo4; + + reuse Trait::foo::<'_, '_, '_, _, _, _,> as foo5; + //~^ ERROR: method takes 3 generic arguments but 5 generic arguments were supplied + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + //~^ ERROR: method takes 3 generic arguments but 6 generic arguments were supplied [E0107] + //~| ERROR: method takes 1 lifetime argument but 3 lifetime arguments were supplied + //~| ERROR: wrong infer used: expected '_, found: _ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::foo::<_, '_, _, _> as foo7; + //~^ ERROR: wrong infer used: expected '_, found: _ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::foo::<'_, '_, '_, '_> as foo8; + //~^ ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::foo::<_> as foo9; + //~^ ERROR: method takes 3 generic arguments but 0 generic arguments were supplied + //~| ERROR: wrong infer used: expected '_, found: _ + + reuse Trait::foo::, _, _, ()> as foo10; + //~^ ERROR: method takes 3 generic arguments but 4 generic arguments were supplied [E0107] + //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + //~| ERROR: struct takes 0 lifetime arguments but 1 lifetime argument was supplied [E0107] + //~| ERROR: struct takes at least 1 generic argument but 0 generic arguments were supplied [E0107] + //~| ERROR: method takes 1 lifetime argument but 0 lifetime arguments were supplied + + reuse Trait::foo::, _, _, ()> as foo11; + //~^ ERROR: method takes 1 lifetime argument but 0 lifetime arguments were supplied [E0107] + //~| ERROR: method takes 3 generic arguments but 4 generic arguments were supplied [E0107] + //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + //~| ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + + reuse Trait::foo::<'____, ___, _, ___> as foo12; + //~^ ERROR: use of undeclared lifetime name `'____` [E0261] + //~| ERROR: cannot find type `___` in this scope [E0425] + //~| ERROR: cannot find type `___` in this scope [E0425] + + reuse Trait::foo::<'_, Vec<_>, Vec>, _> as foo13; + //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + //~| ERROR: type provided when a constant was expected [E0747] + + reuse Trait::foo::<'_, unresolved_, _, _> as foo14; + //~^ ERROR: cannot find type `unresolved_` in this scope + + reuse Trait::foo::<_, _, _> as foo15; + //~^ ERROR: method takes 3 generic arguments but 2 generic arguments were supplied + //~| ERROR: wrong infer used: expected '_, found: _ + } + + mod parent_only { + use super::*; + + reuse Trait::<'_, 'static, _, _, _>::foo as foo1; + reuse Trait::<'_, '_, _, _, _>::foo as foo2; + + reuse Trait::<'_, (), _, '_, _>::foo as foo3; + //~^ ERROR: trait takes 2 lifetime arguments but 1 lifetime argument was supplied [E0107] + //~| ERROR: trait takes 3 generic arguments but 4 generic arguments were supplied [E0107] + //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::<>::foo as foo4; + + reuse Trait::<_, _>::foo as foo5; + //~^ ERROR: trait takes 3 generic arguments but 0 generic arguments were supplied + //~| ERROR: wrong infer used: expected '_, found: _ + //~| ERROR: wrong infer used: expected '_, found: _ + + reuse Trait::<'_, '_>::foo as foo6; + //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions + + reuse Trait::<'_, '_, Vec<_>, 123, Vec>>::foo as foo7; + //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + //~| ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + + reuse Trait::<'static, 'static, (), 123, ()>::foo as foo8; + reuse Trait::<'static, 'static, _, _, _>::foo as foo9; + + reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo as foo10; + //~^ ERROR: trait takes 3 generic arguments but 7 generic arguments were supplied + + reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_, '_>::foo as foo11; + //~^ ERROR: trait takes 2 lifetime arguments but 6 lifetime arguments were supplied + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::<'static, 'static, _>::foo as foo12; + //~^ ERROR: trait takes 3 generic arguments but 1 generic argument was supplied + } + + mod parent_and_child_random { + use super::*; + + reuse Trait::<'_, 'static, _, _, _>::foo::<> as foo1; + reuse Trait::<'_, '_, _, _, _>::foo::<'_, _, _, _> as foo2; + + reuse Trait::<'_, (), _, '_, _>::foo::<'static, String, _, _> as foo3; + //~^ ERROR: trait takes 2 lifetime arguments but 1 lifetime argument was supplied [E0107] + //~| ERROR: trait takes 3 generic arguments but 4 generic arguments were supplied [E0107] + //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::<>::foo::<'_, _, 123, _> as foo4; + + reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5; + //~^ ERROR: trait takes 3 generic arguments but 0 generic arguments were supplied + //~| ERROR: method takes 3 generic arguments but 5 generic arguments were supplied + //~| ERROR: wrong infer used: expected '_, found: _ + //~| ERROR: wrong infer used: expected '_, found: _ + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + //~| ERROR: method takes 3 generic arguments but 6 generic arguments were supplied [E0107] + //~| ERROR: method takes 1 lifetime argument but 3 lifetime arguments were supplied + //~| ERROR: wrong infer used: expected '_, found: _ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::<'_, '_, Vec<_>, 123, Vec>>::foo::<_, '_, _, _> as foo7; + //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + //~| ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + //~| ERROR: wrong infer used: expected '_, found: _ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::<'static, 'static, (), 123, ()>::foo::<'_, '_, '_, '_> as foo8; + //~^ ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::<'static, 'static, _, _, _>::foo::<_> as foo9; + //~^ ERROR: method takes 3 generic arguments but 0 generic arguments were supplied + //~| ERROR: wrong infer used: expected '_, found: _ + + reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::, _, _, ()> as foo10; + //~^ ERROR: trait takes 3 generic arguments but 7 generic arguments were supplied [E0107] + //~| ERROR: method takes 1 lifetime argument but 0 lifetime arguments were supplied [E0107] + //~| ERROR: method takes 3 generic arguments but 4 generic arguments were supplied [E0107] + //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + //~| ERROR: struct takes 0 lifetime arguments but 1 lifetime argument was supplied [E0107] + //~| ERROR: struct takes at least 1 generic argument but 0 generic arguments were supplied [E0107] + + reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::, _, _, ()> as foo11; + //~^ ERROR: trait takes 2 lifetime arguments but 5 lifetime arguments were supplied [E0107] + //~| ERROR: method takes 1 lifetime argument but 0 lifetime arguments were supplied [E0107] + //~| ERROR: method takes 3 generic arguments but 4 generic arguments were supplied [E0107] + //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + //~| ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::<'static, 'static, _>::foo::<'____, ___, _, ___> as foo12; + //~^ ERROR: cannot find type `___` in this scope + //~| ERROR: cannot find type `___` in this scope + //~| ERROR: use of undeclared lifetime name `'____` + //~| ERROR: trait takes 3 generic arguments but 1 generic argument was supplied + } +} + +mod trait_impl_to_free { + pub trait Trait<'a, 'b, X, const C: usize, Y> { + fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self) {} + } + + struct S; + impl<'a, 'b, X, const C: usize, Y> Trait<'a, 'b, X, C, Y> for S {} + + mod to_reuse { + pub fn foo(_: ()) {} + } + + struct F1(S); + impl<'a, 'b, X, const C: usize, Y> Trait<'a, 'b, X, C, Y> for F1 { + reuse to_reuse::foo::<_, _, _> { self.0 } + //~^ ERROR: mismatched types + } + + struct F2(S); + impl<'a, 'b, X, const C: usize, Y> Trait<'a, 'b, X, C, Y> for F2 { + reuse to_reuse::foo { self.0 } + //~^ ERROR: mismatched types + //~| ERROR: function takes 0 lifetime arguments but 1 lifetime argument was supplied + } + + struct F3(S); + impl<'a, 'b, X, const C: usize, Y> Trait<'a, 'b, X, C, Y> for F3 { + reuse to_reuse::foo::<(), 123, ()> { self.0 } + //~^ ERROR: mismatched types + } +} + +fn main() {} diff --git a/tests/ui/delegation/generics/infers.stderr b/tests/ui/delegation/generics/infers.stderr new file mode 100644 index 0000000000000..1ab3ef232832e --- /dev/null +++ b/tests/ui/delegation/generics/infers.stderr @@ -0,0 +1,1296 @@ +error: lifetimes must be followed by `+` to form a trait object type + --> $DIR/infers.rs:54:21 + | +LL | reuse foo::('_, _, _, _) as bar; + | ^^ + | +help: consider adding a trait bound after the potential lifetime bound + | +LL | reuse foo::('_ + /* Trait */, _, _, _) as bar; + | +++++++++++++ + +error[E0261]: use of undeclared lifetime name `'____` + --> $DIR/infers.rs:123:17 + | +LL | reuse foo::<'____, ___, _, ___> as foo12; + | ^^^^^ undeclared lifetime + | +help: consider introducing lifetime `'____` here + | +LL | reuse foo'____, ::<'____, ___, _, ___> as foo12; + | ++++++ + +error[E0261]: use of undeclared lifetime name `'____` + --> $DIR/infers.rs:195:28 + | +LL | reuse Trait::foo::<'____, ___, _, ___> as foo12; + | ^^^^^ undeclared lifetime + | +help: consider introducing lifetime `'____` here + | +LL | reuse Trait::foo'____, ::<'____, ___, _, ___> as foo12; + | ++++++ + +error[E0261]: use of undeclared lifetime name `'____` + --> $DIR/infers.rs:316:51 + | +LL | reuse Trait::<'static, 'static, _>::foo::<'____, ___, _, ___> as foo12; + | ^^^^^ undeclared lifetime + | +help: consider introducing lifetime `'____` here + | +LL | reuse Trait::<'static, 'static, _>::foo'____, ::<'____, ___, _, ___> as foo12; + | ++++++ + +error[E0425]: cannot find type `___` in this scope + --> $DIR/infers.rs:123:24 + | +LL | reuse foo::<'____, ___, _, ___> as foo12; + | ^^^ not found in this scope + +error[E0425]: cannot find type `___` in this scope + --> $DIR/infers.rs:123:32 + | +LL | reuse foo::<'____, ___, _, ___> as foo12; + | ^^^ not found in this scope + +error[E0425]: cannot find type `unresolved_` in this scope + --> $DIR/infers.rs:132:21 + | +LL | reuse foo::<'_, unresolved_, _, _> as foo14; + | ^^^^^^^^^^^ not found in this scope + +error[E0425]: cannot find type `___` in this scope + --> $DIR/infers.rs:195:35 + | +LL | reuse Trait::foo::<'____, ___, _, ___> as foo12; + | ^^^ not found in this scope + +error[E0425]: cannot find type `___` in this scope + --> $DIR/infers.rs:195:43 + | +LL | reuse Trait::foo::<'____, ___, _, ___> as foo12; + | ^^^ not found in this scope + +error[E0425]: cannot find type `unresolved_` in this scope + --> $DIR/infers.rs:204:32 + | +LL | reuse Trait::foo::<'_, unresolved_, _, _> as foo14; + | ^^^^^^^^^^^ not found in this scope + +error[E0425]: cannot find type `___` in this scope + --> $DIR/infers.rs:316:58 + | +LL | reuse Trait::<'static, 'static, _>::foo::<'____, ___, _, ___> as foo12; + | ^^^ not found in this scope + +error[E0425]: cannot find type `___` in this scope + --> $DIR/infers.rs:316:66 + | +LL | reuse Trait::<'static, 'static, _>::foo::<'____, ___, _, ___> as foo12; + | ^^^ not found in this scope + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:11:21 + | +LL | reuse foo::<_, '_, '_, '_> as bar; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:11:24 + | +LL | reuse foo::<_, '_, '_, '_> as bar; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:11:28 + | +LL | reuse foo::<_, '_, '_, '_> as bar; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:11:32 + | +LL | reuse foo::<_, '_, '_, '_> as bar; + | ^^ + +error[E0214]: parenthesized type parameters may only be used with a `Fn` trait + --> $DIR/infers.rs:54:15 + | +LL | reuse foo::('_, _, _, _) as bar; + | ^^^^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses + | +help: use angle brackets instead + | +LL - reuse foo::('_, _, _, _) as bar; +LL + reuse foo::<'_, _, _, _> as bar; + | + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:86:21 + | +LL | reuse foo::<'_, '_, '_, _, _, _,> as foo5; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:86:25 + | +LL | reuse foo::<'_, '_, '_, _, _, _,> as foo5; + | ^^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:91:17 + | +LL | reuse foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:91:26 + | +LL | reuse foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:97:17 + | +LL | reuse foo::<_, '_, _, _> as foo7; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:97:20 + | +LL | reuse foo::<_, '_, _, _> as foo7; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:101:21 + | +LL | reuse foo::<'_, '_, '_, '_> as foo8; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:101:25 + | +LL | reuse foo::<'_, '_, '_, '_> as foo8; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:101:29 + | +LL | reuse foo::<'_, '_, '_, '_> as foo8; + | ^^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:106:17 + | +LL | reuse foo::<_> as foo9; + | ^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:135:17 + | +LL | reuse foo::<_, _, _> as foo15; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:158:32 + | +LL | reuse Trait::foo::<'_, '_, '_, _, _, _,> as foo5; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:158:36 + | +LL | reuse Trait::foo::<'_, '_, '_, _, _, _,> as foo5; + | ^^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:163:28 + | +LL | reuse Trait::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:163:37 + | +LL | reuse Trait::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:169:28 + | +LL | reuse Trait::foo::<_, '_, _, _> as foo7; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:169:31 + | +LL | reuse Trait::foo::<_, '_, _, _> as foo7; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:173:32 + | +LL | reuse Trait::foo::<'_, '_, '_, '_> as foo8; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:173:36 + | +LL | reuse Trait::foo::<'_, '_, '_, '_> as foo8; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:173:40 + | +LL | reuse Trait::foo::<'_, '_, '_, '_> as foo8; + | ^^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:178:28 + | +LL | reuse Trait::foo::<_> as foo9; + | ^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:207:28 + | +LL | reuse Trait::foo::<_, _, _> as foo15; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:218:34 + | +LL | reuse Trait::<'_, (), _, '_, _>::foo as foo3; + | ^^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:226:23 + | +LL | reuse Trait::<_, _>::foo as foo5; + | ^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:226:26 + | +LL | reuse Trait::<_, _>::foo as foo5; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:244:41 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_, '_>::foo as foo11; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:244:44 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_, '_>::foo as foo11; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:244:48 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_, '_>::foo as foo11; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:260:34 + | +LL | reuse Trait::<'_, (), _, '_, _>::foo::<'static, String, _, _> as foo3; + | ^^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:268:23 + | +LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5; + | ^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:268:26 + | +LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:268:40 + | +LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:268:44 + | +LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5; + | ^^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:276:38 + | +LL | reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:276:47 + | +LL | reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:283:64 + | +LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec>>::foo::<_, '_, _, _> as foo7; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:283:67 + | +LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec>>::foo::<_, '_, _, _> as foo7; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:289:65 + | +LL | reuse Trait::<'static, 'static, (), 123, ()>::foo::<'_, '_, '_, '_> as foo8; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:289:69 + | +LL | reuse Trait::<'static, 'static, (), 123, ()>::foo::<'_, '_, '_, '_> as foo8; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:289:73 + | +LL | reuse Trait::<'static, 'static, (), 123, ()>::foo::<'_, '_, '_, '_> as foo8; + | ^^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:294:57 + | +LL | reuse Trait::<'static, 'static, _, _, _>::foo::<_> as foo9; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:306:41 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::, _, _, ()> as foo11; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:306:44 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::, _, _, ()> as foo11; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:306:48 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::, _, _, ()> as foo11; + | ^^ + +error[E0107]: function takes 1 lifetime argument but 2 lifetime arguments were supplied + --> $DIR/infers.rs:44:15 + | +LL | reuse foo::<'_, '_> as foo2; + | ^^^--------- help: remove the lifetime argument + | | + | expected 1 lifetime argument + | +note: function defined here, with 1 lifetime parameter: `'c` + --> $DIR/infers.rs:38:12 + | +LL | fn foo<'a, 'b, 'c: 'c, 'd>(_: &'a &'b &'c &'d ()) {} + | ^^^ -- + +error[E0107]: function takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/infers.rs:54:15 + | +LL | reuse foo::('_, _, _, _) as bar; + | ^^^ expected 1 lifetime argument + | +note: function defined here, with 1 lifetime parameter: `'b` + --> $DIR/infers.rs:52:12 + | +LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + | ^^^ -- +help: add missing lifetime argument + | +LL | reuse foo::('b, '_, _, _, _) as bar; + | +++ + +error[E0107]: function takes 3 generic arguments but 4 generic arguments were supplied + --> $DIR/infers.rs:54:15 + | +LL | reuse foo::('_, _, _, _) as bar; + | ^^^ --- help: remove the unnecessary generic argument + | | + | expected 3 generic arguments + | +note: function defined here, with 3 generic parameters: `X`, `M`, `Y` + --> $DIR/infers.rs:52:12 + | +LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + | ^^^ - -------------- - + +error: inferred lifetimes are not allowed in delegations as we need to inherit signature + --> $DIR/infers.rs:54:15 + | +LL | reuse foo::('_, _, _, _) as bar; + | ^^^ + +error[E0224]: at least one trait is required for an object type + --> $DIR/infers.rs:54:21 + | +LL | reuse foo::('_, _, _, _) as bar; + | ^^ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:54:25 + | +LL | reuse foo::('_, _, _, _) as bar; + | ^ not allowed in type signatures + +error[E0107]: function takes 3 generic arguments but 5 generic arguments were supplied + --> $DIR/infers.rs:86:11 + | +LL | reuse foo::<'_, '_, '_, _, _, _,> as foo5; + | ^^^---------------------- help: remove the unnecessary generic arguments + | | + | expected 3 generic arguments + | +note: function defined here, with 3 generic parameters: `X`, `M`, `Y` + --> $DIR/infers.rs:79:8 + | +LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + | ^^^ - -------------- - + +error[E0107]: function takes 1 lifetime argument but 3 lifetime arguments were supplied + --> $DIR/infers.rs:91:11 + | +LL | reuse foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^^^---------------------- help: remove the lifetime arguments + | | + | expected 1 lifetime argument + | +note: function defined here, with 1 lifetime parameter: `'b` + --> $DIR/infers.rs:79:8 + | +LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + | ^^^ -- + +error[E0107]: function takes 3 generic arguments but 6 generic arguments were supplied + --> $DIR/infers.rs:91:11 + | +LL | reuse foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^^^------------------------------- help: remove the unnecessary generic arguments + | | + | expected 3 generic arguments + | +note: function defined here, with 3 generic parameters: `X`, `M`, `Y` + --> $DIR/infers.rs:79:8 + | +LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + | ^^^ - -------------- - + +error[E0107]: function takes 3 generic arguments but 0 generic arguments were supplied + --> $DIR/infers.rs:106:11 + | +LL | reuse foo::<_> as foo9; + | ^^^ expected 3 generic arguments + | +note: function defined here, with 3 generic parameters: `X`, `M`, `Y` + --> $DIR/infers.rs:79:8 + | +LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + | ^^^ - -------------- - +help: add missing generic arguments + | +LL | reuse fooX, M, Y::<_> as foo9; + | +++++++ + +error[E0107]: function takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/infers.rs:110:11 + | +LL | reuse foo::, _, _, ()> as foo10; + | ^^^ expected 1 lifetime argument + | +note: function defined here, with 1 lifetime parameter: `'b` + --> $DIR/infers.rs:79:8 + | +LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + | ^^^ -- +help: add missing lifetime argument + | +LL | reuse foo::<'b, Vec<'_>, _, _, ()> as foo10; + | +++ + +error[E0107]: function takes 3 generic arguments but 4 generic arguments were supplied + --> $DIR/infers.rs:110:11 + | +LL | reuse foo::, _, _, ()> as foo10; + | ^^^-------------------- help: remove the unnecessary generic argument + | | + | expected 3 generic arguments + | +note: function defined here, with 3 generic parameters: `X`, `M`, `Y` + --> $DIR/infers.rs:79:8 + | +LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + | ^^^ - -------------- - + +error: inferred lifetimes are not allowed in delegations as we need to inherit signature + --> $DIR/infers.rs:110:11 + | +LL | reuse foo::, _, _, ()> as foo10; + | ^^^ + +error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied + --> $DIR/infers.rs:110:17 + | +LL | reuse foo::, _, _, ()> as foo10; + | ^^^---- help: remove the unnecessary generics + | | + | expected 0 lifetime arguments + +error[E0107]: struct takes at least 1 generic argument but 0 generic arguments were supplied + --> $DIR/infers.rs:110:17 + | +LL | reuse foo::, _, _, ()> as foo10; + | ^^^ expected at least 1 generic argument + | +help: add missing generic argument + | +LL | reuse foo::, _, _, ()> as foo10; + | +++ + +error[E0107]: function takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/infers.rs:117:11 + | +LL | reuse foo::, _, _, ()> as foo11; + | ^^^ expected 1 lifetime argument + | +note: function defined here, with 1 lifetime parameter: `'b` + --> $DIR/infers.rs:79:8 + | +LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + | ^^^ -- +help: add missing lifetime argument + | +LL | reuse foo::<'b, Vec<_>, _, _, ()> as foo11; + | +++ + +error[E0107]: function takes 3 generic arguments but 4 generic arguments were supplied + --> $DIR/infers.rs:117:11 + | +LL | reuse foo::, _, _, ()> as foo11; + | ^^^------------------- help: remove the unnecessary generic argument + | | + | expected 3 generic arguments + | +note: function defined here, with 3 generic parameters: `X`, `M`, `Y` + --> $DIR/infers.rs:79:8 + | +LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + | ^^^ - -------------- - + +error: inferred lifetimes are not allowed in delegations as we need to inherit signature + --> $DIR/infers.rs:117:11 + | +LL | reuse foo::, _, _, ()> as foo11; + | ^^^ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:117:21 + | +LL | reuse foo::, _, _, ()> as foo11; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:128:25 + | +LL | reuse foo::<'_, Vec<_>, Vec>, _> as foo13; + | ^ not allowed in type signatures + +error[E0747]: type provided when a constant was expected + --> $DIR/infers.rs:128:29 + | +LL | reuse foo::<'_, Vec<_>, Vec>, _> as foo13; + | ^^^^^^^^^^^ + | +help: if this generic argument was intended as a const parameter, surround it with braces + | +LL | reuse foo::<'_, Vec<_>, { Vec> }, _> as foo13; + | + + + +error[E0107]: function takes 3 generic arguments but 2 generic arguments were supplied + --> $DIR/infers.rs:135:11 + | +LL | reuse foo::<_, _, _> as foo15; + | ^^^ + | | + | expected 3 generic arguments + | supplied 2 generic arguments + | +note: function defined here, with 3 generic parameters: `X`, `M`, `Y` + --> $DIR/infers.rs:79:8 + | +LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + | ^^^ - -------------- - +help: add missing generic argument + | +LL | reuse fooY::<_, _, _> as foo15; + | + + +error[E0207]: the type parameter `Some` is not constrained by the impl trait, self type, or predicates + --> $DIR/infers.rs:146:18 + | +LL | impl<'a, 'b, Some, Params, X, const C: usize, Y> Trait<'a, 'b, X, C, Y> for X {} + | ^^^^ unconstrained type parameter + +error[E0207]: the type parameter `Params` is not constrained by the impl trait, self type, or predicates + --> $DIR/infers.rs:146:24 + | +LL | impl<'a, 'b, Some, Params, X, const C: usize, Y> Trait<'a, 'b, X, C, Y> for X {} + | ^^^^^^ unconstrained type parameter + +error[E0107]: method takes 3 generic arguments but 5 generic arguments were supplied + --> $DIR/infers.rs:158:22 + | +LL | reuse Trait::foo::<'_, '_, '_, _, _, _,> as foo5; + | ^^^---------------------- help: remove the unnecessary generic arguments + | | + | expected 3 generic arguments + | +note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ -- -------------- -- + +error[E0107]: method takes 1 lifetime argument but 3 lifetime arguments were supplied + --> $DIR/infers.rs:163:22 + | +LL | reuse Trait::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^^^---------------------- help: remove the lifetime arguments + | | + | expected 1 lifetime argument + | +note: method defined here, with 1 lifetime parameter: `'bb` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ --- + +error[E0107]: method takes 3 generic arguments but 6 generic arguments were supplied + --> $DIR/infers.rs:163:22 + | +LL | reuse Trait::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^^^------------------------------- help: remove the unnecessary generic arguments + | | + | expected 3 generic arguments + | +note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ -- -------------- -- + +error[E0107]: method takes 3 generic arguments but 0 generic arguments were supplied + --> $DIR/infers.rs:178:22 + | +LL | reuse Trait::foo::<_> as foo9; + | ^^^ expected 3 generic arguments + | +note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ -- -------------- -- +help: add missing generic arguments + | +LL | reuse Trait::fooXX, M, YY::<_> as foo9; + | +++++++++ + +error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/infers.rs:182:22 + | +LL | reuse Trait::foo::, _, _, ()> as foo10; + | ^^^ expected 1 lifetime argument + | +note: method defined here, with 1 lifetime parameter: `'bb` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ --- +help: add missing lifetime argument + | +LL | reuse Trait::foo::<'a, Vec<'_>, _, _, ()> as foo10; + | +++ + +error[E0107]: method takes 3 generic arguments but 4 generic arguments were supplied + --> $DIR/infers.rs:182:22 + | +LL | reuse Trait::foo::, _, _, ()> as foo10; + | ^^^-------------------- help: remove the unnecessary generic argument + | | + | expected 3 generic arguments + | +note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ -- -------------- -- + +error: inferred lifetimes are not allowed in delegations as we need to inherit signature + --> $DIR/infers.rs:182:22 + | +LL | reuse Trait::foo::, _, _, ()> as foo10; + | ^^^ + +error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied + --> $DIR/infers.rs:182:28 + | +LL | reuse Trait::foo::, _, _, ()> as foo10; + | ^^^---- help: remove the unnecessary generics + | | + | expected 0 lifetime arguments + +error[E0107]: struct takes at least 1 generic argument but 0 generic arguments were supplied + --> $DIR/infers.rs:182:28 + | +LL | reuse Trait::foo::, _, _, ()> as foo10; + | ^^^ expected at least 1 generic argument + | +help: add missing generic argument + | +LL | reuse Trait::foo::, _, _, ()> as foo10; + | +++ + +error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/infers.rs:189:22 + | +LL | reuse Trait::foo::, _, _, ()> as foo11; + | ^^^ expected 1 lifetime argument + | +note: method defined here, with 1 lifetime parameter: `'bb` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ --- +help: add missing lifetime argument + | +LL | reuse Trait::foo::<'a, Vec<_>, _, _, ()> as foo11; + | +++ + +error[E0107]: method takes 3 generic arguments but 4 generic arguments were supplied + --> $DIR/infers.rs:189:22 + | +LL | reuse Trait::foo::, _, _, ()> as foo11; + | ^^^------------------- help: remove the unnecessary generic argument + | | + | expected 3 generic arguments + | +note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ -- -------------- -- + +error: inferred lifetimes are not allowed in delegations as we need to inherit signature + --> $DIR/infers.rs:189:22 + | +LL | reuse Trait::foo::, _, _, ()> as foo11; + | ^^^ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:189:32 + | +LL | reuse Trait::foo::, _, _, ()> as foo11; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:200:36 + | +LL | reuse Trait::foo::<'_, Vec<_>, Vec>, _> as foo13; + | ^ not allowed in type signatures + +error[E0747]: type provided when a constant was expected + --> $DIR/infers.rs:200:40 + | +LL | reuse Trait::foo::<'_, Vec<_>, Vec>, _> as foo13; + | ^^^^^^^^^^^ + | +help: if this generic argument was intended as a const parameter, surround it with braces + | +LL | reuse Trait::foo::<'_, Vec<_>, { Vec> }, _> as foo13; + | + + + +error[E0107]: method takes 3 generic arguments but 2 generic arguments were supplied + --> $DIR/infers.rs:207:22 + | +LL | reuse Trait::foo::<_, _, _> as foo15; + | ^^^ + | | + | expected 3 generic arguments + | supplied 2 generic arguments + | +note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ -- -------------- -- +help: add missing generic argument + | +LL | reuse Trait::fooYY::<_, _, _> as foo15; + | ++ + +error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied + --> $DIR/infers.rs:218:15 + | +LL | reuse Trait::<'_, (), _, '_, _>::foo as foo3; + | ^^^^^ --- supplied 1 lifetime argument + | | + | expected 2 lifetime arguments + | +note: trait defined here, with 2 lifetime parameters: `'a`, `'b` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ -- -- +help: add missing lifetime argument + | +LL | reuse Trait::<'_, (), _, '_, _>::foo, 'a as foo3; + | ++++ + +error[E0107]: trait takes 3 generic arguments but 4 generic arguments were supplied + --> $DIR/infers.rs:218:15 + | +LL | reuse Trait::<'_, (), _, '_, _>::foo as foo3; + | ^^^^^ --- help: remove the unnecessary generic argument + | | + | expected 3 generic arguments + | +note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ - -------------- - + +error: inferred lifetimes are not allowed in delegations as we need to inherit signature + --> $DIR/infers.rs:218:15 + | +LL | reuse Trait::<'_, (), _, '_, _>::foo as foo3; + | ^^^^^ + +error[E0107]: trait takes 3 generic arguments but 0 generic arguments were supplied + --> $DIR/infers.rs:226:15 + | +LL | reuse Trait::<_, _>::foo as foo5; + | ^^^^^ expected 3 generic arguments + | +note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ - -------------- - +help: add missing generic arguments + | +LL | reuse Trait::<_, _>::foo, X, C, Y as foo5; + | +++++++++ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:231:15 + | +LL | reuse Trait::<'_, '_>::foo as foo6; + | ^^^^^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:234:35 + | +LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec>>::foo as foo7; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:234:52 + | +LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec>>::foo as foo7; + | ^ not allowed in type signatures + +error[E0107]: trait takes 3 generic arguments but 7 generic arguments were supplied + --> $DIR/infers.rs:241:15 + | +LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo as foo10; + | ^^^^^ expected 3 generic arguments ------- help: remove the unnecessary generic arguments + | +note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ - -------------- - + +error[E0107]: trait takes 2 lifetime arguments but 6 lifetime arguments were supplied + --> $DIR/infers.rs:244:15 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_, '_>::foo as foo11; + | ^^^^^ --------------------------- help: remove the lifetime arguments + | | + | expected 2 lifetime arguments + | +note: trait defined here, with 2 lifetime parameters: `'a`, `'b` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ -- -- + +error[E0107]: trait takes 3 generic arguments but 1 generic argument was supplied + --> $DIR/infers.rs:250:15 + | +LL | reuse Trait::<'static, 'static, _>::foo as foo12; + | ^^^^^ --- supplied 1 generic argument + | | + | expected 3 generic arguments + | +note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ - -------------- - +help: add missing generic arguments + | +LL | reuse Trait::<'static, 'static, _>::foo, C, Y as foo12; + | ++++++ + +error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied + --> $DIR/infers.rs:260:15 + | +LL | reuse Trait::<'_, (), _, '_, _>::foo::<'static, String, _, _> as foo3; + | ^^^^^ --- supplied 1 lifetime argument + | | + | expected 2 lifetime arguments + | +note: trait defined here, with 2 lifetime parameters: `'a`, `'b` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ -- -- +help: add missing lifetime argument + | +LL | reuse Trait::<'_, (), _, '_, _>::foo, 'a::<'static, String, _, _> as foo3; + | ++++ + +error[E0107]: trait takes 3 generic arguments but 4 generic arguments were supplied + --> $DIR/infers.rs:260:15 + | +LL | reuse Trait::<'_, (), _, '_, _>::foo::<'static, String, _, _> as foo3; + | ^^^^^ --- help: remove the unnecessary generic argument + | | + | expected 3 generic arguments + | +note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ - -------------- - + +error: inferred lifetimes are not allowed in delegations as we need to inherit signature + --> $DIR/infers.rs:260:15 + | +LL | reuse Trait::<'_, (), _, '_, _>::foo::<'static, String, _, _> as foo3; + | ^^^^^ + +error[E0107]: trait takes 3 generic arguments but 0 generic arguments were supplied + --> $DIR/infers.rs:268:15 + | +LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5; + | ^^^^^ expected 3 generic arguments + | +note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ - -------------- - +help: add missing generic arguments + | +LL | reuse Trait::<_, _>::foo, X, C, Y::<'_, '_, '_, _, _, _,> as foo5; + | +++++++++ + +error[E0107]: method takes 3 generic arguments but 5 generic arguments were supplied + --> $DIR/infers.rs:268:30 + | +LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5; + | ^^^---------------------- help: remove the unnecessary generic arguments + | | + | expected 3 generic arguments + | +note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ -- -------------- -- + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:276:15 + | +LL | reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^^^^^ not allowed in type signatures + +error[E0107]: method takes 1 lifetime argument but 3 lifetime arguments were supplied + --> $DIR/infers.rs:276:32 + | +LL | reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^^^---------------------- help: remove the lifetime arguments + | | + | expected 1 lifetime argument + | +note: method defined here, with 1 lifetime parameter: `'bb` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ --- + +error[E0107]: method takes 3 generic arguments but 6 generic arguments were supplied + --> $DIR/infers.rs:276:32 + | +LL | reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^^^------------------------------- help: remove the unnecessary generic arguments + | | + | expected 3 generic arguments + | +note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ -- -------------- -- + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:283:35 + | +LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec>>::foo::<_, '_, _, _> as foo7; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:283:52 + | +LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec>>::foo::<_, '_, _, _> as foo7; + | ^ not allowed in type signatures + +error[E0107]: method takes 3 generic arguments but 0 generic arguments were supplied + --> $DIR/infers.rs:294:51 + | +LL | reuse Trait::<'static, 'static, _, _, _>::foo::<_> as foo9; + | ^^^ expected 3 generic arguments + | +note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ -- -------------- -- +help: add missing generic arguments + | +LL | reuse Trait::<'static, 'static, _, _, _>::fooXX, M, YY::<_> as foo9; + | +++++++++ + +error[E0107]: trait takes 3 generic arguments but 7 generic arguments were supplied + --> $DIR/infers.rs:298:15 + | +LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::, _, _, ()> as foo10; + | ^^^^^ expected 3 generic arguments ------- help: remove the unnecessary generic arguments + | +note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ - -------------- - + +error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/infers.rs:298:63 + | +LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::, _, _, ()> as foo10; + | ^^^ expected 1 lifetime argument + | +note: method defined here, with 1 lifetime parameter: `'bb` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ --- +help: add missing lifetime argument + | +LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::<'bb, Vec<'_>, _, _, ()> as foo10; + | ++++ + +error[E0107]: method takes 3 generic arguments but 4 generic arguments were supplied + --> $DIR/infers.rs:298:63 + | +LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::, _, _, ()> as foo10; + | ^^^-------------------- help: remove the unnecessary generic argument + | | + | expected 3 generic arguments + | +note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ -- -------------- -- + +error: inferred lifetimes are not allowed in delegations as we need to inherit signature + --> $DIR/infers.rs:298:63 + | +LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::, _, _, ()> as foo10; + | ^^^ + +error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied + --> $DIR/infers.rs:298:69 + | +LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::, _, _, ()> as foo10; + | ^^^---- help: remove the unnecessary generics + | | + | expected 0 lifetime arguments + +error[E0107]: struct takes at least 1 generic argument but 0 generic arguments were supplied + --> $DIR/infers.rs:298:69 + | +LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::, _, _, ()> as foo10; + | ^^^ expected at least 1 generic argument + | +help: add missing generic argument + | +LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::, _, _, ()> as foo10; + | +++ + +error[E0107]: trait takes 2 lifetime arguments but 5 lifetime arguments were supplied + --> $DIR/infers.rs:306:15 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::, _, _, ()> as foo11; + | ^^^^^ ----------------------- help: remove the lifetime arguments + | | + | expected 2 lifetime arguments + | +note: trait defined here, with 2 lifetime parameters: `'a`, `'b` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ -- -- + +error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/infers.rs:306:65 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::, _, _, ()> as foo11; + | ^^^ expected 1 lifetime argument + | +note: method defined here, with 1 lifetime parameter: `'bb` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ --- +help: add missing lifetime argument + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::<'bb, Vec<_>, _, _, ()> as foo11; + | ++++ + +error[E0107]: method takes 3 generic arguments but 4 generic arguments were supplied + --> $DIR/infers.rs:306:65 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::, _, _, ()> as foo11; + | ^^^------------------- help: remove the unnecessary generic argument + | | + | expected 3 generic arguments + | +note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ -- -------------- -- + +error: inferred lifetimes are not allowed in delegations as we need to inherit signature + --> $DIR/infers.rs:306:65 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::, _, _, ()> as foo11; + | ^^^ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:306:75 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::, _, _, ()> as foo11; + | ^ not allowed in type signatures + +error[E0107]: trait takes 3 generic arguments but 1 generic argument was supplied + --> $DIR/infers.rs:316:15 + | +LL | reuse Trait::<'static, 'static, _>::foo::<'____, ___, _, ___> as foo12; + | ^^^^^ --- supplied 1 generic argument + | | + | expected 3 generic arguments + | +note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ - -------------- - +help: add missing generic arguments + | +LL | reuse Trait::<'static, 'static, _>::foo, C, Y::<'____, ___, _, ___> as foo12; + | ++++++ + +error[E0308]: mismatched types + --> $DIR/infers.rs:338:42 + | +LL | reuse to_reuse::foo::<_, _, _> { self.0 } + | --- ^^^^^^ expected `()`, found `S` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/infers.rs:333:16 + | +LL | pub fn foo(_: ()) {} + | ^^^ ----- + +error[E0107]: function takes 0 lifetime arguments but 1 lifetime argument was supplied + --> $DIR/infers.rs:344:25 + | +LL | reuse to_reuse::foo { self.0 } + | ^^^ + | | + | expected 0 lifetime arguments + | help: remove the lifetime argument + | +note: function defined here, with 0 lifetime parameters + --> $DIR/infers.rs:333:16 + | +LL | pub fn foo(_: ()) {} + | ^^^ + +error[E0308]: mismatched types + --> $DIR/infers.rs:344:31 + | +LL | reuse to_reuse::foo { self.0 } + | --- ^^^^^^ expected `()`, found `S` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/infers.rs:333:16 + | +LL | pub fn foo(_: ()) {} + | ^^^ ----- + +error[E0308]: mismatched types + --> $DIR/infers.rs:351:46 + | +LL | reuse to_reuse::foo::<(), 123, ()> { self.0 } + | --- ^^^^^^ expected `()`, found `S` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/infers.rs:333:16 + | +LL | pub fn foo(_: ()) {} + | ^^^ ----- + +error: aborting due to 138 previous errors + +Some errors have detailed explanations: E0107, E0121, E0207, E0214, E0224, E0261, E0308, E0425, E0747. +For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/delegation/generics/trait-impl-wrong-args-count.rs b/tests/ui/delegation/generics/trait-impl-wrong-args-count.rs index 4073e5ce88607..7b33e1d16eadf 100644 --- a/tests/ui/delegation/generics/trait-impl-wrong-args-count.rs +++ b/tests/ui/delegation/generics/trait-impl-wrong-args-count.rs @@ -26,6 +26,7 @@ mod test_1 { reuse to_reuse::bar1; //~^ ERROR: function takes 0 generic arguments but 3 generic arguments were supplied + //~| ERROR: function takes 0 lifetime arguments but 2 lifetime arguments were supplied reuse to_reuse::bar2; //~^ ERROR: type annotations needed @@ -59,8 +60,10 @@ mod test_2 { impl Trait for X { reuse ::bar; //~^ ERROR: missing generics for trait + //~| ERROR: associated function takes 1 lifetime argument but 2 lifetime arguments were supplied reuse >::bar as bar1; + //~^ ERROR: associated function takes 1 lifetime argument but 2 lifetime arguments were supplied reuse >::bar::<'static, u32, u32, 1> as bar2; @@ -94,9 +97,11 @@ mod test_3 { impl Trait for X { reuse >::bar; //~^ ERROR: associated function takes 0 generic arguments but 3 generic arguments were supplied + //~| ERROR: associated function takes 0 lifetime arguments but 2 lifetime arguments were supplied reuse >::bar as bar1; //~^ ERROR: associated function takes 0 generic arguments but 3 generic arguments were supplied + //~| ERROR: associated function takes 0 lifetime arguments but 2 lifetime arguments were supplied reuse >::foo as bar2; //~^ ERROR: type annotations needed diff --git a/tests/ui/delegation/generics/trait-impl-wrong-args-count.stderr b/tests/ui/delegation/generics/trait-impl-wrong-args-count.stderr index 09281768bbf73..931b61ef0ca85 100644 --- a/tests/ui/delegation/generics/trait-impl-wrong-args-count.stderr +++ b/tests/ui/delegation/generics/trait-impl-wrong-args-count.stderr @@ -13,11 +13,29 @@ note: function defined here, with at most 2 generic parameters: `A`, `B` LL | pub fn bar<'a: 'a, 'b: 'b, A, B>(x: &super::XX) {} | ^^^ - - +error[E0107]: function takes 0 lifetime arguments but 2 lifetime arguments were supplied + --> $DIR/trait-impl-wrong-args-count.rs:27:25 + | +LL | reuse to_reuse::bar1; + | ^^^^ + | | + | expected 0 lifetime arguments + | help: remove the lifetime arguments + | +note: function defined here, with 0 lifetime parameters + --> $DIR/trait-impl-wrong-args-count.rs:7:16 + | +LL | pub fn bar1(x: &super::XX) {} + | ^^^^ + error[E0107]: function takes 0 generic arguments but 3 generic arguments were supplied --> $DIR/trait-impl-wrong-args-count.rs:27:25 | LL | reuse to_reuse::bar1; - | ^^^^ expected 0 generic arguments + | ^^^^ + | | + | expected 0 generic arguments + | help: remove the unnecessary generic arguments | note: function defined here, with 0 generic parameters --> $DIR/trait-impl-wrong-args-count.rs:7:16 @@ -26,7 +44,7 @@ LL | pub fn bar1(x: &super::XX) {} | ^^^^ error[E0284]: type annotations needed - --> $DIR/trait-impl-wrong-args-count.rs:30:25 + --> $DIR/trait-impl-wrong-args-count.rs:31:25 | LL | reuse to_reuse::bar2; | ^^^^ cannot infer the value of the const parameter `X` declared on the function `bar2` @@ -42,7 +60,7 @@ LL | reuse to_reuse::bar2::; | ++++++++++++++++++++++++++ error[E0284]: type annotations needed - --> $DIR/trait-impl-wrong-args-count.rs:30:25 + --> $DIR/trait-impl-wrong-args-count.rs:31:25 | LL | reuse to_reuse::bar2; | ^^^^ cannot infer the value of the const parameter `Y` declared on the function `bar2` @@ -58,13 +76,13 @@ LL | reuse to_reuse::bar2::; | ++++++++++++++++++++++++++ error[E0107]: missing generics for trait `test_2::Trait1` - --> $DIR/trait-impl-wrong-args-count.rs:60:21 + --> $DIR/trait-impl-wrong-args-count.rs:61:21 | LL | reuse ::bar; | ^^^^^^ expected 2 generic arguments | note: trait defined here, with 2 generic parameters: `A`, `B` - --> $DIR/trait-impl-wrong-args-count.rs:51:11 + --> $DIR/trait-impl-wrong-args-count.rs:52:11 | LL | trait Trait1 { | ^^^^^^ - - @@ -73,14 +91,44 @@ help: add missing generic arguments LL | reuse >::bar; | ++++++ +error[E0107]: associated function takes 1 lifetime argument but 2 lifetime arguments were supplied + --> $DIR/trait-impl-wrong-args-count.rs:61:30 + | +LL | reuse ::bar; + | ^^^ + | | + | expected 1 lifetime argument + | help: remove the lifetime argument + | +note: associated function defined here, with 1 lifetime parameter: `'x` + --> $DIR/trait-impl-wrong-args-count.rs:53:12 + | +LL | fn bar<'x: 'x, AA, BB, const NN: usize>() {} + | ^^^ -- + +error[E0107]: associated function takes 1 lifetime argument but 2 lifetime arguments were supplied + --> $DIR/trait-impl-wrong-args-count.rs:65:44 + | +LL | reuse >::bar as bar1; + | ^^^ + | | + | expected 1 lifetime argument + | help: remove the lifetime argument + | +note: associated function defined here, with 1 lifetime parameter: `'x` + --> $DIR/trait-impl-wrong-args-count.rs:53:12 + | +LL | fn bar<'x: 'x, AA, BB, const NN: usize>() {} + | ^^^ -- + error[E0107]: missing generics for trait `test_2::Trait1` - --> $DIR/trait-impl-wrong-args-count.rs:67:21 + --> $DIR/trait-impl-wrong-args-count.rs:70:21 | LL | reuse ::bar::<'static, u32, u32, 1> as bar3; | ^^^^^^ expected 2 generic arguments | note: trait defined here, with 2 generic parameters: `A`, `B` - --> $DIR/trait-impl-wrong-args-count.rs:51:11 + --> $DIR/trait-impl-wrong-args-count.rs:52:11 | LL | trait Trait1 { | ^^^^^^ - - @@ -90,13 +138,13 @@ LL | reuse >::bar::<'static, u32, u32, 1> as bar3; | ++++++ error[E0107]: missing generics for trait `test_2::Trait1` - --> $DIR/trait-impl-wrong-args-count.rs:70:21 + --> $DIR/trait-impl-wrong-args-count.rs:73:21 | LL | reuse ::bar as bar4; | ^^^^^^ expected 2 generic arguments | note: trait defined here, with 2 generic parameters: `A`, `B` - --> $DIR/trait-impl-wrong-args-count.rs:51:11 + --> $DIR/trait-impl-wrong-args-count.rs:52:11 | LL | trait Trait1 { | ^^^^^^ - - @@ -105,38 +153,74 @@ help: add missing generic arguments LL | reuse >::bar as bar4; | ++++++ +error[E0107]: associated function takes 0 lifetime arguments but 2 lifetime arguments were supplied + --> $DIR/trait-impl-wrong-args-count.rs:98:40 + | +LL | reuse >::bar; + | ^^^ + | | + | expected 0 lifetime arguments + | help: remove the lifetime arguments + | +note: associated function defined here, with 0 lifetime parameters + --> $DIR/trait-impl-wrong-args-count.rs:89:12 + | +LL | fn bar() {} + | ^^^ + error[E0107]: associated function takes 0 generic arguments but 3 generic arguments were supplied - --> $DIR/trait-impl-wrong-args-count.rs:95:40 + --> $DIR/trait-impl-wrong-args-count.rs:98:40 | LL | reuse >::bar; - | ^^^ expected 0 generic arguments + | ^^^ + | | + | expected 0 generic arguments + | help: remove the unnecessary generic arguments | note: associated function defined here, with 0 generic parameters - --> $DIR/trait-impl-wrong-args-count.rs:86:12 + --> $DIR/trait-impl-wrong-args-count.rs:89:12 + | +LL | fn bar() {} + | ^^^ + +error[E0107]: associated function takes 0 lifetime arguments but 2 lifetime arguments were supplied + --> $DIR/trait-impl-wrong-args-count.rs:102:40 + | +LL | reuse >::bar as bar1; + | ^^^ + | | + | expected 0 lifetime arguments + | help: remove the lifetime arguments + | +note: associated function defined here, with 0 lifetime parameters + --> $DIR/trait-impl-wrong-args-count.rs:89:12 | LL | fn bar() {} | ^^^ error[E0107]: associated function takes 0 generic arguments but 3 generic arguments were supplied - --> $DIR/trait-impl-wrong-args-count.rs:98:40 + --> $DIR/trait-impl-wrong-args-count.rs:102:40 | LL | reuse >::bar as bar1; - | ^^^ expected 0 generic arguments + | ^^^ + | | + | expected 0 generic arguments + | help: remove the unnecessary generic arguments | note: associated function defined here, with 0 generic parameters - --> $DIR/trait-impl-wrong-args-count.rs:86:12 + --> $DIR/trait-impl-wrong-args-count.rs:89:12 | LL | fn bar() {} | ^^^ error[E0282]: type annotations needed - --> $DIR/trait-impl-wrong-args-count.rs:101:40 + --> $DIR/trait-impl-wrong-args-count.rs:106:40 | LL | reuse >::foo as bar2; | ^^^ cannot infer type of the type parameter `X` declared on the associated function `foo` error[E0107]: associated function takes at most 2 generic arguments but 3 generic arguments were supplied - --> $DIR/trait-impl-wrong-args-count.rs:104:40 + --> $DIR/trait-impl-wrong-args-count.rs:109:40 | LL | reuse >::foo as bar3; | ^^^ @@ -145,12 +229,12 @@ LL | reuse >::foo as bar3; | help: remove the unnecessary generic argument | note: associated function defined here, with at most 2 generic parameters: `X`, `Y` - --> $DIR/trait-impl-wrong-args-count.rs:87:12 + --> $DIR/trait-impl-wrong-args-count.rs:90:12 | LL | fn foo() {} | ^^^ - - -error: aborting due to 11 previous errors +error: aborting due to 16 previous errors Some errors have detailed explanations: E0107, E0282, E0284. For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/delegation/generics/unelided-lifetime-in-sig-ice-156848.rs b/tests/ui/delegation/generics/unelided-lifetime-in-sig-ice-156848.rs index fad06b37ae416..1f97f7c652c35 100644 --- a/tests/ui/delegation/generics/unelided-lifetime-in-sig-ice-156848.rs +++ b/tests/ui/delegation/generics/unelided-lifetime-in-sig-ice-156848.rs @@ -1,3 +1,4 @@ +//@ check-pass //@ compile-flags: -Z deduplicate-diagnostics=yes #![feature(fn_delegation)] @@ -12,11 +13,8 @@ impl Trait for F {} struct S(F); impl S { reuse Trait::foo::<> { self.0 } - //~^ ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + reuse Trait::foo::<'_> as bar { self.0 } - //~^ ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature - //~| WARN: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - //~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } fn main() {} diff --git a/tests/ui/delegation/generics/unelided-lifetime-in-sig-ice-156848.stderr b/tests/ui/delegation/generics/unelided-lifetime-in-sig-ice-156848.stderr deleted file mode 100644 index 464b6a3a76819..0000000000000 --- a/tests/ui/delegation/generics/unelided-lifetime-in-sig-ice-156848.stderr +++ /dev/null @@ -1,27 +0,0 @@ -error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/unelided-lifetime-in-sig-ice-156848.rs:14:18 - | -LL | reuse Trait::foo::<> { self.0 } - | ^^^ - -warning: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/unelided-lifetime-in-sig-ice-156848.rs:16:24 - | -LL | fn foo<'a: 'a>(&self) {} - | - the late bound lifetime parameter is introduced here -... -LL | reuse Trait::foo::<'_> as bar { self.0 } - | ^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #42868 - = note: `#[warn(late_bound_lifetime_arguments)]` (part of `#[warn(future_incompatible)]`) on by default - -error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/unelided-lifetime-in-sig-ice-156848.rs:16:24 - | -LL | reuse Trait::foo::<'_> as bar { self.0 } - | ^^ - -error: aborting due to 2 previous errors; 1 warning emitted - diff --git a/tests/ui/delegation/self-ty-ice-156388.rs b/tests/ui/delegation/self-ty-ice-156388.rs index 542f56867b2b2..74cad01236375 100644 --- a/tests/ui/delegation/self-ty-ice-156388.rs +++ b/tests/ui/delegation/self-ty-ice-156388.rs @@ -1,8 +1,9 @@ //@ compile-flags: -Z deduplicate-diagnostics=yes +#![feature(const_trait_impl)] #![feature(fn_delegation)] reuse Default::default; -//~^ ERROR: delegation self type is not specified +//~^ ERROR: the trait bound `Self: [const] Default` is not satisfied fn main() {} diff --git a/tests/ui/delegation/self-ty-ice-156388.stderr b/tests/ui/delegation/self-ty-ice-156388.stderr index c2323cf1c6082..a311635db608a 100644 --- a/tests/ui/delegation/self-ty-ice-156388.stderr +++ b/tests/ui/delegation/self-ty-ice-156388.stderr @@ -1,10 +1,14 @@ -error: delegation self type is not specified - --> $DIR/self-ty-ice-156388.rs:5:16 +error[E0277]: the trait bound `Self: [const] Default` is not satisfied + --> $DIR/self-ty-ice-156388.rs:6:16 | LL | reuse Default::default; | ^^^^^^^ | - = help: consider explicitly specifying self type: `reuse ::function` +help: consider restricting type parameter `Self` with trait `Default` + | +LL | reuse Default::default [const] std::default::Default; + | +++++++++++++++++++++++++++++ error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/delegation/target-expr.rs b/tests/ui/delegation/target-expr.rs index 14232d194a740..b4b3a31f437fc 100644 --- a/tests/ui/delegation/target-expr.rs +++ b/tests/ui/delegation/target-expr.rs @@ -15,7 +15,6 @@ fn foo(x: i32) -> i32 { x } fn bar(_: T) { reuse Trait::static_method { - //~^ ERROR: delegation self type is not specified let _ = T::Default(); //~^ ERROR can't use generic parameters from outer item } diff --git a/tests/ui/delegation/target-expr.stderr b/tests/ui/delegation/target-expr.stderr index 9126234a2c3cd..2ceefbf929b9f 100644 --- a/tests/ui/delegation/target-expr.stderr +++ b/tests/ui/delegation/target-expr.stderr @@ -1,18 +1,17 @@ error[E0401]: can't use generic parameters from outer item - --> $DIR/target-expr.rs:19:17 + --> $DIR/target-expr.rs:18:17 | LL | fn bar(_: T) { | - type parameter from outer item LL | reuse Trait::static_method { | ------------- generic parameter used in this inner delegated function -LL | LL | let _ = T::Default(); | ^ use of generic parameter from outer item | = note: nested items are independent from their parent item for everything except for privacy and name resolution error[E0434]: can't capture dynamic environment in a fn item - --> $DIR/target-expr.rs:27:17 + --> $DIR/target-expr.rs:26:17 | LL | let x = y; | ^ @@ -20,7 +19,7 @@ LL | let x = y; = help: use the `|| { ... }` closure form instead error[E0424]: expected value, found module `self` - --> $DIR/target-expr.rs:34:5 + --> $DIR/target-expr.rs:33:5 | LL | fn main() { | ---- this function can't have a `self` parameter @@ -29,26 +28,18 @@ LL | self.0; | ^^^^ `self` value is a keyword only available in methods with a `self` parameter error[E0425]: cannot find value `x` in this scope - --> $DIR/target-expr.rs:36:13 + --> $DIR/target-expr.rs:35:13 | LL | let z = x; | ^ | help: the binding `x` is available in a different scope in the same function - --> $DIR/target-expr.rs:27:13 + --> $DIR/target-expr.rs:26:13 | LL | let x = y; | ^ -error: delegation self type is not specified - --> $DIR/target-expr.rs:17:18 - | -LL | reuse Trait::static_method { - | ^^^^^^^^^^^^^ - | - = help: consider explicitly specifying self type: `reuse ::function` - -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0401, E0424, E0425, E0434. For more information about an error, try `rustc --explain E0401`. diff --git a/tests/ui/delegation/unsupported.current.stderr b/tests/ui/delegation/unsupported.current.stderr index fdfd9251b4650..6cdd54e2e27fc 100644 --- a/tests/ui/delegation/unsupported.current.stderr +++ b/tests/ui/delegation/unsupported.current.stderr @@ -20,14 +20,6 @@ LL | reuse ToReuse::opaque_ret; = note: cycle used when checking assoc item `opaque::::opaque_ret` is compatible with trait definition = note: for more information, see and -error: delegation self type is not specified - --> $DIR/unsupported.rs:54:18 - | -LL | reuse Trait::foo; - | ^^^ - | - = help: consider explicitly specifying self type: `reuse ::function` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/delegation/unsupported.next.stderr b/tests/ui/delegation/unsupported.next.stderr index fdfd9251b4650..6cdd54e2e27fc 100644 --- a/tests/ui/delegation/unsupported.next.stderr +++ b/tests/ui/delegation/unsupported.next.stderr @@ -20,14 +20,6 @@ LL | reuse ToReuse::opaque_ret; = note: cycle used when checking assoc item `opaque::::opaque_ret` is compatible with trait definition = note: for more information, see and -error: delegation self type is not specified - --> $DIR/unsupported.rs:54:18 - | -LL | reuse Trait::foo; - | ^^^ - | - = help: consider explicitly specifying self type: `reuse ::function` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/delegation/unsupported.rs b/tests/ui/delegation/unsupported.rs index 3349c4ec27ab1..3da1206b5b2df 100644 --- a/tests/ui/delegation/unsupported.rs +++ b/tests/ui/delegation/unsupported.rs @@ -52,7 +52,6 @@ mod effects { } reuse Trait::foo; - //~^ ERROR: delegation self type is not specified } fn main() {} From 2172c51b05018bac56cfb75af4f009d58aab53f1 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Tue, 23 Jun 2026 00:37:42 +0100 Subject: [PATCH 33/42] triagebot: Stop pinging myself https://www.github.com/rust-lang/team/pull/2523 --- triagebot.toml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index d68e4a4882159..9fd7bad75160f 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1155,7 +1155,6 @@ otherwise, make sure you bump the `FORMAT_VERSION` constant. """ cc = [ "@CraftSpider", - "@aDotInTheVoid", "@Enselic", "@obi1kenobi", ] @@ -1313,7 +1312,7 @@ Please ensure that if you've changed the output: - It's intentional. - The `FORMAT_VERSION` in `src/librustdoc-json-types` is bumped if necessary. """ -cc = ["@aDotInTheVoid", "@obi1kenobi"] +cc = ["@obi1kenobi"] [mentions."tests/ui/derives/deriving-all-codegen.stdout"] message = "Changes to the code generated for builtin derived traits." @@ -1698,7 +1697,7 @@ dep-bumps = [ "/tests/rustdoc-gui" = ["rustdoc"] "/tests/rustdoc-js-std" = ["rustdoc"] "/tests/rustdoc-js/" = ["rustdoc"] -"/tests/rustdoc-json" = ["@aDotInTheVoid"] +"/tests/rustdoc-json" = ["rustdoc"] "/tests/rustdoc-ui" = ["rustdoc"] "/tests/ui" = ["compiler"] "/tests/ui-fulldeps" = ["compiler"] From 1bdb472b1faf52f5728095121e5e7ba2b607168e Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Tue, 23 Jun 2026 01:15:32 +0000 Subject: [PATCH 34/42] Add test. --- tests/ui/uninhabited/void-branch.rs | 10 +++++++ tests/ui/uninhabited/void-branch.stderr | 36 ++++++++++++++++++++----- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/tests/ui/uninhabited/void-branch.rs b/tests/ui/uninhabited/void-branch.rs index b9e1d70382910..f39cdbae56594 100644 --- a/tests/ui/uninhabited/void-branch.rs +++ b/tests/ui/uninhabited/void-branch.rs @@ -29,4 +29,14 @@ fn with_infallible() { println!() } +fn infallible_with_arg(x: T) -> (T, std::convert::Infallible) { + (x, loop {}) + //~^ ERROR unreachable expression +} + +fn in_if_else(x: String) -> Result { + if x.len() > 0 { Err(infallible_with_arg(x)) } else { Ok(x) } + //~^ ERROR unreachable expression +} + fn main() {} diff --git a/tests/ui/uninhabited/void-branch.stderr b/tests/ui/uninhabited/void-branch.stderr index 15693fc85f4b6..ad30057030870 100644 --- a/tests/ui/uninhabited/void-branch.stderr +++ b/tests/ui/uninhabited/void-branch.stderr @@ -1,3 +1,18 @@ +error: unreachable expression + --> $DIR/void-branch.rs:33:5 + | +LL | (x, loop {}) + | ^^^^-------^ + | | | + | | any code following this expression is unreachable + | unreachable expression + | +note: the lint level is defined here + --> $DIR/void-branch.rs:1:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + error: unreachable expression --> $DIR/void-branch.rs:10:13 | @@ -11,11 +26,6 @@ note: this expression has type `Void`, which is uninhabited | LL | std::mem::uninitialized::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: the lint level is defined here - --> $DIR/void-branch.rs:1:9 - | -LL | #![deny(unreachable_code)] - | ^^^^^^^^^^^^^^^^ error: unreachable expression --> $DIR/void-branch.rs:25:9 @@ -31,5 +41,19 @@ note: this expression has type `Infallible`, which is uninhabited LL | infallible(); | ^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: unreachable expression + --> $DIR/void-branch.rs:38:48 + | +LL | if x.len() > 0 { Err(infallible_with_arg(x)) } else { Ok(x) } + | ----------------------^ unreachable expression + | | + | any code following this expression is unreachable + | +note: this expression has type `(String, Infallible)`, which is uninhabited + --> $DIR/void-branch.rs:38:26 + | +LL | if x.len() > 0 { Err(infallible_with_arg(x)) } else { Ok(x) } + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors From 490d32c3beec697465459d2683b6ff12ecddc170 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Mon, 22 Jun 2026 01:19:17 +0000 Subject: [PATCH 35/42] Follow goto and drop when linting unreachable code. This removes a few false-positives due to extraneous drops. --- .../src/lint_and_remove_uninhabited.rs | 23 ++++++++++++++----- library/std/src/sync/poison.rs | 3 --- tests/ui/uninhabited/void-branch.rs | 1 - tests/ui/uninhabited/void-branch.stderr | 16 +------------ 4 files changed, 18 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_mir_transform/src/lint_and_remove_uninhabited.rs b/compiler/rustc_mir_transform/src/lint_and_remove_uninhabited.rs index 81e98585995fd..b359077753fd6 100644 --- a/compiler/rustc_mir_transform/src/lint_and_remove_uninhabited.rs +++ b/compiler/rustc_mir_transform/src/lint_and_remove_uninhabited.rs @@ -93,8 +93,8 @@ fn find_unreachable_code_from<'tcx>( bb: BasicBlock, body: &Body<'tcx>, ) -> Option<(SourceInfo, &'static str)> { - let bb = &body.basic_blocks[bb]; - for stmt in &bb.statements { + let bbdata = &body.basic_blocks[bb]; + for stmt in &bbdata.statements { match &stmt.kind { // Ignore the implicit `()` return place assignment for unit functions/blocks StatementKind::Assign((_, Rvalue::Use(Operand::Constant(const_), _))) @@ -108,7 +108,10 @@ fn find_unreachable_code_from<'tcx>( StatementKind::Assign((place, _)) if place.as_local() == Some(RETURN_PLACE) => { continue; } - StatementKind::StorageLive(_) | StatementKind::StorageDead(_) => { + // Ignore statements inserted by MIR building that do not correspond to user code. + StatementKind::StorageLive(_) + | StatementKind::StorageDead(_) + | StatementKind::BackwardIncompatibleDropHint { .. } => { continue; } StatementKind::FakeRead(..) => return Some((stmt.source_info, "definition")), @@ -116,10 +119,18 @@ fn find_unreachable_code_from<'tcx>( } } - let term = bb.terminator(); + let term = bbdata.terminator(); match term.kind { - // No user code in this bb, and our goto target may be reachable via other paths - TerminatorKind::Goto { .. } | TerminatorKind::Return => None, + // The user does not care for `goto` and compiler-generated drops. If the target block is + // only reachable through those terminators, continue searching there. + TerminatorKind::Goto { target } | TerminatorKind::Drop { target, .. } => { + if &body.basic_blocks.predecessors()[target][..] == &[bb] { + find_unreachable_code_from(target, body) + } else { + None + } + } + TerminatorKind::Return => None, _ => Some((term.source_info, "expression")), } } diff --git a/library/std/src/sync/poison.rs b/library/std/src/sync/poison.rs index 9f40c01546632..ee7e5f8586700 100644 --- a/library/std/src/sync/poison.rs +++ b/library/std/src/sync/poison.rs @@ -57,9 +57,6 @@ //! //! [`Once`]: crate::sync::Once -// If we are not unwinding, `PoisonError` is uninhabited. -#![cfg_attr(not(panic = "unwind"), expect(unreachable_code))] - #[stable(feature = "rust1", since = "1.0.0")] pub use self::condvar::Condvar; #[unstable(feature = "mapped_lock_guards", issue = "117108")] diff --git a/tests/ui/uninhabited/void-branch.rs b/tests/ui/uninhabited/void-branch.rs index f39cdbae56594..0f3e6987fead5 100644 --- a/tests/ui/uninhabited/void-branch.rs +++ b/tests/ui/uninhabited/void-branch.rs @@ -36,7 +36,6 @@ fn infallible_with_arg(x: T) -> (T, std::convert::Infallible) { fn in_if_else(x: String) -> Result { if x.len() > 0 { Err(infallible_with_arg(x)) } else { Ok(x) } - //~^ ERROR unreachable expression } fn main() {} diff --git a/tests/ui/uninhabited/void-branch.stderr b/tests/ui/uninhabited/void-branch.stderr index ad30057030870..7d886056098aa 100644 --- a/tests/ui/uninhabited/void-branch.stderr +++ b/tests/ui/uninhabited/void-branch.stderr @@ -41,19 +41,5 @@ note: this expression has type `Infallible`, which is uninhabited LL | infallible(); | ^^^^^^^^^^^^ -error: unreachable expression - --> $DIR/void-branch.rs:38:48 - | -LL | if x.len() > 0 { Err(infallible_with_arg(x)) } else { Ok(x) } - | ----------------------^ unreachable expression - | | - | any code following this expression is unreachable - | -note: this expression has type `(String, Infallible)`, which is uninhabited - --> $DIR/void-branch.rs:38:26 - | -LL | if x.len() > 0 { Err(infallible_with_arg(x)) } else { Ok(x) } - | ^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors From 24d44396b5be47a535bf5349d4df02e7c87b5305 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Mon, 22 Jun 2026 13:47:30 +0000 Subject: [PATCH 36/42] Use `cfg_select` in `std::os` This reverts commit 7bc501687b39a9d47938c58f2661b54f014ff7d3. --- library/std/src/os/mod.rs | 183 ++++++++++++++------------------------ 1 file changed, 66 insertions(+), 117 deletions(-) diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs index 76374402be4b3..44ddb55c920f4 100644 --- a/library/std/src/os/mod.rs +++ b/library/std/src/os/mod.rs @@ -6,121 +6,83 @@ pub mod raw; -// The code below could be written clearer using `cfg_if!`. However, the items below are -// publicly exported by `std` and external tools can have trouble analysing them because of the use -// of a macro that is not vendored by Rust and included in the toolchain. -// See https://github.com/rust-analyzer/rust-analyzer/issues/6038. +// # Important platforms -// On certain platforms right now the "main modules" modules that are -// documented don't compile (missing things in `libc` which is empty), -// so just omit them with an empty module and add the "unstable" attribute. - -// darwin, unix, linux, wasi and windows are handled a bit differently. -#[cfg(all( - doc, - any( - all(target_arch = "wasm32", not(target_os = "wasi")), - all(target_vendor = "fortanix", target_env = "sgx") - ) -))] -#[unstable(issue = "none", feature = "std_internals")] -pub mod darwin {} -#[cfg(all( - doc, - any( - all(target_arch = "wasm32", not(target_os = "wasi")), - all(target_vendor = "fortanix", target_env = "sgx") - ) -))] -#[unstable(issue = "none", feature = "std_internals")] -pub mod unix {} -#[cfg(all( - doc, - any( - all(target_arch = "wasm32", not(target_os = "wasi")), - all(target_vendor = "fortanix", target_env = "sgx") - ) -))] -#[unstable(issue = "none", feature = "std_internals")] -pub mod linux {} -#[cfg(all( - doc, - any( - all(target_arch = "wasm32", not(target_os = "wasi")), - all(target_vendor = "fortanix", target_env = "sgx") - ) -))] -#[unstable(issue = "none", feature = "std_internals")] -pub mod wasi {} -#[cfg(all( - doc, +// We always want to show documentation for the most important platforms, +// so these are handled specially here. +// +// FIXME: On certain platforms compilation errors (due to empty `libc`), +// prevent this, so we substitute an unstable empty module. +#[cfg(doc)] +cfg_select! { any( all(target_arch = "wasm32", not(target_os = "wasi")), all(target_vendor = "fortanix", target_env = "sgx") - ) -))] -#[unstable(issue = "none", feature = "std_internals")] -pub mod windows {} + ) => { + #[unstable(issue = "none", feature = "std_internals")] + pub mod darwin {} -// darwin -#[cfg(not(all( - doc, - any( - all(target_arch = "wasm32", not(target_os = "wasi")), - all(target_vendor = "fortanix", target_env = "sgx") - ) -)))] -#[cfg(any(target_vendor = "apple", doc))] -pub mod darwin; + #[unstable(issue = "none", feature = "std_internals")] + pub mod unix {} -// unix -#[cfg(not(all( - doc, - any( - all(target_arch = "wasm32", not(target_os = "wasi")), - all(target_vendor = "fortanix", target_env = "sgx") - ) -)))] -#[cfg(all(not(target_os = "hermit"), any(unix, doc)))] -pub mod unix; + #[unstable(issue = "none", feature = "std_internals")] + pub mod linux {} -// linux -#[cfg(not(all( - doc, - any( - all(target_arch = "wasm32", not(target_os = "wasi")), - all(target_vendor = "fortanix", target_env = "sgx") - ) -)))] -#[cfg(any(target_os = "linux", doc))] -pub mod linux; + #[unstable(issue = "none", feature = "std_internals")] + pub mod wasi {} -// wasi -#[cfg(not(all( - doc, - any( - all(target_arch = "wasm32", not(target_os = "wasi")), - all(target_vendor = "fortanix", target_env = "sgx") - ) -)))] -#[cfg(any(target_os = "wasi", any(target_env = "p1", target_env = "p2"), doc))] -pub mod wasi; + #[unstable(issue = "none", feature = "std_internals")] + pub mod windows {} + } + _ => { + // important platforms + pub mod darwin; + pub mod linux; + pub mod unix; + pub mod wasi; + pub mod wasip2; + pub mod windows; + } +} +#[cfg(not(doc))] // to prevent double module declarations +cfg_select! { + target_family = "unix" => { + pub mod unix; + #[cfg(target_vendor = "apple")] + pub mod darwin; + #[cfg(target_os = "linux")] + pub mod linux; + } + target_family = "wasm" => { + #[cfg(any(target_env = "p1", target_env = "p2"))] + pub mod wasi; + #[cfg(target_env = "p2")] + pub mod wasip2; + } + target_family = "windows" => { + pub mod windows; + } + _ => { /* handled below */ } +} -#[cfg(any(all(target_os = "wasi", target_env = "p2"), doc))] -pub mod wasip2; +// # Special modules -// windows -#[cfg(not(all( - doc, - any( - all(target_arch = "wasm32", not(target_os = "wasi")), - all(target_vendor = "fortanix", target_env = "sgx") - ) -)))] -#[cfg(any(windows, doc))] -pub mod windows; +#[cfg(any( + unix, + target_os = "hermit", + target_os = "trusty", + target_os = "wasi", + target_os = "motor", + doc +))] +pub mod fd; + +#[cfg(any(target_os = "linux", target_os = "android", target_os = "cygwin", doc))] +mod net; + +// # Ordinary platforms +// `cfg(doc)` not handled specially -// Others. #[cfg(target_os = "aix")] pub mod aix; #[cfg(target_os = "android")] @@ -183,16 +145,3 @@ pub mod vita; pub mod vxworks; #[cfg(target_os = "xous")] pub mod xous; - -#[cfg(any( - unix, - target_os = "hermit", - target_os = "trusty", - target_os = "wasi", - target_os = "motor", - doc -))] -pub mod fd; - -#[cfg(any(target_os = "linux", target_os = "android", target_os = "cygwin", doc))] -mod net; From 5d07ed58ead1b457aa52e6c5c62753764198d069 Mon Sep 17 00:00:00 2001 From: Arhan Chaudhary Date: Tue, 23 Jun 2026 05:09:58 +0000 Subject: [PATCH 37/42] slice_split_once: bounds check optimization note --- library/core/src/slice/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 9b077f1f9c1bd..7ab476e785d16 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -2530,6 +2530,7 @@ impl [T] { F: FnMut(&T) -> bool, { let index = self.iter().position(pred)?; + // Slice bounds checks optimized are away (as of June 2026) Some((&self[..index], &self[index + 1..])) } @@ -2558,6 +2559,7 @@ impl [T] { F: FnMut(&T) -> bool, { let index = self.iter().rposition(pred)?; + // Slice bounds checks optimized are away (as of June 2026) Some((&self[..index], &self[index + 1..])) } From e638ebef2b89e25a872504d5632d91eb6af37d8a Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 15 Jun 2026 19:50:56 +0200 Subject: [PATCH 38/42] Lift the same-signature restriction for `extern "tail"` --- compiler/rustc_codegen_ssa/src/mir/block.rs | 5 +- compiler/rustc_hir_typeck/src/check.rs | 2 +- .../rustc_mir_build/src/check_tail_calls.rs | 21 +++++++- compiler/rustc_target/src/callconv/mod.rs | 3 ++ compiler/rustc_ty_utils/src/abi.rs | 6 ++- .../no-unsized-arguments.aarch64.stderr | 31 ++++++++++++ .../no-unsized-arguments.rs | 50 +++++++++++++++++++ .../no-unsized-arguments.x86.stderr | 31 ++++++++++++ .../no-unsized-arguments.x86_64.stderr | 31 ++++++++++++ .../explicit-tail-calls/signature-mismatch.rs | 12 +++-- .../signature-mismatch.stderr | 17 +++++-- .../tailcc-no-signature-restriction.rs | 49 ++++++++++++++++++ 12 files changed, 245 insertions(+), 13 deletions(-) create mode 100644 tests/ui/explicit-tail-calls/no-unsized-arguments.aarch64.stderr create mode 100644 tests/ui/explicit-tail-calls/no-unsized-arguments.rs create mode 100644 tests/ui/explicit-tail-calls/no-unsized-arguments.x86.stderr create mode 100644 tests/ui/explicit-tail-calls/no-unsized-arguments.x86_64.stderr create mode 100644 tests/ui/explicit-tail-calls/tailcc-no-signature-restriction.rs diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index d4932adeda1f9..ab983ceb72ffc 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1317,7 +1317,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } LocalRef::Operand(arg) => { let Ref(place_value) = arg.val else { - bug!("only `Ref` should use `PassMode::Indirect`"); + bug!( + "only `Ref` should use `PassMode::Indirect`, but got {:?}", + arg.val + ); }; bx.typed_place_copy(place_value, tmp.val, fn_abi.args[i].layout); op.val = arg.val; diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 5fe1f4191c93f..1780430567a80 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -90,7 +90,7 @@ pub(super) fn check_fn<'a, 'tcx>( } // Check that argument is Sized. - if !params_can_be_unsized { + if !params_can_be_unsized || fn_sig.abi() == rustc_abi::ExternAbi::RustTail { fcx.require_type_is_sized( param_ty, param.ty_span, diff --git a/compiler/rustc_mir_build/src/check_tail_calls.rs b/compiler/rustc_mir_build/src/check_tail_calls.rs index 8052ee26df841..ac9f6e384cf04 100644 --- a/compiler/rustc_mir_build/src/check_tail_calls.rs +++ b/compiler/rustc_mir_build/src/check_tail_calls.rs @@ -147,7 +147,9 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> { // ``` // we should think what is the expected behavior here. // (we should probably just accept this by revealing opaques?) - if caller_sig.inputs_and_output != callee_sig.inputs_and_output { + if caller_sig.inputs_and_output != callee_sig.inputs_and_output + && !matches!(callee_sig.abi(), ExternAbi::RustTail) + { let caller_ty = self.tcx.type_of(self.caller_def_id).skip_binder(); self.report_signature_mismatch( @@ -189,6 +191,12 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> { if callee_sig.c_variadic() { self.report_c_variadic_callee(expr.span); } + + for &arg_ty in callee_sig.inputs() { + if !arg_ty.is_sized(self.tcx, self.typing_env) { + self.report_unsized_argument(expr.span, arg_ty); + } + } } /// Returns true if the caller function needs a location argument @@ -417,6 +425,17 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> { self.found_errors = Err(err); } + + fn report_unsized_argument(&mut self, sp: Span, arg_ty: Ty<'tcx>) { + let err = self + .tcx + .dcx() + .struct_span_err(sp, format!("unsized arguments cannot be used in a tail call")) + .with_note(format!("unsized argument of type `{arg_ty}`")) + .emit(); + + self.found_errors = Err(err); + } } impl<'a, 'tcx> Visitor<'a, 'tcx> for TailCallCkVisitor<'a, 'tcx> { diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index 7e1eafa10097f..30d16b5c7b1c9 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -827,6 +827,9 @@ impl<'a, Ty> FnAbi<'a, Ty> { ArgAttribute::default() }; arg.cast_to_with_attrs(Reg { kind: RegKind::Integer, size }, attr.into()); + } else if self.conv == CanonAbi::RustTail { + assert!(arg.layout.is_sized(), "extern \"tail\" arguments must be sized"); + arg.pass_by_stack_offset(None); } } diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index e782557d126bf..5c67021c59c59 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -458,8 +458,10 @@ fn fn_abi_sanity_check<'tcx>( // omitted entirely in the calling convention. assert!(arg.is_ignore()); } - if let PassMode::Indirect { on_stack, .. } = arg.mode { - assert!(!on_stack, "rust abi shouldn't use on_stack"); + if let PassMode::Indirect { on_stack, .. } = arg.mode + && spec_abi != ExternAbi::RustTail + { + assert!(!on_stack, "rustic abi {spec_abi:?} shouldn't use on_stack"); } } else if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { assert_matches!( diff --git a/tests/ui/explicit-tail-calls/no-unsized-arguments.aarch64.stderr b/tests/ui/explicit-tail-calls/no-unsized-arguments.aarch64.stderr new file mode 100644 index 0000000000000..33e190e1a4a7f --- /dev/null +++ b/tests/ui/explicit-tail-calls/no-unsized-arguments.aarch64.stderr @@ -0,0 +1,31 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/no-unsized-arguments.rs:40:42 + | +LL | extern "tail" fn unsized_argument(x: [u8]) -> u8 { + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +help: function arguments must have a statically known size, borrowed slices always have a known size + | +LL | extern "tail" fn unsized_argument(x: &[u8]) -> u8 { + | + + +error: unsized arguments cannot be used in a tail call + --> $DIR/no-unsized-arguments.rs:33:5 + | +LL | become unsized_argument(b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: unsized argument of type `[u8]` + +error: unsized arguments cannot be used in a tail call + --> $DIR/no-unsized-arguments.rs:48:5 + | +LL | become unsized_argument(*b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: unsized argument of type `[u8]` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/explicit-tail-calls/no-unsized-arguments.rs b/tests/ui/explicit-tail-calls/no-unsized-arguments.rs new file mode 100644 index 0000000000000..a0c5b53d8df0c --- /dev/null +++ b/tests/ui/explicit-tail-calls/no-unsized-arguments.rs @@ -0,0 +1,50 @@ +//@ add-minicore +//@ ignore-backends: gcc +//@ min-llvm-version: 22 +// +//@ revisions: x86 x86_64 aarch64 +// +//@ [x86] compile-flags: --target=i686-unknown-linux-gnu +//@ [x86] needs-llvm-components: x86 +//@ [x86_64] compile-flags: --target=x86_64-unknown-linux-gnu +//@ [x86_64] needs-llvm-components: x86 +//@ [aarch64] compile-flags: --target=aarch64-unknown-linux-gnu +//@ [aarch64] needs-llvm-components: aarch64 +#![feature(explicit_tail_calls, rust_tail_cc, unsized_fn_params, no_core)] +#![allow(incomplete_features, internal_features)] +#![no_core] +#![crate_type = "lib"] + +extern crate minicore; +use minicore::*; + +extern "C" { + fn extract(_: [u8]) -> u8; +} + +fn vanilla(b: [u8]) -> u8 { + fn unsized_argument(x: [u8]) -> u8 { + unsafe { extract(x) } + } + + // Non-tail call. + let _ = unsized_argument(b); + + become unsized_argument(b); + //~^ ERROR unsized arguments cannot be used in a tail call +} + +extern "tail" fn tailcc(b: &[u8]) -> u8 { + // `extern "tail"` is special because we also can't unsized parameters in standard definitions + // and calls. + extern "tail" fn unsized_argument(x: [u8]) -> u8 { + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + unsafe { extract(x) } + } + + // Vanilla call. + let _ = unsized_argument(*b); + + become unsized_argument(*b); + //~^ ERROR unsized arguments cannot be used in a tail call +} diff --git a/tests/ui/explicit-tail-calls/no-unsized-arguments.x86.stderr b/tests/ui/explicit-tail-calls/no-unsized-arguments.x86.stderr new file mode 100644 index 0000000000000..33e190e1a4a7f --- /dev/null +++ b/tests/ui/explicit-tail-calls/no-unsized-arguments.x86.stderr @@ -0,0 +1,31 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/no-unsized-arguments.rs:40:42 + | +LL | extern "tail" fn unsized_argument(x: [u8]) -> u8 { + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +help: function arguments must have a statically known size, borrowed slices always have a known size + | +LL | extern "tail" fn unsized_argument(x: &[u8]) -> u8 { + | + + +error: unsized arguments cannot be used in a tail call + --> $DIR/no-unsized-arguments.rs:33:5 + | +LL | become unsized_argument(b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: unsized argument of type `[u8]` + +error: unsized arguments cannot be used in a tail call + --> $DIR/no-unsized-arguments.rs:48:5 + | +LL | become unsized_argument(*b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: unsized argument of type `[u8]` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/explicit-tail-calls/no-unsized-arguments.x86_64.stderr b/tests/ui/explicit-tail-calls/no-unsized-arguments.x86_64.stderr new file mode 100644 index 0000000000000..33e190e1a4a7f --- /dev/null +++ b/tests/ui/explicit-tail-calls/no-unsized-arguments.x86_64.stderr @@ -0,0 +1,31 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/no-unsized-arguments.rs:40:42 + | +LL | extern "tail" fn unsized_argument(x: [u8]) -> u8 { + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +help: function arguments must have a statically known size, borrowed slices always have a known size + | +LL | extern "tail" fn unsized_argument(x: &[u8]) -> u8 { + | + + +error: unsized arguments cannot be used in a tail call + --> $DIR/no-unsized-arguments.rs:33:5 + | +LL | become unsized_argument(b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: unsized argument of type `[u8]` + +error: unsized arguments cannot be used in a tail call + --> $DIR/no-unsized-arguments.rs:48:5 + | +LL | become unsized_argument(*b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: unsized argument of type `[u8]` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/explicit-tail-calls/signature-mismatch.rs b/tests/ui/explicit-tail-calls/signature-mismatch.rs index a32ac9d8bfee3..bed480f60f63b 100644 --- a/tests/ui/explicit-tail-calls/signature-mismatch.rs +++ b/tests/ui/explicit-tail-calls/signature-mismatch.rs @@ -1,5 +1,5 @@ #![expect(incomplete_features)] -#![feature(explicit_tail_calls)] +#![feature(explicit_tail_calls, rust_tail_cc)] #![feature(c_variadic)] fn _f0((): ()) { @@ -8,26 +8,30 @@ fn _f0((): ()) { fn _g0() {} - fn _f1() { become _g1(()); //~ error: mismatched signatures } fn _g1((): ()) {} - extern "C" fn _f2() { become _g2(); //~ error: mismatched function ABIs } fn _g2() {} - fn _f3() { become _g3(); //~ error: mismatched function ABIs } extern "C" fn _g3() {} +extern "tail" fn _tailcc() {} + +fn _f4() { + // tailcc does not need the signatures to match, + // but only tailcc can tail call tailcc. + become _tailcc(); //~ error: mismatched function ABIs +} fn main() {} diff --git a/tests/ui/explicit-tail-calls/signature-mismatch.stderr b/tests/ui/explicit-tail-calls/signature-mismatch.stderr index ba9e9dcb98483..6e26f1c075539 100644 --- a/tests/ui/explicit-tail-calls/signature-mismatch.stderr +++ b/tests/ui/explicit-tail-calls/signature-mismatch.stderr @@ -9,7 +9,7 @@ LL | become _g0(); = note: callee signature: `fn()` error: mismatched signatures - --> $DIR/signature-mismatch.rs:13:5 + --> $DIR/signature-mismatch.rs:12:5 | LL | become _g1(()); | ^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | become _g1(()); = note: callee signature: `fn(())` error: mismatched function ABIs - --> $DIR/signature-mismatch.rs:20:5 + --> $DIR/signature-mismatch.rs:18:5 | LL | become _g2(); | ^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | become _g2(); = note: caller ABI is `"C"`, while callee ABI is `"Rust"` error: mismatched function ABIs - --> $DIR/signature-mismatch.rs:27:5 + --> $DIR/signature-mismatch.rs:24:5 | LL | become _g3(); | ^^^^^^^^^^^^ @@ -36,5 +36,14 @@ LL | become _g3(); = note: `become` requires caller and callee to have the same ABI = note: caller ABI is `"Rust"`, while callee ABI is `"C"` -error: aborting due to 4 previous errors +error: mismatched function ABIs + --> $DIR/signature-mismatch.rs:34:5 + | +LL | become _tailcc(); + | ^^^^^^^^^^^^^^^^ + | + = note: `become` requires caller and callee to have the same ABI + = note: caller ABI is `"Rust"`, while callee ABI is `"tail"` + +error: aborting due to 5 previous errors diff --git a/tests/ui/explicit-tail-calls/tailcc-no-signature-restriction.rs b/tests/ui/explicit-tail-calls/tailcc-no-signature-restriction.rs new file mode 100644 index 0000000000000..9c9085ca1daca --- /dev/null +++ b/tests/ui/explicit-tail-calls/tailcc-no-signature-restriction.rs @@ -0,0 +1,49 @@ +//@ run-pass +//@ ignore-backends: gcc +//@ min-llvm-version: 22 +//@ revisions: x86_64 aarch64 +// +// FIXME: enable x86 on LLVM 23. +//@ [x86_64] only-x86_64 +//@ [aarch64] only-aarch64 +#![feature(explicit_tail_calls, rust_tail_cc)] + +#[inline(never)] +pub extern "tail" fn add() -> u64 { + #[inline(never)] + extern "tail" fn add(a: u64, b: u64) -> u64 { + a.wrapping_add(b) + } + + become add(1, 2); +} + +#[inline(never)] +pub extern "tail" fn pass_struct(a: u64, d: u64) -> u64 { + #[derive(Clone, Copy)] + pub struct Large { + pub a: u64, + pub b: u64, + pub c: u64, + pub d: u64, + } + + #[inline(never)] + extern "tail" fn add(large: Large) -> u64 { + let _ = large.b; + let _ = large.c; + large.a.wrapping_add(large.d) + } + + let large = Large { a, b: 0xBBBB_BBBB_BBBB_BBBB, c: 0xCCCC_CCCC_CCCC_CCCC, d }; + become add(large); +} + +fn main() { + assert_eq!(add(), 3); + + // FIXME: LLVM 22 has a bug which makes this miscompile. + if false { + assert_eq!(pass_struct(5, 6), 5 + 6); + } +} From 24a66cb151819237b6580ff3d7588a896983eda4 Mon Sep 17 00:00:00 2001 From: Eva van Houten Date: Mon, 22 Jun 2026 17:06:32 +0200 Subject: [PATCH 39/42] Improve unknown crate_type diagnostic suggestions --- .../src/attributes/crate_level.rs | 6 +- tests/ui/attributes/invalid-crate-type.rs | 49 ++++++++++++ tests/ui/attributes/invalid-crate-type.stderr | 74 ++++++++++++++++--- 3 files changed, 116 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs index eb78bc0775f6b..ac5251838300a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs +++ b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs @@ -2,7 +2,7 @@ use rustc_feature::AttributeStability; use rustc_hir::attrs::{CrateType, WindowsSubsystemKind}; use rustc_session::lint::builtin::UNKNOWN_CRATE_TYPES; use rustc_span::Symbol; -use rustc_span::edit_distance::find_best_match_for_name; +use rustc_span::edit_distance::find_best_match_for_name_with_substrings; use super::prelude::*; use crate::diagnostics::{UnknownCrateTypes, UnknownCrateTypesSuggestion}; @@ -49,10 +49,10 @@ impl CombineAttributeParser for CrateTypeParser { let Ok(crate_type) = crate_type.try_into() else { // We don't error on invalid `#![crate_type]` when not applied to a crate if cx.shared.target == Target::Crate { - let candidate = find_best_match_for_name( + let candidate = find_best_match_for_name_with_substrings( &CrateType::all_stable().iter().map(|(name, _)| *name).collect::>(), crate_type, - None, + Some(5), ); let span = n.value_span; cx.emit_lint( diff --git a/tests/ui/attributes/invalid-crate-type.rs b/tests/ui/attributes/invalid-crate-type.rs index c233e7d5e3db8..aea75f4cfad90 100644 --- a/tests/ui/attributes/invalid-crate-type.rs +++ b/tests/ui/attributes/invalid-crate-type.rs @@ -1,5 +1,8 @@ // regression test for issue 11256 #![crate_type="foo"] //~ ERROR invalid `crate_type` value +//~| NOTE `#[deny(unknown_crate_types)]` on by default +//~| HELP did you mean +//~| SUGGESTION lib // Tests for suggestions (#53958) @@ -43,6 +46,52 @@ //~| HELP did you mean //~| SUGGESTION cdylib +// substring matching tests +#![crate_type="binary"] +//~^ ERROR invalid `crate_type` value +//~| HELP did you mean +//~| SUGGESTION bin + +#![crate_type="library"] +//~^ ERROR invalid `crate_type` value +//~| HELP did you mean +//~| SUGGESTION lib + +#![crate_type="rustlib"] +//~^ ERROR invalid `crate_type` value +//~| HELP did you mean +//~| SUGGESTION rlib + +#![crate_type="dynamiclib"] +//~^ ERROR invalid `crate_type` value +//~| HELP did you mean +//~| SUGGESTION dylib + +#![crate_type="dylibrary"] +//~^ ERROR invalid `crate_type` value +//~| HELP did you mean +//~| SUGGESTION dylib + +#![crate_type="cdynamiclib"] +//~^ ERROR invalid `crate_type` value +//~| HELP did you mean +//~| SUGGESTION cdylib + +#![crate_type="cdylibrary"] +//~^ ERROR invalid `crate_type` value +//~| HELP did you mean +//~| SUGGESTION cdylib + +#![crate_type="staticlibrary"] +//~^ ERROR invalid `crate_type` value +//~| HELP did you mean +//~| SUGGESTION staticlib + +#![crate_type="procedural-macro"] +//~^ ERROR invalid `crate_type` value +//~| HELP did you mean +//~| SUGGESTION proc-macro + fn main() { return } diff --git a/tests/ui/attributes/invalid-crate-type.stderr b/tests/ui/attributes/invalid-crate-type.stderr index 3eae04678b4a7..2c7663b10925e 100644 --- a/tests/ui/attributes/invalid-crate-type.stderr +++ b/tests/ui/attributes/invalid-crate-type.stderr @@ -2,57 +2,111 @@ error: invalid `crate_type` value --> $DIR/invalid-crate-type.rs:2:15 | LL | #![crate_type="foo"] - | ^^^^^ + | ^^^^^ help: did you mean: `"lib"` | = note: `#[deny(unknown_crate_types)]` on by default error: invalid `crate_type` value - --> $DIR/invalid-crate-type.rs:6:15 + --> $DIR/invalid-crate-type.rs:9:15 | LL | #![crate_type="statoclib"] | ^^^^^^^^^^^ help: did you mean: `"staticlib"` error: invalid `crate_type` value - --> $DIR/invalid-crate-type.rs:11:15 + --> $DIR/invalid-crate-type.rs:14:15 | LL | #![crate_type="procmacro"] | ^^^^^^^^^^^ help: did you mean: `"proc-macro"` error: invalid `crate_type` value - --> $DIR/invalid-crate-type.rs:16:15 + --> $DIR/invalid-crate-type.rs:19:15 | LL | #![crate_type="static-lib"] | ^^^^^^^^^^^^ help: did you mean: `"staticlib"` error: invalid `crate_type` value - --> $DIR/invalid-crate-type.rs:21:15 + --> $DIR/invalid-crate-type.rs:24:15 | LL | #![crate_type="drylib"] | ^^^^^^^^ help: did you mean: `"dylib"` error: invalid `crate_type` value - --> $DIR/invalid-crate-type.rs:26:15 + --> $DIR/invalid-crate-type.rs:29:15 | LL | #![crate_type="dlib"] | ^^^^^^ help: did you mean: `"lib"` error: invalid `crate_type` value - --> $DIR/invalid-crate-type.rs:31:15 + --> $DIR/invalid-crate-type.rs:34:15 | LL | #![crate_type="lob"] | ^^^^^ help: did you mean: `"lib"` error: invalid `crate_type` value - --> $DIR/invalid-crate-type.rs:36:15 + --> $DIR/invalid-crate-type.rs:39:15 | LL | #![crate_type="bon"] | ^^^^^ help: did you mean: `"bin"` error: invalid `crate_type` value - --> $DIR/invalid-crate-type.rs:41:15 + --> $DIR/invalid-crate-type.rs:44:15 | LL | #![crate_type="cdalib"] | ^^^^^^^^ help: did you mean: `"cdylib"` -error: aborting due to 9 previous errors +error: invalid `crate_type` value + --> $DIR/invalid-crate-type.rs:50:15 + | +LL | #![crate_type="binary"] + | ^^^^^^^^ help: did you mean: `"bin"` + +error: invalid `crate_type` value + --> $DIR/invalid-crate-type.rs:55:15 + | +LL | #![crate_type="library"] + | ^^^^^^^^^ help: did you mean: `"lib"` + +error: invalid `crate_type` value + --> $DIR/invalid-crate-type.rs:60:15 + | +LL | #![crate_type="rustlib"] + | ^^^^^^^^^ help: did you mean: `"rlib"` + +error: invalid `crate_type` value + --> $DIR/invalid-crate-type.rs:65:15 + | +LL | #![crate_type="dynamiclib"] + | ^^^^^^^^^^^^ help: did you mean: `"dylib"` + +error: invalid `crate_type` value + --> $DIR/invalid-crate-type.rs:70:15 + | +LL | #![crate_type="dylibrary"] + | ^^^^^^^^^^^ help: did you mean: `"dylib"` + +error: invalid `crate_type` value + --> $DIR/invalid-crate-type.rs:75:15 + | +LL | #![crate_type="cdynamiclib"] + | ^^^^^^^^^^^^^ help: did you mean: `"cdylib"` + +error: invalid `crate_type` value + --> $DIR/invalid-crate-type.rs:80:15 + | +LL | #![crate_type="cdylibrary"] + | ^^^^^^^^^^^^ help: did you mean: `"cdylib"` + +error: invalid `crate_type` value + --> $DIR/invalid-crate-type.rs:85:15 + | +LL | #![crate_type="staticlibrary"] + | ^^^^^^^^^^^^^^^ help: did you mean: `"staticlib"` + +error: invalid `crate_type` value + --> $DIR/invalid-crate-type.rs:90:15 + | +LL | #![crate_type="procedural-macro"] + | ^^^^^^^^^^^^^^^^^^ help: did you mean: `"proc-macro"` + +error: aborting due to 18 previous errors From e290ddc80f7c119f328ba8c53ce23f45ce4c915f Mon Sep 17 00:00:00 2001 From: Roland Xu Date: Tue, 23 Jun 2026 21:38:57 +0800 Subject: [PATCH 40/42] mailmap: update mu001999 --- .mailmap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mailmap b/.mailmap index d1e5b3f519591..9166494632a00 100644 --- a/.mailmap +++ b/.mailmap @@ -491,7 +491,6 @@ Milan Landaverde mjptree Ms2ger msizanoen1 -mu001999 Mukilan Thiagarajan Nadrieril Feneanar Nadrieril Feneanar @@ -603,6 +602,7 @@ Robert Habermeier Robert Millar Roc Yu Rohit Joshi Rohit Joshi +Roland Xu Ross Smyth <18294397+RossSmyth@users.noreply.github.com> Ross Smyth <18294397+RossSmyth@users.noreply.github.com> Ross Smyth <18294397+RossSmyth@users.noreply.github.com> From bd73fb8e296503d9b7aecfe58350cce0bcc249ad Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 22 Jun 2026 17:49:19 +0200 Subject: [PATCH 41/42] Only load the feature list once in the entire resolver --- .../rustc_resolve/src/build_reduced_graph.rs | 10 ++++---- compiler/rustc_resolve/src/def_collector.rs | 4 ++-- compiler/rustc_resolve/src/error_helper.rs | 18 +++++++++------ compiler/rustc_resolve/src/ident.rs | 14 +++++------ compiler/rustc_resolve/src/imports.rs | 7 +++--- compiler/rustc_resolve/src/late.rs | 23 +++++++++---------- .../rustc_resolve/src/late/diagnostics.rs | 9 ++++---- compiler/rustc_resolve/src/lib.rs | 16 ++++++------- compiler/rustc_resolve/src/macros.rs | 11 ++++----- 9 files changed, 56 insertions(+), 56 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 911c6142e4b22..bb9bf8976f672 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -548,7 +548,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { root_id, vis, vis_span: item.vis.span, - on_unknown_attr: OnUnknownData::from_attrs(self.r.tcx, &item.attrs), + on_unknown_attr: OnUnknownData::from_attrs(self.r, &item.attrs), }); self.r.indeterminate_imports.push(import); @@ -863,7 +863,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { || ast::attr::contains_name(&item.attrs, sym::no_implicit_prelude), ); self.parent_scope.module = module.to_module(); - if let Some(directive) = OnUnknownData::from_attrs(self.r.tcx, &item.attrs) { + if let Some(directive) = OnUnknownData::from_attrs(self.r, &item.attrs) { self.r.on_unknown_data.insert(local_def_id, directive); } } @@ -1040,7 +1040,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { module_path: Vec::new(), vis, vis_span: item.vis.span, - on_unknown_attr: OnUnknownData::from_attrs(self.r.tcx, &item.attrs), + on_unknown_attr: OnUnknownData::from_attrs(self.r, &item.attrs), }); if used { self.r.import_use_map.insert(import, Used::Other); @@ -1172,7 +1172,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { module_path: Vec::new(), vis: Visibility::Restricted(CRATE_DEF_ID), vis_span: item.vis.span, - on_unknown_attr: OnUnknownData::from_attrs(this.r.tcx, &item.attrs), + on_unknown_attr: OnUnknownData::from_attrs(this.r, &item.attrs), }) }; @@ -1353,7 +1353,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { module_path: Vec::new(), vis, vis_span: item.vis.span, - on_unknown_attr: OnUnknownData::from_attrs(self.r.tcx, &item.attrs), + on_unknown_attr: OnUnknownData::from_attrs(self.r, &item.attrs), }); self.r.import_use_map.insert(import, Used::Other); let import_decl = self.r.new_import_decl(decl, import); diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index cdc2df5bf2945..a5049339382f7 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -186,7 +186,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { // Does that prevents errors from happening? maybe let mut parser = AttributeParser::new( &self.r.tcx.sess, - self.r.tcx.features(), + self.r.features, self.r.tcx().registered_tools(()), ShouldEmit::Nothing, ); @@ -433,7 +433,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { // `MgcaDisambiguation::Direct` is set even when MGCA is disabled, so // to avoid affecting stable we have to feature gate the not creating // anon consts - if !self.r.tcx.features().min_generic_const_args() { + if !self.r.features.min_generic_const_args() { let parent = self .create_def(constant.id, None, DefKind::AnonConst, constant.value.span) .def_id(); diff --git a/compiler/rustc_resolve/src/error_helper.rs b/compiler/rustc_resolve/src/error_helper.rs index 81c1b6fa8d675..1b7d799cadd35 100644 --- a/compiler/rustc_resolve/src/error_helper.rs +++ b/compiler/rustc_resolve/src/error_helper.rs @@ -1628,7 +1628,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { in_module.for_each_child(self, |this, ident, orig_ident_span, ns, name_binding| { // Avoid non-importable candidates. if name_binding.is_assoc_item() - && !this.tcx.features().import_trait_associated_functions() + && !this.features.import_trait_associated_functions() { return; } @@ -1809,10 +1809,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }) => { if span.allows_unstable(feature) { true - } else if self.tcx.features().enabled(feature) { + } else if self.features.enabled(feature) { true } else if let Some(implied_by) = implied_by - && self.tcx.features().enabled(implied_by) + && self.features.enabled(implied_by) { true } else { @@ -4144,13 +4144,17 @@ pub(crate) struct OnUnknownData { } impl OnUnknownData { - pub(crate) fn from_attrs<'tcx>( - tcx: TyCtxt<'tcx>, + pub(crate) fn from_attrs( + r: &Resolver<'_, '_>, attrs: &[ast::Attribute], ) -> Option { - if tcx.features().diagnostic_on_unknown() + if r.features.diagnostic_on_unknown() && let Some(Attribute::Parsed(AttributeKind::OnUnknown { directive, .. })) = - AttributeParser::parse_limited(tcx.sess, attrs, &[sym::diagnostic, sym::on_unknown]) + AttributeParser::parse_limited( + r.tcx.sess, + attrs, + &[sym::diagnostic, sym::on_unknown], + ) { Some(Self { directive: directive? }) } else { diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 2e69405811db4..574e932cc75d8 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -746,7 +746,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Scope::BuiltinTypes => match self.builtin_type_decls.get(&ident.name) { Some(decl) => { if matches!(ident.name, sym::f16) - && !self.tcx.features().f16() + && !self.features.f16() && !orig_ident_span.allows_unstable(sym::f16) && finalize.is_some() { @@ -759,7 +759,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .emit(); } if matches!(ident.name, sym::f128) - && !self.tcx.features().f128() + && !self.features.f128() && !orig_ident_span.allows_unstable(sym::f128) && finalize.is_some() { @@ -1535,7 +1535,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } RibKind::ConstParamTy => { - if !self.tcx.features().generic_const_parameter_types() { + if !self.features.generic_const_parameter_types() { if let Some(span) = finalize { self.report_error( span, @@ -1564,7 +1564,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } NoConstantGenericsReason::NonTrivialConstArg => { ResolutionError::ParamInNonTrivialAnonConst { - is_gca: self.tcx.features().generic_const_args(), + is_gca: self.features.generic_const_args(), name: rib_ident.name, param_kind: ParamKindInNonTrivialAnonConst::Type, } @@ -1629,7 +1629,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { | RibKind::ForwardGenericParamBan(_) => continue, RibKind::ConstParamTy => { - if !self.tcx.features().generic_const_parameter_types() { + if !self.features.generic_const_parameter_types() { if let Some(span) = finalize { self.report_error( span, @@ -1656,7 +1656,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } NoConstantGenericsReason::NonTrivialConstArg => { ResolutionError::ParamInNonTrivialAnonConst { - is_gca: self.tcx.features().generic_const_args(), + is_gca: self.features.generic_const_args(), name: rib_ident.name, param_kind: ParamKindInNonTrivialAnonConst::Const { name: rib_ident.name, @@ -2019,7 +2019,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { module, || { let import_inherent_item_error_flag = - self.tcx.features().import_trait_associated_functions() + self.features.import_trait_associated_functions() && matches!( res, Res::Def( diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index d823da9756c81..a3cb526e60a87 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -779,7 +779,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { match import_decls[ns] { PendingDecl::Ready(Some(import_decl)) => { if import_decl.is_assoc_item() - && !this.tcx.features().import_trait_associated_functions() + && !this.features.import_trait_associated_functions() { feature_err( this.tcx.sess, @@ -822,8 +822,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { continue; }; - if module.is_trait() && !self.tcx.features().import_trait_associated_functions() - { + if module.is_trait() && !self.features.import_trait_associated_functions() { feature_err( self.tcx.sess, sym::import_trait_associated_functions, @@ -1487,7 +1486,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // If importing of trait asscoiated items is enabled, an also find an // `Enum`, then note that inherent associated items cannot be imported. - let note = if self.tcx.features().import_trait_associated_functions() + let note = if self.features.import_trait_associated_functions() && let PathResult::Module(ModuleOrUniformRoot::Module(m)) = path_res && let Some(Res::Def(DefKind::Enum, _)) = m.res() { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index bf53b891a08f1..479af1582fd6f 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1664,7 +1664,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { }; // We'll ban these with a `ConstParamTy` rib, so just clear these ribs for better // diagnostics, so we don't mention anything about const param tys having generics at all. - if !self.r.tcx.features().generic_const_parameter_types() { + if !self.r.features.generic_const_parameter_types() { forward_ty_ban_rib_const_param_ty.bindings.clear(); forward_const_ban_rib_const_param_ty.bindings.clear(); } @@ -1701,7 +1701,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { this.ribs[TypeNS].push(forward_ty_ban_rib_const_param_ty); this.ribs[ValueNS].push(forward_const_ban_rib_const_param_ty); - if this.r.tcx.features().generic_const_parameter_types() { + if this.r.features.generic_const_parameter_types() { this.visit_ty(ty) } else { this.ribs[TypeNS].push(Rib::new(RibKind::ConstParamTy)); @@ -1812,8 +1812,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } LifetimeRibKind::ImplTrait => { - if self.r.tcx.features().anonymous_lifetime_in_impl_trait() - { + if self.r.features.anonymous_lifetime_in_impl_trait() { None } else { Some(LifetimeUseSet::Many) @@ -2991,7 +2990,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { self.with_generic_param_rib( &generics.params, RibKind::Item( - if self.r.tcx.features().generic_const_items() { + if self.r.features.generic_const_items() { HasGenericParams::Yes(generics.span) } else { HasGenericParams::No @@ -3008,7 +3007,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { LifetimeRibKind::Elided(LifetimeRes::Static), |this| { if rhs_kind.is_type_const() - && !this.r.tcx.features().generic_const_parameter_types() + && !this.r.features.generic_const_parameter_types() { this.with_rib(TypeNS, RibKind::ConstParamTy, |this| { this.with_rib(ValueNS, RibKind::ConstParamTy, |this| { @@ -3255,7 +3254,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { RibKind::Normal => { // FIXME(non_lifetime_binders): Stop special-casing // const params to error out here. - if self.r.tcx.features().non_lifetime_binders() + if self.r.features.non_lifetime_binders() && matches!(param.kind, GenericParamKind::Type { .. }) { Res::Def(def_kind, def_id.to_def_id()) @@ -3409,7 +3408,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |this| { this.visit_generics(generics); if rhs_kind.is_type_const() - && !this.r.tcx.features().generic_const_parameter_types() + && !this.r.features.generic_const_parameter_types() { this.with_rib(TypeNS, RibKind::ConstParamTy, |this| { this.with_rib(ValueNS, RibKind::ConstParamTy, |this| { @@ -5038,10 +5037,10 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let tcx = self.r.tcx(); let gate_err_sym_msg = match prim { - PrimTy::Float(FloatTy::F16) if !tcx.features().f16() => { + PrimTy::Float(FloatTy::F16) if !self.r.features.f16() => { Some((sym::f16, "the type `f16` is unstable")) } - PrimTy::Float(FloatTy::F128) if !tcx.features().f128() => { + PrimTy::Float(FloatTy::F128) if !self.r.features.f128() => { Some((sym::f128, "the type `f128` is unstable")) } _ => None, @@ -5196,8 +5195,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { AnonConstKind::FieldDefaultValue => ConstantHasGenerics::Yes, AnonConstKind::InlineConst => ConstantHasGenerics::Yes, AnonConstKind::ConstArg(_) => { - if self.r.tcx.features().generic_const_exprs() - || self.r.tcx.features().min_generic_const_args() + if self.r.features.generic_const_exprs() + || self.r.features.min_generic_const_args() || is_trivial_const_arg { ConstantHasGenerics::Yes diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 95fdf8124a225..045e0ff523c7d 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1775,8 +1775,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { // const generics. Of course, `Struct` and `Enum` may contain ty params, too, but the // benefits of including them here outweighs the small number of false positives. Some(Res::Def(DefKind::Struct | DefKind::Enum, _)) - if self.r.tcx.features().adt_const_params() - || self.r.tcx.features().min_adt_const_params() => + if self.r.features.adt_const_params() || self.r.features.min_adt_const_params() => { Applicability::MaybeIncorrect } @@ -3977,7 +3976,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { }) .emit(), NoConstantGenericsReason::NonTrivialConstArg => { - assert!(!self.r.tcx.features().generic_const_exprs()); + assert!(!self.r.features.generic_const_exprs()); self.r .dcx() .create_err(diagnostics::ParamInNonTrivialAnonConst { @@ -3985,8 +3984,8 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { name: lifetime_ref.ident.name, param_kind: diagnostics::ParamKindInNonTrivialAnonConst::Lifetime, help: self.r.tcx.sess.is_nightly_build(), - is_gca: self.r.tcx.features().generic_const_args(), - help_gca: self.r.tcx.features().generic_const_args(), + is_gca: self.r.features.generic_const_args(), + help_gca: self.r.features.generic_const_args(), }) .emit() } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 061471ccc97e0..1f1884ea0cbe2 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -50,7 +50,7 @@ use rustc_data_structures::sync::{FreezeReadGuard, FreezeWriteGuard}; use rustc_data_structures::unord::{UnordItems, UnordMap, UnordSet}; use rustc_errors::{Applicability, Diag, ErrCode, ErrorGuaranteed, LintBuffer}; use rustc_expand::base::{DeriveResolution, SyntaxExtension, SyntaxExtensionKind}; -use rustc_feature::BUILTIN_ATTRIBUTES; +use rustc_feature::{BUILTIN_ATTRIBUTES, Features}; use rustc_hir::attrs::StrippedCfgItem; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{ @@ -1550,7 +1550,8 @@ pub struct Resolver<'ra, 'tcx> { impl_trait_names: FxHashMap = default::fx_hash_map(), /// Stores `#[diagnostic::on_unknown]` attributes placed on module declarations. - on_unknown_data: FxHashMap, + on_unknown_data: FxHashMap = default::fx_hash_map(), + features: &'tcx Features, } /// This provides memory for the rest of the crate. The `'ra` lifetime that is @@ -1808,11 +1809,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let registered_tools = tcx.registered_tools(()); let edition = tcx.sess.edition(); - let mut on_unknown_data = default::fx_hash_map(); - if let Some(directive) = OnUnknownData::from_attrs(tcx, attrs) { - on_unknown_data.insert(CRATE_DEF_ID, directive); - } - let mut resolver = Resolver { tcx, @@ -1880,10 +1876,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { current_crate_outer_attr_insert_span, disambiguators: Default::default(), delegation_infos: Default::default(), - on_unknown_data, + features: tcx.features(), .. }; + if let Some(directive) = OnUnknownData::from_attrs(&resolver, attrs) { + resolver.on_unknown_data.insert(CRATE_DEF_ID, directive); + } + let root_parent_scope = ParentScope::module(graph_root, resolver.arenas); resolver.invocation_parent_scopes.insert(LocalExpnId::ROOT, root_parent_scope); resolver.feed_visibility(crate_feed, Visibility::Public); diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index fade23f9cf308..595c2fdf011dd 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -699,7 +699,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } // We are trying to avoid reporting this error if other related errors were reported. - if res != Res::Err && inner_attr && !self.tcx.features().custom_inner_attributes() { + if res != Res::Err && inner_attr && !self.features.custom_inner_attributes() { let is_macro = match res { Res::Def(..) => true, Res::NonMacroAttr(..) => false, @@ -727,8 +727,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { && let [namespace, attribute, ..] = &*path.segments && namespace.ident.name == sym::diagnostic && !DIAGNOSTIC_ATTRIBUTES.iter().any(|(attr, feature)| { - attribute.ident.name == *attr - && feature.is_none_or(|f| self.tcx.features().enabled(f)) + attribute.ident.name == *attr && feature.is_none_or(|f| self.features.enabled(f)) }) { let name = attribute.ident.name; @@ -750,7 +749,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let candidates = DIAGNOSTIC_ATTRIBUTES .iter() .filter_map(|(attr, feature)| { - feature.is_none_or(|f| self.tcx.features().enabled(f)).then_some(*attr) + feature.is_none_or(|f| self.features.enabled(f)).then_some(*attr) }) .collect::>(); @@ -1112,7 +1111,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let feature = stability.feature; let is_allowed = - |feature| self.tcx.features().enabled(feature) || span.allows_unstable(feature); + |feature| self.features.enabled(feature) || span.allows_unstable(feature); let allowed_by_implication = implied_by.is_some_and(|feature| is_allowed(feature)); if !is_allowed(feature) && !allowed_by_implication { stability::report_unstable( @@ -1242,7 +1241,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ) -> SyntaxExtension { let mut ext = compile_declarative_macro( self.tcx.sess, - self.tcx.features(), + self.features, macro_def, ident, attrs, From 480406069ac514c677d9f0fef043188921cea381 Mon Sep 17 00:00:00 2001 From: Mahdi Ali-Raihan Date: Sat, 20 Jun 2026 02:28:37 -0400 Subject: [PATCH 42/42] Added implementation on set_permissions_nofollow for all platforms supported (windows, unix, uefi, etc.); modified the Unix implementation to use fchmodat instead of open + fchmod; clarified documentations for set_permissions_nofollow; added a test case for set_permissions_nofollow --- library/std/src/fs.rs | 53 ++++++++++++++--- library/std/src/fs/tests.rs | 83 +++++++++++++++++++++++++++ library/std/src/sys/fs/hermit.rs | 4 ++ library/std/src/sys/fs/mod.rs | 24 +------- library/std/src/sys/fs/motor.rs | 5 ++ library/std/src/sys/fs/solid.rs | 5 ++ library/std/src/sys/fs/uefi.rs | 5 ++ library/std/src/sys/fs/unix.rs | 37 ++++++++++++ library/std/src/sys/fs/unsupported.rs | 4 ++ library/std/src/sys/fs/vexos.rs | 4 ++ library/std/src/sys/fs/windows.rs | 9 +++ 11 files changed, 203 insertions(+), 30 deletions(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 750ddb91c482b..05695dacbf912 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -3337,23 +3337,60 @@ pub fn set_permissions>(path: P, perm: Permissions) -> io::Result fs_imp::set_permissions(path.as_ref(), perm.0) } -/// Set the permissions of a file, unless it is a symlink. +/// Changes the permissions found on a file or a directory. On certain platforms, if the file +/// is a symlink, it will change the permissions bits on the symlink itself rather than +/// the target (e.g. Windows, BSD, MacOS). On other platforms, this results in an error when +/// attempting to change permissions on a symlink (e.g. Linux). /// -/// Note that the non-final path elements are allowed to be symlinks. +/// Note that non-final path elements are allowed to be symlinks. /// /// # Platform-specific behavior /// -/// Currently unimplemented on Windows. +/// This function currently corresponds to `open` with `O_NOFOLLOW` flag enabled +/// + `fchmod` on WASI and the `fchmodat` function on all other Unix platforms with +/// the flag `AT_SYMLINK_NOFOLLOW` enabled. On Windows, the file is opened +/// with the flag `FILE_FLAG_OPEN_REPARSE_POINT` enabled and then the permissions +/// is set through `SetFileInformationByHandle`. On all other platforms, the behavior +/// remains the same with [`fs::set_permissions`]. /// -/// On Unix platforms, this results in a [`FilesystemLoop`] error if the last element is a symlink. +/// [`fs::set_permissions`]: crate::fs::set_permissions /// -/// This behavior may change in the future. +/// Note that, this [may change in the future][changes]. /// -/// [`FilesystemLoop`]: crate::io::ErrorKind::FilesystemLoop -#[doc(alias = "chmod", alias = "SetFileAttributes")] +/// [changes]: io#platform-specific-behavior +/// +/// # Errors +/// +/// This function will return an error in the following situations, but is not +/// limited to just these cases: +/// +/// * `path` does not exist. +/// * The user lacks the permission to change attributes of the file. +/// +/// Note: On Linux, this will result in a [`Unsupported`] error +/// if the final element is a symlink. +/// +/// [`Unsupported`]: crate::io::ErrorKind::Unsupported +/// +/// # Examples +/// +/// ```no_run +/// #![feature(set_permissions_nofollow)] +/// use std::fs; +/// +/// fn main() -> std::io::Result<()> { +/// let mut perms = fs::symlink_metadata("foo.txt")?.permissions(); +/// perms.set_readonly(true); +/// // This should result in an error on certain platforms +/// // or succeed in modifying the permissions of a symlink +/// fs::set_permissions_nofollow("foo.txt", perms)?; +/// Ok(()) +/// } +/// ``` +#[doc(alias = "fchmodat", alias = "SetFileInformationByHandle")] #[unstable(feature = "set_permissions_nofollow", issue = "141607")] pub fn set_permissions_nofollow>(path: P, perm: Permissions) -> io::Result<()> { - fs_imp::set_permissions_nofollow(path.as_ref(), perm) + fs_imp::set_permissions_nofollow(path.as_ref(), perm.0) } impl DirBuilder { diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index eb619aa4884c5..bf58660754876 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -613,6 +613,66 @@ fn set_get_unix_permissions() { assert_eq!(mask & metadata1.permissions().mode(), 0o0777); } +#[test] +fn set_get_permissions_nofollows() { + let tmpdir = tmpdir(); + let filename = tmpdir.join("set_get_unix_permissions_file"); + check!(File::create(&filename)); + let file_metadata = check!(fs::metadata(&filename)); + assert!(!file_metadata.permissions().readonly()); + let mut permission_bits = file_metadata.permissions(); + permission_bits.set_readonly(true); + let result = fs::set_permissions_nofollow(&filename, permission_bits); + + cfg_select! { + any(windows, unix, target_os = "uefi", target_os = "solid_asp3", target_os = "motor") => { + assert_eq!(result.unwrap(), ()); + let metadata0 = check!(fs::metadata(&filename)); + assert!(metadata0.permissions().readonly()); + }, + _ => { + let error_kind = result.unwrap_err().kind(); + assert_eq!(error_kind, crate::io::ErrorKind::Unsupported); + } + } +} + +// Only Windows and Unix support `fs::set_permissions_nofollow` +#[test] +#[cfg(any(windows, unix))] +fn set_get_permissions_nofollows_symlink() { + #[cfg(not(windows))] + use crate::os::unix::fs::symlink; + #[cfg(windows)] + use crate::os::windows::fs::symlink_dir; + + let tmpdir = tmpdir(); + let filename = tmpdir.join("set_get_unix_permissions_file"); + let symlink_name = tmpdir.join("set_get_unix_permissions"); + check!(File::create(&filename)); + #[cfg(not(windows))] + check!(symlink(&filename, &symlink_name)); + #[cfg(windows)] + check!(symlink_dir(&filename, &symlink_name)); + + let sym_metadata = check!(fs::symlink_metadata(&symlink_name)); + let mut permission_bits = sym_metadata.permissions(); + permission_bits.set_readonly(true); + let result = fs::set_permissions_nofollow(&symlink_name, permission_bits); + + cfg_select! { + any(target_os = "macos", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd", target_os = "dragonfly", target_os = "espidf", target_os = "horizon") => { + assert_eq!(result.unwrap(), ()); + let metadata0 = check!(fs::symlink_metadata(&symlink_name)); + assert!(metadata0.permissions().readonly()); + }, + _ => { + let error_kind = result.unwrap_err().kind(); + assert_eq!(error_kind, crate::io::ErrorKind::Unsupported); + } + } +} + #[test] #[cfg(windows)] fn file_test_io_seek_read_write() { @@ -1330,6 +1390,29 @@ fn fchmod_works() { check!(file.set_permissions(p)); } +#[test] +fn fchmodat_works() { + let tmpdir = tmpdir(); + let file = tmpdir.join("in.txt"); + + check!(File::create(&file)); + let attr = check!(fs::metadata(&file)); + assert!(!attr.permissions().readonly()); + let mut p = attr.permissions(); + p.set_readonly(true); + check!(fs::set_permissions_nofollow(&file, p.clone())); + let attr = check!(fs::metadata(&file)); + assert!(attr.permissions().readonly()); + + match fs::set_permissions_nofollow(&tmpdir.join("foo"), p.clone()) { + Ok(..) => panic!("wanted an error"), + Err(..) => {} + } + + p.set_readonly(false); + check!(fs::set_permissions_nofollow(&file, p)); +} + #[test] fn sync_doesnt_kill_anything() { let tmpdir = tmpdir(); diff --git a/library/std/src/sys/fs/hermit.rs b/library/std/src/sys/fs/hermit.rs index 5f69560998293..d29ea81c67e6d 100644 --- a/library/std/src/sys/fs/hermit.rs +++ b/library/std/src/sys/fs/hermit.rs @@ -566,6 +566,10 @@ pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> { Err(Error::from_raw_os_error(22)) } +pub fn set_perm_nofollow(_p: &Path, _perm: FilePermissions) -> io::Result<()> { + unsupported() +} + pub fn set_times(_p: &Path, _times: FileTimes) -> io::Result<()> { Err(Error::from_raw_os_error(22)) } diff --git a/library/std/src/sys/fs/mod.rs b/library/std/src/sys/fs/mod.rs index 0c297c5766b82..b5a5fa93fd491 100644 --- a/library/std/src/sys/fs/mod.rs +++ b/library/std/src/sys/fs/mod.rs @@ -120,28 +120,8 @@ pub fn set_permissions(path: &Path, perm: FilePermissions) -> io::Result<()> { with_native_path(path, &|path| imp::set_perm(path, perm.clone())) } -#[cfg(all(unix, not(target_os = "vxworks")))] -pub fn set_permissions_nofollow(path: &Path, perm: crate::fs::Permissions) -> io::Result<()> { - use crate::fs::OpenOptions; - - let mut options = OpenOptions::new(); - - // ESP-IDF and Horizon do not support O_NOFOLLOW, so we skip setting it. - // Their filesystems do not have symbolic links, so no special handling is required. - #[cfg(not(any(target_os = "espidf", target_os = "horizon")))] - { - use crate::os::unix::fs::OpenOptionsExt; - options.custom_flags(libc::O_NOFOLLOW); - } - - options.open(path)?.set_permissions(perm) -} - -#[cfg(any(not(unix), target_os = "vxworks"))] -pub fn set_permissions_nofollow(_path: &Path, _perm: crate::fs::Permissions) -> io::Result<()> { - crate::unimplemented!( - "`set_permissions_nofollow` is currently only implemented on Unix platforms" - ) +pub fn set_permissions_nofollow(path: &Path, perm: FilePermissions) -> io::Result<()> { + with_native_path(path, &|path| imp::set_perm_nofollow(path, perm.clone())) } pub fn canonicalize(path: &Path) -> io::Result { diff --git a/library/std/src/sys/fs/motor.rs b/library/std/src/sys/fs/motor.rs index 51b7f347b0b17..a76f64a47c24a 100644 --- a/library/std/src/sys/fs/motor.rs +++ b/library/std/src/sys/fs/motor.rs @@ -319,6 +319,11 @@ pub fn remove_dir_all(path: &Path) -> io::Result<()> { } pub fn set_perm(path: &Path, perm: FilePermissions) -> io::Result<()> { + // Motor does not support symlinks + set_perm_nofollow(path, perm) +} + +pub fn set_perm_nofollow(path: &Path, perm: FilePermissions) -> io::Result<()> { let path = path.to_str().ok_or(io::Error::from(io::ErrorKind::InvalidFilename))?; moto_rt::fs::set_perm(path, perm.rt_perm).map_err(map_motor_error) } diff --git a/library/std/src/sys/fs/solid.rs b/library/std/src/sys/fs/solid.rs index b61147db57ed5..bd963b1d2f038 100644 --- a/library/std/src/sys/fs/solid.rs +++ b/library/std/src/sys/fs/solid.rs @@ -531,6 +531,11 @@ pub fn rename(old: &Path, new: &Path) -> io::Result<()> { } pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> { + // Solid does not support symlinks + set_perm_nofollow(p, perm) +} + +pub fn set_perm_nofollow(p: &Path, perm: FilePermissions) -> io::Result<()> { error::SolidError::err_if_negative(unsafe { abi::SOLID_FS_Chmod(cstr(p)?.as_ptr(), perm.0.into()) }) diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index c4467ed23e125..1b4c1074b4339 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -480,6 +480,11 @@ pub fn rename(old: &Path, new: &Path) -> io::Result<()> { } pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> { + // UEFI does not support symlinks + set_perm_nofollow(p, perm); +} + +pub fn set_perm_nofollow(p: &Path, perm: FilePermissions) -> io::Result<()> { let f = uefi_fs::File::from_path(p, file::MODE_READ | file::MODE_WRITE, 0)?; set_perm_inner(&f, perm) } diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 3152a22534f6c..dd644b3abd94e 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -1989,6 +1989,43 @@ pub fn set_perm(p: &CStr, perm: FilePermissions) -> io::Result<()> { cvt_r(|| unsafe { libc::chmod(p.as_ptr(), perm.mode) }).map(|_| ()) } +pub fn set_perm_nofollow(p: &CStr, perm: FilePermissions) -> io::Result<()> { + // ESP-IDF and Horizon do not support O_NOFOLLOW, so we skip setting it. + // Their filesystems do not have symbolic links, so no special handling is required. + cfg_select! { + // wasm32-wasip1 targets do not support fchmodat, so we fall down to + // open + fchmod + target_os = "wasi" => { + use crate::fs::OpenOptions; + use crate::fs::Permissions; + use crate::os::wasi::ffi::OsStrExt; + let mut options = OpenOptions::new(); + + #[cfg(not(any(target_os = "espidf", target_os = "horizon")))] + { + use crate::os::wasi::fs::OpenOptionsExt; + options.custom_flags(libc::O_NOFOLLOW); + } + + let bytes = p.to_bytes(); + let os_str = OsStr::from_bytes(bytes); + options.open(Path::new(os_str))?.set_permissions(Permissions::from_inner(perm)) + } + not(any(target_os = "espidf", target_os = "horizon")) => { + cvt_r(|| unsafe { + libc::fchmodat(libc::AT_FDCWD, p.as_ptr(), perm.mode, libc::AT_SYMLINK_NOFOLLOW) + }) + .map(|_| ()) + }, + _ => { + cvt_r(|| unsafe { + libc::fchmodat(libc::AT_FDCWD, p.as_ptr(), perm.mode, 0) + }) + .map(|_| ()) + } + } +} + pub fn rmdir(p: &CStr) -> io::Result<()> { cvt(unsafe { libc::rmdir(p.as_ptr()) }).map(|_| ()) } diff --git a/library/std/src/sys/fs/unsupported.rs b/library/std/src/sys/fs/unsupported.rs index 703ebef380383..512af27401dfe 100644 --- a/library/std/src/sys/fs/unsupported.rs +++ b/library/std/src/sys/fs/unsupported.rs @@ -313,6 +313,10 @@ pub fn set_perm(_p: &Path, perm: FilePermissions) -> io::Result<()> { match perm.0 {} } +pub fn set_perm_nofollow(_p: &Path, perm: FilePermissions) -> io::Result<()> { + match perm.0 {} +} + pub fn set_times(_p: &Path, _times: FileTimes) -> io::Result<()> { unsupported() } diff --git a/library/std/src/sys/fs/vexos.rs b/library/std/src/sys/fs/vexos.rs index 9de9570cb5b24..0ed0a4cbfc437 100644 --- a/library/std/src/sys/fs/vexos.rs +++ b/library/std/src/sys/fs/vexos.rs @@ -492,6 +492,10 @@ pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> { unsupported() } +pub fn set_perm_nofollow(_p: &Path, _perm: FilePermissions) -> io::Result<()> { + unsupported() +} + pub fn set_times(_p: &Path, _times: FileTimes) -> io::Result<()> { unsupported() } diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs index e3e7b081b47d5..a7e8e8b3ac630 100644 --- a/library/std/src/sys/fs/windows.rs +++ b/library/std/src/sys/fs/windows.rs @@ -1564,6 +1564,15 @@ pub fn set_perm(p: &WCStr, perm: FilePermissions) -> io::Result<()> { } } +pub fn set_perm_nofollow(p: &WCStr, perm: FilePermissions) -> io::Result<()> { + let mut opts = OpenOptions::new(); + opts.access_mode(c::FILE_WRITE_ATTRIBUTES); + // `FILE_FLAG_OPEN_REPARSE_POINT` for no_follow behavior + opts.custom_flags(c::FILE_FLAG_BACKUP_SEMANTICS | c::FILE_FLAG_OPEN_REPARSE_POINT); + let file = File::open_native(p, &opts)?; + file.set_permissions(perm) +} + pub fn set_times(p: &WCStr, times: FileTimes) -> io::Result<()> { let mut opts = OpenOptions::new(); opts.access_mode(c::FILE_WRITE_ATTRIBUTES);