diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 99db5f9b62435..0e5c786cd8dcf 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -23,11 +23,17 @@ use super::{ ObjectSafetyViolation, }; +use errors::DiagnosticBuilder; use fmt_macros::{Parser, Piece, Position}; +use hir::{intravisit, Local, Pat}; +use hir::intravisit::{Visitor, NestedVisitorMap}; +use hir::map::NodeExpr; use hir::def_id::DefId; use infer::{self, InferCtxt}; use infer::type_variable::TypeVariableOrigin; use rustc::lint::builtin::EXTRA_REQUIREMENT_IN_IMPL; +use std::fmt; +use syntax::ast; use ty::{self, AdtKind, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable}; use ty::error::ExpectedFound; use ty::fast_reject; @@ -35,12 +41,8 @@ use ty::fold::TypeFolder; use ty::subst::Subst; use util::nodemap::{FxHashMap, FxHashSet}; -use std::fmt; -use syntax::ast; -use hir::{intravisit, Local, Pat}; -use hir::intravisit::{Visitor, NestedVisitorMap}; use syntax_pos::{DUMMY_SP, Span}; -use errors::DiagnosticBuilder; + #[derive(Debug, PartialEq, Eq, Hash)] pub struct TraitErrorKey<'tcx> { @@ -848,15 +850,18 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { err.span_label(cause.span, &format!("cannot infer type for `{}`", name)); - let expr = self.tcx.hir.expect_expr(cause.body_id); - let mut local_visitor = FindLocalByTypeVisitor { infcx: &self, target_ty: &ty, found_pattern: None, }; - local_visitor.visit_expr(expr); + // #40294: cause.body_id can also be a fn declaration. + // Currently, if it's anything other than NodeExpr, we just ignore it + match self.tcx.hir.find(cause.body_id) { + Some(NodeExpr(expr)) => local_visitor.visit_expr(expr), + _ => () + } if let Some(pattern) = local_visitor.found_pattern { let pattern_span = pattern.span; diff --git a/src/test/ui/codemap_tests/issue-38812-2.rs b/src/test/ui/type-check/issue-38812-2.rs similarity index 100% rename from src/test/ui/codemap_tests/issue-38812-2.rs rename to src/test/ui/type-check/issue-38812-2.rs diff --git a/src/test/ui/codemap_tests/issue-38812-2.stderr b/src/test/ui/type-check/issue-38812-2.stderr similarity index 100% rename from src/test/ui/codemap_tests/issue-38812-2.stderr rename to src/test/ui/type-check/issue-38812-2.stderr diff --git a/src/test/ui/codemap_tests/issue-38812.rs b/src/test/ui/type-check/issue-38812.rs similarity index 100% rename from src/test/ui/codemap_tests/issue-38812.rs rename to src/test/ui/type-check/issue-38812.rs diff --git a/src/test/ui/codemap_tests/issue-38812.stderr b/src/test/ui/type-check/issue-38812.stderr similarity index 100% rename from src/test/ui/codemap_tests/issue-38812.stderr rename to src/test/ui/type-check/issue-38812.stderr diff --git a/src/test/ui/type-check/issue-40294.rs b/src/test/ui/type-check/issue-40294.rs new file mode 100644 index 0000000000000..d30a425d1099b --- /dev/null +++ b/src/test/ui/type-check/issue-40294.rs @@ -0,0 +1,23 @@ +// Copyright 2017 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Foo: Sized { + fn foo(self); +} + +fn foo<'a,'b,T>(x: &'a T, y: &'b T) + where &'a T : Foo, + &'b T : Foo +{ + x.foo(); + y.foo(); +} + +fn main() { } diff --git a/src/test/ui/type-check/issue-40294.stderr b/src/test/ui/type-check/issue-40294.stderr new file mode 100644 index 0000000000000..5c388c9d602ea --- /dev/null +++ b/src/test/ui/type-check/issue-40294.stderr @@ -0,0 +1,15 @@ +error[E0282]: type annotations needed + --> $DIR/issue-40294.rs:15:1 + | +15 | fn foo<'a,'b,T>(x: &'a T, y: &'b T) + | _^ starting here... +16 | | where &'a T : Foo, +17 | | &'b T : Foo +18 | | { +19 | | x.foo(); +20 | | y.foo(); +21 | | } + | |_^ ...ending here: cannot infer type for `&'a T` + +error: aborting due to previous error +