From b2562fbcbaaafdb06ed343c7473db769a20afd89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 22 May 2018 19:27:41 -0700 Subject: [PATCH] Tweak `main` type arguments and where clause spans Tweak the spans for error when finding type arguments or where clauses in main and start functions. --- src/librustc/hir/mod.rs | 12 ++++++++ src/librustc_typeck/lib.rs | 42 +++++++++++++++++----------- src/test/compile-fail/issue-1900.rs | 2 +- src/test/ui/error-codes/E0131.stderr | 4 +-- src/test/ui/error-codes/E0646.stderr | 6 ++-- src/test/ui/error-codes/E0647.stderr | 10 +++---- src/test/ui/issue-50714-1.stderr | 10 +++---- src/test/ui/issue-50714.stderr | 6 ++-- 8 files changed, 55 insertions(+), 37 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index caae79961a6..71d815f3893 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -598,6 +598,18 @@ pub struct WhereClause { pub predicates: HirVec, } +impl WhereClause { + pub fn span(&self) -> Option { + self.predicates.iter().map(|predicate| predicate.span()) + .fold(None, |acc, i| match (acc, i) { + (None, i) => Some(i), + (Some(acc), i) => { + Some(acc.to(i)) + } + }) + } +} + /// A single predicate in a `where` clause #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum WherePredicate { diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index ea48e839a7f..0cd741a11d5 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -186,18 +186,23 @@ fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, Some(hir_map::NodeItem(it)) => { match it.node { hir::ItemFn(.., ref generics, _) => { + let mut error = false; if !generics.params.is_empty() { struct_span_err!(tcx.sess, generics.span, E0131, - "main function is not allowed to have type parameters") + "`main` function is not allowed to have type parameters") .span_label(generics.span, - "main cannot have type parameters") + "`main` cannot have type parameters") .emit(); - return; + error = true; } - if !generics.where_clause.predicates.is_empty() { - struct_span_err!(tcx.sess, main_span, E0646, - "main function is not allowed to have a where clause") - .emit(); + if let Some(sp) = generics.where_clause.span() { + struct_span_err!(tcx.sess, sp, E0646, + "`main` function is not allowed to have a `where` clause") + .span_label(sp, "`main` cannot have a `where` clause") + .emit(); + error = true; + } + if error { return; } } @@ -251,19 +256,24 @@ fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, match tcx.hir.find(start_id) { Some(hir_map::NodeItem(it)) => { match it.node { - hir::ItemFn(..,ref ps,_) => { - if !ps.params.is_empty() { - struct_span_err!(tcx.sess, ps.span, E0132, + hir::ItemFn(.., ref generics, _) => { + let mut error = false; + if !generics.params.is_empty() { + struct_span_err!(tcx.sess, generics.span, E0132, "start function is not allowed to have type parameters") - .span_label(ps.span, + .span_label(generics.span, "start function cannot have type parameters") .emit(); - return; + error = true; } - if !ps.where_clause.predicates.is_empty() { - struct_span_err!(tcx.sess, start_span, E0647, - "start function is not allowed to have a where clause") - .emit(); + if let Some(sp) = generics.where_clause.span() { + struct_span_err!(tcx.sess, sp, E0647, + "start function is not allowed to have a `where` clause") + .span_label(sp, "start function cannot have a `where` clause") + .emit(); + error = true; + } + if error { return; } } diff --git a/src/test/compile-fail/issue-1900.rs b/src/test/compile-fail/issue-1900.rs index ae46ab8116f..c7564a9355b 100644 --- a/src/test/compile-fail/issue-1900.rs +++ b/src/test/compile-fail/issue-1900.rs @@ -8,5 +8,5 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: main function is not allowed to have type parameters +// error-pattern: `main` function is not allowed to have type parameters fn main() { } diff --git a/src/test/ui/error-codes/E0131.stderr b/src/test/ui/error-codes/E0131.stderr index 3774e21c214..ba9355763f6 100644 --- a/src/test/ui/error-codes/E0131.stderr +++ b/src/test/ui/error-codes/E0131.stderr @@ -1,8 +1,8 @@ -error[E0131]: main function is not allowed to have type parameters +error[E0131]: `main` function is not allowed to have type parameters --> $DIR/E0131.rs:11:8 | LL | fn main() { - | ^^^ main cannot have type parameters + | ^^^ `main` cannot have type parameters error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0646.stderr b/src/test/ui/error-codes/E0646.stderr index 96da22a643c..7b2de775a10 100644 --- a/src/test/ui/error-codes/E0646.stderr +++ b/src/test/ui/error-codes/E0646.stderr @@ -1,8 +1,8 @@ -error[E0646]: main function is not allowed to have a where clause - --> $DIR/E0646.rs:11:1 +error[E0646]: `main` function is not allowed to have a `where` clause + --> $DIR/E0646.rs:11:17 | LL | fn main() where (): Copy {} //~ ERROR [E0646] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^ `main` cannot have a `where` clause error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0647.stderr b/src/test/ui/error-codes/E0647.stderr index f02407dcea6..afd37a7edf4 100644 --- a/src/test/ui/error-codes/E0647.stderr +++ b/src/test/ui/error-codes/E0647.stderr @@ -1,10 +1,8 @@ -error[E0647]: start function is not allowed to have a where clause - --> $DIR/E0647.rs:17:1 +error[E0647]: start function is not allowed to have a `where` clause + --> $DIR/E0647.rs:17:56 | -LL | / fn start(_: isize, _: *const *const u8) -> isize where (): Copy { //~ ERROR [E0647] -LL | | 0 -LL | | } - | |_^ +LL | fn start(_: isize, _: *const *const u8) -> isize where (): Copy { //~ ERROR [E0647] + | ^^^^^^^^ start function cannot have a `where` clause error: aborting due to previous error diff --git a/src/test/ui/issue-50714-1.stderr b/src/test/ui/issue-50714-1.stderr index b93183d2f24..5c92516cbc5 100644 --- a/src/test/ui/issue-50714-1.stderr +++ b/src/test/ui/issue-50714-1.stderr @@ -1,10 +1,8 @@ -error[E0647]: start function is not allowed to have a where clause - --> $DIR/issue-50714-1.rs:19:1 +error[E0647]: start function is not allowed to have a `where` clause + --> $DIR/issue-50714-1.rs:19:56 | -LL | / fn start(_: isize, _: *const *const u8) -> isize where fn(&()): Eq { //~ ERROR [E0647] -LL | | 0 -LL | | } - | |_^ +LL | fn start(_: isize, _: *const *const u8) -> isize where fn(&()): Eq { //~ ERROR [E0647] + | ^^^^^^^^^^^ start function cannot have a `where` clause error: aborting due to previous error diff --git a/src/test/ui/issue-50714.stderr b/src/test/ui/issue-50714.stderr index 8cdcfe4abe2..e2c99980e1b 100644 --- a/src/test/ui/issue-50714.stderr +++ b/src/test/ui/issue-50714.stderr @@ -1,8 +1,8 @@ -error[E0646]: main function is not allowed to have a where clause - --> $DIR/issue-50714.rs:13:1 +error[E0646]: `main` function is not allowed to have a `where` clause + --> $DIR/issue-50714.rs:13:17 | LL | fn main() where fn(&()): Eq {} //~ ERROR [E0646] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^ `main` cannot have a `where` clause error: aborting due to previous error