From ca79b82c6cff632c98ed355e7d0f554ef8b5cc5d Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Mon, 3 Apr 2023 15:23:08 +0000 Subject: [PATCH] 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. --- .../src/traits/select/candidate_assembly.rs | 10 ++++++++-- .../rustc_trait_selection/src/traits/select/mod.rs | 12 ++++++------ tests/ui/fn/fn-ptr-trait-int-float-infer-var.rs | 10 ++++++++++ 3 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 tests/ui/fn/fn-ptr-trait-int-float-infer-var.rs 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 @@ fn assemble_candidates_for_fn_ptr_trait( | 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>, - // 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 Ord for F` is never considered for int and float infer vars. + 0.0.cmp(); +}