about summary refs log tree commit diff
diff options
context:
space:
mode:
authory21 <30553356+y21@users.noreply.github.com>2024-06-01 20:10:48 +0200
committery21 <30553356+y21@users.noreply.github.com>2024-06-01 20:10:48 +0200
commit25d40c9f6b09b4decd17c564c037e1f8de9859b2 (patch)
tree07f12c78708af20103f52cdbdcfd9f13e5be5dc2
parent28e887fe719ed8fdcf2047c2e587efcd25e4d62e (diff)
downloadrust-25d40c9f6b09b4decd17c564c037e1f8de9859b2.tar.gz
rust-25d40c9f6b09b4decd17c564c037e1f8de9859b2.zip
handle parent const effects correctly in type_certainty
-rw-r--r--clippy_utils/src/ty/type_certainty/mod.rs14
-rw-r--r--tests/ui/or_fun_call.fixed7
-rw-r--r--tests/ui/or_fun_call.rs7
3 files changed, 26 insertions, 2 deletions
diff --git a/clippy_utils/src/ty/type_certainty/mod.rs b/clippy_utils/src/ty/type_certainty/mod.rs
index 80219303450..cba61c841ef 100644
--- a/clippy_utils/src/ty/type_certainty/mod.rs
+++ b/clippy_utils/src/ty/type_certainty/mod.rs
@@ -206,8 +206,18 @@ fn path_segment_certainty(
             // Checking `res_generics_def_id(..)` before calling `generics_of` avoids an ICE.
             if cx.tcx.res_generics_def_id(path_segment.res).is_some() {
                 let generics = cx.tcx.generics_of(def_id);
-                let count = generics.own_params.len() - usize::from(generics.host_effect_index.is_some());
-                let lhs = if (parent_certainty.is_certain() || generics.parent_count == 0) && count == 0 {
+
+                let own_count = generics.own_params.len()
+                    - usize::from(generics.host_effect_index.is_some_and(|index| {
+                        // Check that the host index actually belongs to this resolution.
+                        // E.g. for `Add::add`, host_effect_index is `Some(2)`, but it's part of the parent `Add`
+                        // trait's generics.
+                        // Add params:      [Self#0, Rhs#1, host#2]   parent_count=0, count=3
+                        // Add::add params: []                        parent_count=3, count=3
+                        // (3..3).contains(&host_effect_index) => false
+                        (generics.parent_count..generics.count()).contains(&index)
+                    }));
+                let lhs = if (parent_certainty.is_certain() || generics.parent_count == 0) && own_count == 0 {
                     Certainty::Certain(None)
                 } else {
                     Certainty::Uncertain
diff --git a/tests/ui/or_fun_call.fixed b/tests/ui/or_fun_call.fixed
index e7ba54864ab..7657ef470c5 100644
--- a/tests/ui/or_fun_call.fixed
+++ b/tests/ui/or_fun_call.fixed
@@ -311,4 +311,11 @@ mod lazy {
     }
 }
 
+fn host_effect() {
+    // #12877 - make sure we don't ICE in type_certainty
+    use std::ops::Add;
+
+    Add::<i32>::add(1, 1).add(i32::MIN);
+}
+
 fn main() {}
diff --git a/tests/ui/or_fun_call.rs b/tests/ui/or_fun_call.rs
index 196632133d5..97cf496d3ac 100644
--- a/tests/ui/or_fun_call.rs
+++ b/tests/ui/or_fun_call.rs
@@ -311,4 +311,11 @@ mod lazy {
     }
 }
 
+fn host_effect() {
+    // #12877 - make sure we don't ICE in type_certainty
+    use std::ops::Add;
+
+    Add::<i32>::add(1, 1).add(i32::MIN);
+}
+
 fn main() {}