From 465844c3bee12c7a8895e6a914ab791041da2952 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 3 Feb 2025 11:42:04 +0100 Subject: [PATCH] Do not use make use of `InferenceResult::has_errors` flag for mir building It generaly does not work as expected right now as we fallback type parameters to errors --- crates/hir-ty/src/infer.rs | 3 +++ crates/hir-ty/src/method_resolution.rs | 21 +++++++++++++++---- crates/hir-ty/src/mir/lower.rs | 2 +- .../src/handlers/incorrect_case.rs | 2 ++ .../src/handlers/mutability_errors.rs | 3 ++- 5 files changed, 25 insertions(+), 6 deletions(-) diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs index 3c258e3c4c..f4a018e2ee 100644 --- a/crates/hir-ty/src/infer.rs +++ b/crates/hir-ty/src/infer.rs @@ -466,6 +466,9 @@ pub struct InferenceResult { pub type_of_for_iterator: FxHashMap, type_mismatches: FxHashMap, /// Whether there are any type-mismatching errors in the result. + // FIXME: This isn't as useful as initially thought due to us falling back placeholders to + // `TyKind::Error`. + // Which will then mark this field. pub(crate) has_errors: bool, /// Interned common types to return references to. // FIXME: Move this into `InferenceContext` diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs index 1cea67ee96..db94351dcc 100644 --- a/crates/hir-ty/src/method_resolution.rs +++ b/crates/hir-ty/src/method_resolution.rs @@ -4,6 +4,7 @@ //! and the corresponding code mostly in rustc_hir_analysis/check/method/probe.rs. use std::ops::ControlFlow; +use arrayvec::ArrayVec; use base_db::CrateId; use chalk_ir::{cast::Cast, UniverseIndex, WithKind}; use hir_def::{ @@ -732,15 +733,27 @@ fn lookup_impl_assoc_item_for_trait_ref( let self_ty = trait_ref.self_type_parameter(Interner); let self_ty_fp = TyFingerprint::for_trait_impl(&self_ty)?; let impls = db.trait_impls_in_deps(env.krate); - let self_impls = match self_ty.kind(Interner) { - TyKind::Adt(id, _) => { - id.0.module(db.upcast()).containing_block().and_then(|it| db.trait_impls_in_block(it)) + + let trait_module = hir_trait_id.module(db.upcast()); + let type_module = match self_ty_fp { + TyFingerprint::Adt(adt_id) => Some(adt_id.module(db.upcast())), + TyFingerprint::ForeignType(type_id) => { + Some(from_foreign_def_id(type_id).module(db.upcast())) } + TyFingerprint::Dyn(trait_id) => Some(trait_id.module(db.upcast())), _ => None, }; + + let def_blocks: ArrayVec<_, 2> = + [trait_module.containing_block(), type_module.and_then(|it| it.containing_block())] + .into_iter() + .flatten() + .filter_map(|block_id| db.trait_impls_in_block(block_id)) + .collect(); + let impls = impls .iter() - .chain(self_impls.as_ref()) + .chain(&def_blocks) .flat_map(|impls| impls.for_trait_and_self_ty(hir_trait_id, self_ty_fp)); let table = InferenceTable::new(db, env); diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs index cc6ed122af..549450e9be 100644 --- a/crates/hir-ty/src/mir/lower.rs +++ b/crates/hir-ty/src/mir/lower.rs @@ -2156,7 +2156,7 @@ pub fn lower_to_mir( // need to take this input explicitly. root_expr: ExprId, ) -> Result { - if infer.has_errors { + if infer.type_mismatches().next().is_some() { return Err(MirLowerError::HasErrors); } let mut ctx = MirLowerCtx::new(db, owner, body, infer); diff --git a/crates/ide-diagnostics/src/handlers/incorrect_case.rs b/crates/ide-diagnostics/src/handlers/incorrect_case.rs index 0cc80bda2c..246330e6ef 100644 --- a/crates/ide-diagnostics/src/handlers/incorrect_case.rs +++ b/crates/ide-diagnostics/src/handlers/incorrect_case.rs @@ -936,6 +936,7 @@ fn func() { fn override_lint_level() { check_diagnostics( r#" +#![allow(unused_variables)] #[warn(nonstandard_style)] fn foo() { let BAR; @@ -992,6 +993,7 @@ struct QUX; const foo: i32 = 0; fn BAR() { let BAZ; + _ = BAZ; } "#, ); diff --git a/crates/ide-diagnostics/src/handlers/mutability_errors.rs b/crates/ide-diagnostics/src/handlers/mutability_errors.rs index 1397979144..0e3c4c7aa3 100644 --- a/crates/ide-diagnostics/src/handlers/mutability_errors.rs +++ b/crates/ide-diagnostics/src/handlers/mutability_errors.rs @@ -831,13 +831,14 @@ fn f() { #[test] fn or_pattern() { - // FIXME: `None` is inferred as unknown here for some reason check_diagnostics( r#" //- minicore: option fn f(_: i32) {} fn main() { let ((Some(mut x), None) | (_, Some(mut x))) = (None, Some(7)) else { return }; + //^^^^^ 💡 warn: variable does not need to be mutable + f(x); } "#,