diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index ea3c0a8ddb450..7352c14490d1a 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -14,6 +14,7 @@ use infer::InferCtxt; use infer::type_variable::TypeVariableOrigin; use ty::{self, Ty, TyInfer, TyVar}; use syntax_pos::Span; +use errors::DiagnosticBuilder; struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, @@ -86,7 +87,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } } - pub fn need_type_info(&self, body_id: Option<hir::BodyId>, span: Span, ty: Ty<'tcx>) { + pub fn need_type_info_err(&self, + body_id: Option<hir::BodyId>, + span: Span, + ty: Ty<'tcx>) + -> DiagnosticBuilder<'gcx> { let ty = self.resolve_type_vars_if_possible(&ty); let name = self.extract_type_name(&ty); @@ -142,6 +147,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { err.span_label(target_span, label_message); } - err.emit(); + err } } diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 25be4a2ff5c8b..f6ec01546c18d 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1234,7 +1234,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.tcx.lang_items().sized_trait() .map_or(false, |sized_id| sized_id == trait_ref.def_id()) { - self.need_type_info(body_id, span, self_ty); + self.need_type_info_err(body_id, span, self_ty).emit(); } else { let mut err = struct_span_err!(self.tcx.sess, span, E0283, @@ -1251,7 +1251,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // Same hacky approach as above to avoid deluging user // with error messages. if !ty.references_error() && !self.tcx.sess.has_errors() { - self.need_type_info(body_id, span, ty); + self.need_type_info_err(body_id, span, ty).emit(); } } @@ -1262,9 +1262,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let &SubtypePredicate { a_is_expected: _, a, b } = data.skip_binder(); // both must be type variables, or the other would've been instantiated assert!(a.is_ty_var() && b.is_ty_var()); - self.need_type_info(body_id, - obligation.cause.span, - a); + self.need_type_info_err(body_id, + obligation.cause.span, + a).emit(); } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 7b859635f60df..9ac55fda3c1f9 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3067,7 +3067,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { base: &'gcx hir::Expr, field: &Spanned<ast::Name>) -> Ty<'tcx> { let expr_t = self.check_expr_with_needs(base, needs); - let expr_t = self.structurally_resolved_type(expr.span, + let expr_t = self.structurally_resolved_type(base.span, expr_t); let mut private_candidate = None; let mut autoderef = self.autoderef(expr.span, expr_t); @@ -4080,7 +4080,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } else if idx_t.references_error() { idx_t } else { - let base_t = self.structurally_resolved_type(expr.span, base_t); + let base_t = self.structurally_resolved_type(base.span, base_t); match self.lookup_indexing(expr, base, base_t, idx_t, needs) { Some((index_ty, element_ty)) => { // two-phase not needed because index_ty is never mutable @@ -5053,7 +5053,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty } else { if !self.is_tainted_by_errors() { - self.need_type_info((**self).body_id, sp, ty); + self.need_type_info_err((**self).body_id, sp, ty) + .note("type must be known at this point") + .emit(); } self.demand_suptype(sp, self.tcx.types.err, ty); self.tcx.types.err diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 57c1d33cb5d2a..b0ee1154e863b 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -593,7 +593,7 @@ impl<'cx, 'gcx, 'tcx> Resolver<'cx, 'gcx, 'tcx> { fn report_error(&self, t: Ty<'tcx>) { if !self.tcx.sess.has_errors() { self.infcx - .need_type_info(Some(self.body.id()), self.span.to_span(&self.tcx), t); + .need_type_info_err(Some(self.body.id()), self.span.to_span(&self.tcx), t).emit(); } } } diff --git a/src/test/ui/span/issue-42234-unknown-receiver-type.stderr b/src/test/ui/span/issue-42234-unknown-receiver-type.stderr index 23315e3b76a4f..e1e13e9256dcd 100644 --- a/src/test/ui/span/issue-42234-unknown-receiver-type.stderr +++ b/src/test/ui/span/issue-42234-unknown-receiver-type.stderr @@ -5,6 +5,8 @@ LL | let x: Option<_> = None; | - consider giving `x` a type LL | x.unwrap().method_that_could_exist_on_some_type(); | ^^^^^^^^^^ cannot infer type for `T` + | + = note: type must be known at this point error[E0282]: type annotations needed --> $DIR/issue-42234-unknown-receiver-type.rs:22:5 @@ -12,6 +14,8 @@ error[E0282]: type annotations needed LL | / data.iter() //~ ERROR 22:5: 23:20: type annotations needed LL | | .sum::<_>() | |___________________^ cannot infer type for `_` + | + = note: type must be known at this point error: aborting due to 2 previous errors diff --git a/src/test/ui/span/method-and-field-eager-resolution.rs b/src/test/ui/span/method-and-field-eager-resolution.rs new file mode 100644 index 0000000000000..29011abb46016 --- /dev/null +++ b/src/test/ui/span/method-and-field-eager-resolution.rs @@ -0,0 +1,25 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that spans get only base in eager type resolution (structurally_resolve_type). + +fn main() { + let mut x = Default::default(); + x.0; + //~^ ERROR type annotations needed + x = 1; +} + +fn foo() { + let mut x = Default::default(); + x[0]; + //~^ ERROR type annotations needed + x = 1; +} diff --git a/src/test/ui/span/method-and-field-eager-resolution.stderr b/src/test/ui/span/method-and-field-eager-resolution.stderr new file mode 100644 index 0000000000000..21e19828a99cf --- /dev/null +++ b/src/test/ui/span/method-and-field-eager-resolution.stderr @@ -0,0 +1,23 @@ +error[E0282]: type annotations needed + --> $DIR/method-and-field-eager-resolution.rs:15:5 + | +LL | let mut x = Default::default(); + | ----- consider giving `x` a type +LL | x.0; + | ^ cannot infer type for `_` + | + = note: type must be known at this point + +error[E0282]: type annotations needed + --> $DIR/method-and-field-eager-resolution.rs:22:5 + | +LL | let mut x = Default::default(); + | ----- consider giving `x` a type +LL | x[0]; + | ^ cannot infer type for `_` + | + = note: type must be known at this point + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0282`.