about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <jtitor@2k36.org>2023-04-04 05:52:35 +0900
committerGitHub <noreply@github.com>2023-04-04 05:52:35 +0900
commit7d3207be9776d6707f77a2ce7da170ffdd4f1b0d (patch)
tree0288e53b7f1159c06a17c8a0e8e8ccd4574a531a
parent4e25d20f957600aeae70d43f0d5fba54d9685d30 (diff)
parentca79b82c6cff632c98ed355e7d0f554ef8b5cc5d (diff)
downloadrust-7d3207be9776d6707f77a2ce7da170ffdd4f1b0d.tar.gz
rust-7d3207be9776d6707f77a2ce7da170ffdd4f1b0d.zip
Rollup merge of #109896 - Nilstrieb:integers-are-not-fn-ptrs-remember-this-dear-transmuter, r=compiler-errors
Never consider int and float vars for `FnPtr` candidates

This solves a regression where `0.0.cmp()` was ambiguous when a custom trait with a `cmp` method was in scope.

For integers it shouldn't be a problem in practice so I wasn't able to add a test.

I'm not sure whether there could be more issues hidden in the shadows as mentioned in the issue, but this should at least fix the problematic regression immediately.

fixes #109892

r? oli-obk
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs10
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs12
-rw-r--r--tests/ui/fn/fn-ptr-trait-int-float-infer-var.rs10
3 files changed, 24 insertions, 8 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 47a351590b1..090312338e0 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -998,8 +998,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             | ty::Alias(..)
             | ty::Param(..)
             | ty::Bound(..)
-            | ty::Error(_) => {}
-            ty::Infer(_) => {
+            | ty::Error(_)
+            | ty::Infer(
+                ty::InferTy::IntVar(_)
+                | ty::InferTy::FloatVar(_)
+                | ty::InferTy::FreshIntTy(_)
+                | ty::InferTy::FreshFloatTy(_),
+            ) => {}
+            ty::Infer(ty::InferTy::TyVar(_) | ty::InferTy::FreshTy(_)) => {
                 candidates.ambiguous = true;
             }
         }
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 3ed3dd2d20d..b58e62536d6 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -177,14 +177,14 @@ struct TraitObligationStack<'prev, 'tcx> {
 }
 
 struct SelectionCandidateSet<'tcx> {
-    // A list of candidates that definitely apply to the current
-    // obligation (meaning: types unify).
+    /// A list of candidates that definitely apply to the current
+    /// obligation (meaning: types unify).
     vec: Vec<SelectionCandidate<'tcx>>,
 
-    // If `true`, then there were candidates that might or might
-    // not have applied, but we couldn't tell. This occurs when some
-    // of the input types are type variables, in which case there are
-    // various "builtin" rules that might or might not trigger.
+    /// If `true`, then there were candidates that might or might
+    /// not have applied, but we couldn't tell. This occurs when some
+    /// of the input types are type variables, in which case there are
+    /// various "builtin" rules that might or might not trigger.
     ambiguous: bool,
 }
 
diff --git a/tests/ui/fn/fn-ptr-trait-int-float-infer-var.rs b/tests/ui/fn/fn-ptr-trait-int-float-infer-var.rs
new file mode 100644
index 00000000000..eec7da044c0
--- /dev/null
+++ b/tests/ui/fn/fn-ptr-trait-int-float-infer-var.rs
@@ -0,0 +1,10 @@
+// check-pass
+trait MyCmp {
+    fn cmp(&self) {}
+}
+impl MyCmp for f32 {}
+
+fn main() {
+    // Ensure that `impl<F: FnPtr> Ord for F` is never considered for int and float infer vars.
+    0.0.cmp();
+}