diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 283c6264717f..a8f20815a9a8 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -281,11 +281,10 @@ fn check_for_static_nan(cx: &MatchCheckCtxt, pat: &Pat) { Ok(_) => {} Err(err) => { - let subspan = p.span.lo <= err.span.lo && err.span.hi <= p.span.hi; span_err!(cx.tcx.sess, err.span, E0471, "constant evaluation error: {}", err.description()); - if !subspan { + if !p.span.contains(err.span) { cx.tcx.sess.span_note(p.span, "in pattern here") } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index dd15c1325603..a05d9b19d232 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1692,12 +1692,10 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>, } } Err(ref r) => { - let subspan = - ast_ty.span.lo <= r.span.lo && r.span.hi <= ast_ty.span.hi; span_err!(tcx.sess, r.span, E0250, "array length constant evaluation error: {}", r.description()); - if !subspan { + if !ast_ty.span.contains(r.span) { span_note!(tcx.sess, ast_ty.span, "for array length here") } this.tcx().types.err diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 39805bfc8a3e..7a70bc73b733 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1173,9 +1173,12 @@ fn convert_enum_def<'tcx>(tcx: &ty::ctxt<'tcx>, None }, Err(err) => { - span_err!(tcx.sess, err.span, E0080, - "constant evaluation error: {}", - err.description()); + span_err!(tcx.sess, err.span, E0080, + "constant evaluation error: {}", + err.description()); + if !e.span.contains(err.span) { + tcx.sess.span_note(e.span, "for enum discriminant here"); + } None } } diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 1f8c726bf688..aa4dd1d53c50 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -142,6 +142,10 @@ impl Span { pub fn substitute_dummy(self, other: Span) -> Span { if self == DUMMY_SP { other } else { self } } + + pub fn contains(self, other: Span) -> bool { + self.lo <= other.lo && other.hi <= self.hi + } } #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] @@ -1011,7 +1015,7 @@ impl CodeMap { let span_comes_from_this_expansion = info.callee.span.map_or(span == info.call_site, |mac_span| { - mac_span.lo <= span.lo && span.hi <= mac_span.hi + mac_span.contains(span) }); debug!("span_allows_unstable: span: {:?} call_site: {:?} callee: {:?}", diff --git a/src/test/compile-fail/const-eval-span.rs b/src/test/compile-fail/const-eval-span.rs new file mode 100644 index 000000000000..8e9209916f35 --- /dev/null +++ b/src/test/compile-fail/const-eval-span.rs @@ -0,0 +1,24 @@ +// Copyright 2015 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. + +// Check that error in constant evaluation of enum discriminant +// provides the context for what caused the evaluation. + +struct S(i32); + +const CONSTANT: S = S(0); +//~^ ERROR: constant evaluation error: unsupported constant expr + +enum E { + V = CONSTANT, + //~^ NOTE: for enum discriminant here +} + +fn main() {}