From 1f5325866088b9b58a004734e67777d2ff3ef7b4 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Wed, 11 Feb 2026 17:05:50 +0900 Subject: [PATCH 1/4] Bump `ena` --- Cargo.lock | 4 ++-- compiler/rustc_data_structures/Cargo.toml | 2 +- compiler/rustc_type_ir/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1a930b64f458..ba42ec20331e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1298,9 +1298,9 @@ dependencies = [ [[package]] name = "ena" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" +checksum = "eabffdaee24bd1bf95c5ef7cec31260444317e72ea56c4c91750e8b7ee58d5f1" dependencies = [ "log", ] diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index f358ffffb47d..0332ff681082 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -9,7 +9,7 @@ arrayvec = { version = "0.7", default-features = false } bitflags = "2.4.1" either = "1.0" elsa = "1.11.0" -ena = "0.14.3" +ena = "0.14.4" indexmap = "2.12.1" jobserver_crate = { version = "0.1.28", package = "jobserver" } measureme = "12.0.1" diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 315ab8b97e9b..fbe382712893 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -8,7 +8,7 @@ edition = "2024" arrayvec = { version = "0.7", default-features = false } bitflags = "2.4.1" derive-where = "1.2.7" -ena = "0.14.3" +ena = "0.14.4" indexmap = "2.0.0" rustc-hash = "2.0.0" rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false } From 13a83cb6397e19088ff7d5946f901c6e35f12374 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Wed, 11 Feb 2026 17:38:34 +0900 Subject: [PATCH 2/4] Shallow resolve ty and const vars to their root vars --- compiler/rustc_infer/src/infer/mod.rs | 52 ++++++++++++++----- .../rustc_infer/src/infer/type_variable.rs | 19 +++++++ 2 files changed, 58 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index e15b25500bb5..21f486a228da 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1099,22 +1099,45 @@ impl<'tcx> InferCtxt<'tcx> { // // Note: if these two lines are combined into one we get // dynamic borrow errors on `self.inner`. - let known = self.inner.borrow_mut().type_variables().probe(v).known(); - known.map_or(ty, |t| self.shallow_resolve(t)) + let (root_vid, value) = + self.inner.borrow_mut().type_variables().probe_with_root_vid(v); + value.known().map_or_else( + || if root_vid == v { ty } else { Ty::new_var(self.tcx, root_vid) }, + |t| self.shallow_resolve(t), + ) } ty::IntVar(v) => { - match self.inner.borrow_mut().int_unification_table().probe_value(v) { + let (root, value) = + self.inner.borrow_mut().int_unification_table().inlined_probe_key_value(v); + match value { ty::IntVarValue::IntType(ty) => Ty::new_int(self.tcx, ty), ty::IntVarValue::UintType(ty) => Ty::new_uint(self.tcx, ty), - ty::IntVarValue::Unknown => ty, + ty::IntVarValue::Unknown => { + if root == v { + ty + } else { + Ty::new_int_var(self.tcx, root) + } + } } } ty::FloatVar(v) => { - match self.inner.borrow_mut().float_unification_table().probe_value(v) { + let (root, value) = self + .inner + .borrow_mut() + .float_unification_table() + .inlined_probe_key_value(v); + match value { ty::FloatVarValue::Known(ty) => Ty::new_float(self.tcx, ty), - ty::FloatVarValue::Unknown => ty, + ty::FloatVarValue::Unknown => { + if root == v { + ty + } else { + Ty::new_float_var(self.tcx, root) + } + } } } @@ -1128,13 +1151,16 @@ impl<'tcx> InferCtxt<'tcx> { pub fn shallow_resolve_const(&self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { match ct.kind() { ty::ConstKind::Infer(infer_ct) => match infer_ct { - InferConst::Var(vid) => self - .inner - .borrow_mut() - .const_unification_table() - .probe_value(vid) - .known() - .unwrap_or(ct), + InferConst::Var(vid) => { + let (root, value) = self + .inner + .borrow_mut() + .const_unification_table() + .inlined_probe_key_value(vid); + value.known().unwrap_or_else(|| { + if root.vid == vid { ct } else { ty::Const::new_var(self.tcx, root.vid) } + }) + } InferConst::Fresh(_) => ct, }, ty::ConstKind::Param(_) diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs index 65f77fe8e25f..9b928cc5cc8c 100644 --- a/compiler/rustc_infer/src/infer/type_variable.rs +++ b/compiler/rustc_infer/src/infer/type_variable.rs @@ -258,6 +258,25 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> { self.eq_relations().inlined_probe_value(vid) } + /// Retrieves the type to which `vid` has been instantiated, if + /// any, along with the root `vid`. + pub(crate) fn probe_with_root_vid( + &mut self, + vid: ty::TyVid, + ) -> (ty::TyVid, TypeVariableValue<'tcx>) { + self.inlined_probe_with_vid(vid) + } + + /// An always-inlined variant of `probe_with_root_vid`, for very hot call sites. + #[inline(always)] + pub(crate) fn inlined_probe_with_vid( + &mut self, + vid: ty::TyVid, + ) -> (ty::TyVid, TypeVariableValue<'tcx>) { + let (id, value) = self.eq_relations().inlined_probe_key_value(vid); + (id.vid, value) + } + #[inline] fn eq_relations(&mut self) -> super::UnificationTable<'_, 'tcx, TyVidEqKey<'tcx>> { self.storage.eq_relations.with_log(self.undo_log) From 955f7750c1538060d7093a0c17bb8533f2665465 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Wed, 11 Feb 2026 17:50:50 +0900 Subject: [PATCH 3/4] Remove redundant `shallow_resolve` call --- compiler/rustc_hir_typeck/src/fallback.rs | 5 ----- compiler/rustc_infer/src/infer/mod.rs | 7 +++++++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 2e421c610e7a..c10e7f3bfb8b 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -357,11 +357,6 @@ impl<'tcx> FnCtxt<'_, 'tcx> { VecGraph::new(num_ty_vars, coercion_edges) } - /// If `ty` is an unresolved type variable, returns its root vid. - fn root_vid(&self, ty: Ty<'tcx>) -> Option { - Some(self.root_var(self.shallow_resolve(ty).ty_vid()?)) - } - /// Given a set of diverging vids and coercions, walk the HIR to gather a /// set of suggestions which can be applied to preserve fallback to unit. fn try_to_suggest_annotations( diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 21f486a228da..b57306536260 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1184,6 +1184,13 @@ impl<'tcx> InferCtxt<'tcx> { self.inner.borrow_mut().type_variables().root_var(var) } + /// If `ty` is an unresolved type variable, returns its root vid. + pub fn root_vid(&self, ty: Ty<'tcx>) -> Option { + let (root, value) = + self.inner.borrow_mut().type_variables().inlined_probe_with_vid(ty.ty_vid()?); + value.is_unknown().then_some(root) + } + pub fn sub_unify_ty_vids_raw(&self, a: ty::TyVid, b: ty::TyVid) { self.inner.borrow_mut().type_variables().sub_unify(a, b); } From 8062bee9e3825374539906bf502ff1f0c1a06e61 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Wed, 11 Feb 2026 18:00:36 +0900 Subject: [PATCH 4/4] Bless tests --- .../incremental/const-generics/issue-64087.rs | 2 - .../inference-fail.stderr | 2 +- .../warn-when-cycle-is-error-in-coherence.rs | 2 +- ...rn-when-cycle-is-error-in-coherence.stderr | 2 +- .../dyn-compatibility-ok-infer-err.rs | 1 - .../dyn-compatibility-ok-infer-err.stderr | 23 +- tests/ui/const-generics/infer/issue-77092.rs | 1 - .../const-generics/infer/issue-77092.stderr | 20 +- .../try-from-with-const-genericsrs-98299.rs | 2 - ...ry-from-with-const-genericsrs-98299.stderr | 44 +-- .../multiline-removal-suggestion.svg | 364 ++++++++++-------- .../indexing/indexing-requires-a-uint.stderr | 2 - .../point-at-index-for-obligation-failure.rs | 4 +- ...int-at-index-for-obligation-failure.stderr | 9 +- tests/ui/parser/issue-12187-1.stderr | 2 +- tests/ui/parser/issue-12187-2.stderr | 2 +- ...opy-inference-side-effects-are-lazy.stderr | 2 +- .../suggest-dereferencing-index.stderr | 2 - ...oxed-closures-failed-recursive-fn-2.stderr | 2 +- 19 files changed, 225 insertions(+), 263 deletions(-) diff --git a/tests/incremental/const-generics/issue-64087.rs b/tests/incremental/const-generics/issue-64087.rs index 787f2af8aa39..97f212b3fbba 100644 --- a/tests/incremental/const-generics/issue-64087.rs +++ b/tests/incremental/const-generics/issue-64087.rs @@ -6,6 +6,4 @@ fn combinator() -> [T; S] {} fn main() { combinator().into_iter(); //[cfail1]~^ ERROR type annotations needed - //[cfail1]~| ERROR type annotations needed - //[cfail1]~| ERROR type annotations needed } diff --git a/tests/ui/associated-inherent-types/inference-fail.stderr b/tests/ui/associated-inherent-types/inference-fail.stderr index bf329c69e99c..12cc3ae7960c 100644 --- a/tests/ui/associated-inherent-types/inference-fail.stderr +++ b/tests/ui/associated-inherent-types/inference-fail.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed --> $DIR/inference-fail.rs:10:12 | LL | let _: S<_>::P = (); - | ^^^^^^^ cannot infer type for type parameter `T` + | ^^^^^^^ cannot infer type error: aborting due to 1 previous error diff --git a/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.rs b/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.rs index c50bbcec5215..b754b1cb5472 100644 --- a/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.rs +++ b/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.rs @@ -3,7 +3,7 @@ use std::cmp::Ordering; use std::marker::PhantomData; #[derive(PartialEq, Default)] -//~^ ERROR conflicting implementations of trait `PartialEq>` for type `Interval<_>` +//~^ ERROR conflicting implementations of trait `PartialEq` for type `Interval<_>` pub(crate) struct Interval(PhantomData); // This impl overlaps with the `derive` unless we reject the nested diff --git a/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.stderr b/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.stderr index a9a99fb28d84..620694aacf83 100644 --- a/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.stderr +++ b/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.stderr @@ -1,4 +1,4 @@ -error[E0119]: conflicting implementations of trait `PartialEq>` for type `Interval<_>` +error[E0119]: conflicting implementations of trait `PartialEq` for type `Interval<_>` --> $DIR/warn-when-cycle-is-error-in-coherence.rs:5:10 | LL | #[derive(PartialEq, Default)] diff --git a/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.rs b/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.rs index 298cfb512e41..79e9834b54ed 100644 --- a/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.rs +++ b/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.rs @@ -18,5 +18,4 @@ fn use_dyn(v: &dyn Foo) where [u8; N + 1]: Sized { fn main() { use_dyn(&()); //~^ ERROR type annotations needed - //~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.stderr b/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.stderr index a124fbc60920..f9904c9d2e48 100644 --- a/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.stderr +++ b/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.stderr @@ -14,27 +14,6 @@ help: consider specifying the generic argument LL | use_dyn::(&()); | +++++ -error[E0284]: type annotations needed - --> $DIR/dyn-compatibility-ok-infer-err.rs:19:5 - | -LL | use_dyn(&()); - | ^^^^^^^ --- type must be known at this point - | | - | cannot infer the value of the const parameter `N` declared on the function `use_dyn` - | -note: required for `()` to implement `Foo<_>` - --> $DIR/dyn-compatibility-ok-infer-err.rs:8:22 - | -LL | impl Foo for () { - | -------------- ^^^^^^ ^^ - | | - | unsatisfied trait bound introduced here - = note: required for the cast from `&()` to `&dyn Foo<_>` -help: consider specifying the generic argument - | -LL | use_dyn::(&()); - | +++++ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/infer/issue-77092.rs b/tests/ui/const-generics/infer/issue-77092.rs index 47c594e5b11e..77d1fe187795 100644 --- a/tests/ui/const-generics/infer/issue-77092.rs +++ b/tests/ui/const-generics/infer/issue-77092.rs @@ -10,6 +10,5 @@ fn main() { for i in 1..4 { println!("{:?}", take_array_from_mut(&mut arr, i)); //~^ ERROR type annotations needed - //~| ERROR type annotations needed } } diff --git a/tests/ui/const-generics/infer/issue-77092.stderr b/tests/ui/const-generics/infer/issue-77092.stderr index 3763cd738a86..96f6496eca53 100644 --- a/tests/ui/const-generics/infer/issue-77092.stderr +++ b/tests/ui/const-generics/infer/issue-77092.stderr @@ -14,24 +14,6 @@ help: consider specifying the generic arguments LL | println!("{:?}", take_array_from_mut::(&mut arr, i)); | ++++++++++ -error[E0284]: type annotations needed - --> $DIR/issue-77092.rs:11:26 - | -LL | println!("{:?}", take_array_from_mut(&mut arr, i)); - | ---- ^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `take_array_from_mut` - | | - | required by this formatting parameter - | - = note: required for `[i32; _]` to implement `Debug` - = note: 1 redundant requirement hidden - = note: required for `&mut [i32; _]` to implement `Debug` -note: required by a bound in `core::fmt::rt::Argument::<'_>::new_debug` - --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL -help: consider specifying the generic arguments - | -LL | println!("{:?}", take_array_from_mut::(&mut arr, i)); - | ++++++++++ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/try-from-with-const-genericsrs-98299.rs b/tests/ui/const-generics/try-from-with-const-genericsrs-98299.rs index 49c88856bc96..808d960da68b 100644 --- a/tests/ui/const-generics/try-from-with-const-genericsrs-98299.rs +++ b/tests/ui/const-generics/try-from-with-const-genericsrs-98299.rs @@ -4,8 +4,6 @@ use std::convert::TryFrom; pub fn test_usage(p: ()) { SmallCString::try_from(p).map(|cstr| cstr); //~^ ERROR: type annotations needed - //~| ERROR: type annotations needed - //~| ERROR: type annotations needed } pub struct SmallCString {} diff --git a/tests/ui/const-generics/try-from-with-const-genericsrs-98299.stderr b/tests/ui/const-generics/try-from-with-const-genericsrs-98299.stderr index 1557b83b00ec..c80efd6df8a8 100644 --- a/tests/ui/const-generics/try-from-with-const-genericsrs-98299.stderr +++ b/tests/ui/const-generics/try-from-with-const-genericsrs-98299.stderr @@ -7,7 +7,7 @@ LL | SmallCString::try_from(p).map(|cstr| cstr); | type must be known at this point | note: required by a const generic parameter in `SmallCString` - --> $DIR/try-from-with-const-genericsrs-98299.rs:11:25 + --> $DIR/try-from-with-const-genericsrs-98299.rs:9:25 | LL | pub struct SmallCString {} | ^^^^^^^^^^^^^^ required by this const generic parameter in `SmallCString` @@ -16,46 +16,6 @@ help: consider giving this closure parameter an explicit type, where the value o LL | SmallCString::try_from(p).map(|cstr: SmallCString| cstr); | +++++++++++++++++ -error[E0284]: type annotations needed for `SmallCString<_>` - --> $DIR/try-from-with-const-genericsrs-98299.rs:5:36 - | -LL | SmallCString::try_from(p).map(|cstr| cstr); - | ------------ ^^^^ - | | - | type must be known at this point - | -note: required for `SmallCString<_>` to implement `TryFrom<()>` - --> $DIR/try-from-with-const-genericsrs-98299.rs:13:22 - | -LL | impl TryFrom<()> for SmallCString { - | -------------- ^^^^^^^^^^^ ^^^^^^^^^^^^^^^ - | | - | unsatisfied trait bound introduced here -help: consider giving this closure parameter an explicit type, where the value of const parameter `N` is specified - | -LL | SmallCString::try_from(p).map(|cstr: SmallCString| cstr); - | +++++++++++++++++ - -error[E0284]: type annotations needed for `SmallCString<_>` - --> $DIR/try-from-with-const-genericsrs-98299.rs:5:36 - | -LL | SmallCString::try_from(p).map(|cstr| cstr); - | ------------------------- ^^^^ - | | - | type must be known at this point - | -note: required for `SmallCString<_>` to implement `TryFrom<()>` - --> $DIR/try-from-with-const-genericsrs-98299.rs:13:22 - | -LL | impl TryFrom<()> for SmallCString { - | -------------- ^^^^^^^^^^^ ^^^^^^^^^^^^^^^ - | | - | unsatisfied trait bound introduced here -help: consider giving this closure parameter an explicit type, where the value of const parameter `N` is specified - | -LL | SmallCString::try_from(p).map(|cstr: SmallCString| cstr); - | +++++++++++++++++ - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/error-emitter/multiline-removal-suggestion.svg b/tests/ui/error-emitter/multiline-removal-suggestion.svg index 1e8621388510..39631e0e306d 100644 --- a/tests/ui/error-emitter/multiline-removal-suggestion.svg +++ b/tests/ui/error-emitter/multiline-removal-suggestion.svg @@ -1,4 +1,4 @@ - +