From 29acd398004555695bbf29eb054b12381e955cbf Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 1 Jan 2021 20:45:49 +0100 Subject: Don't emit arg count diagnostics for method calls with unknown receiver Fixes #7098. --- crates/hir_ty/src/diagnostics/expr.rs | 26 +++++++++++++++++++++++++- crates/hir_ty/src/lib.rs | 4 ++++ 2 files changed, 29 insertions(+), 1 deletion(-) (limited to 'crates') diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs index 849415706..b4e453411 100644 --- a/crates/hir_ty/src/diagnostics/expr.rs +++ b/crates/hir_ty/src/diagnostics/expr.rs @@ -156,7 +156,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> { // FIXME: Due to shortcomings in the current type system implementation, only emit this // diagnostic if there are no type mismatches in the containing function. if self.infer.type_mismatches.iter().next().is_some() { - return Some(()); + return None; } let is_method_call = matches!(expr, Expr::MethodCall { .. }); @@ -170,6 +170,14 @@ impl<'a, 'b> ExprValidator<'a, 'b> { let mut args = args.clone(); args.insert(0, *receiver); + let receiver = &self.infer.type_of_expr[*receiver]; + if receiver.strip_references().is_unknown() { + // if the receiver is of unknown type, it's very likely we + // don't know enough to correctly resolve the method call. + // This is kind of a band-aid for #6975. + return None; + } + // FIXME: note that we erase information about substs here. This // is not right, but, luckily, doesn't matter as we care only // about the number of params @@ -504,6 +512,22 @@ fn f() { ); } + #[test] + fn method_unknown_receiver() { + // note: this is incorrect code, so there might be errors on this in the + // future, but we shouldn't emit an argument count diagnostic here + check_diagnostics( + r#" +trait Foo { fn method(&self, arg: usize) {} } + +fn f() { + let x; + x.method(); +} +"#, + ); + } + #[test] fn tuple_struct() { check_diagnostics( diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 357bd92f9..e00c7e176 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs @@ -791,6 +791,10 @@ impl Ty { matches!(self, Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. })) } + pub fn is_unknown(&self) -> bool { + matches!(self, Ty::Unknown) + } + /// If this is a `dyn Trait` type, this returns the `Trait` part. pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { match self { -- cgit v1.2.3