From 137ffa10229bfec497a446d24045388ee3c418d6 Mon Sep 17 00:00:00 2001 From: David Wood Date: Fri, 12 Apr 2019 01:19:02 +0200 Subject: [PATCH] Improve robustness of nested check. This commit removes the assumption that the start of a use statement will always be on one line with a single space - which was silly in the first place. --- src/librustc_resolve/error_reporting.rs | 45 +++++++++++++------------ src/test/ui/issue-59764.fixed | 11 ++++++ src/test/ui/issue-59764.rs | 14 ++++++++ src/test/ui/issue-59764.stderr | 25 +++++++++++--- 4 files changed, 69 insertions(+), 26 deletions(-) diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs index eea8cb80f69e..5372c4ee44bd 100644 --- a/src/librustc_resolve/error_reporting.rs +++ b/src/librustc_resolve/error_reporting.rs @@ -827,28 +827,29 @@ fn find_span_immediately_after_crate_name( module_name, use_span); let source_map = sess.source_map(); - // Get position of the first `{` character for the use statement. - // ie. `use foo::{a, b::{c, d}};` - // ^ - let pos_of_use_tree_left_bracket = source_map.span_until_char(use_span, '{').hi(); - debug!("find_span_immediately_after_crate_name: pos_of_use_tree_left_bracket={:?}", - pos_of_use_tree_left_bracket); + // Using `use issue_59764::foo::{baz, makro};` as an example throughout.. + let mut num_colons = 0; + // Find second colon.. `use issue_59764:` + let until_second_colon = source_map.span_take_while(use_span, |c| { + if *c == ':' { num_colons += 1; } + match c { + ':' if num_colons == 2 => false, + _ => true, + } + }); + // Find everything after the second colon.. `foo::{baz, makro};` + let from_second_colon = use_span.with_lo(until_second_colon.hi() + BytePos(1)); - // Calculate the expected difference between the first `{` character and the start of a - // use statement. - // ie. `use foo::{..};` - // ^^^^ - // | ^^^ - // 4 | ^^ - // 3 | - // 2 - let expected_difference = BytePos((module_name.as_str().len() + 4 + 2) as u32); - debug!("find_span_immediately_after_crate_name: expected_difference={:?}", - expected_difference); - let actual_difference = pos_of_use_tree_left_bracket - use_span.lo(); - debug!("find_span_immediately_after_crate_name: actual_difference={:?}", - actual_difference); + let mut found_a_non_whitespace_character = false; + // Find the first non-whitespace character in `from_second_colon`.. `f` + let after_second_colon = source_map.span_take_while(from_second_colon, |c| { + if found_a_non_whitespace_character { return false; } + if !c.is_whitespace() { found_a_non_whitespace_character = true; } + true + }); - (expected_difference == actual_difference, - use_span.with_lo(use_span.lo() + expected_difference)) + // Find the first `{` in from_second_colon.. `foo::{` + let next_left_bracket = source_map.span_through_char(from_second_colon, '{'); + + (next_left_bracket == after_second_colon, from_second_colon) } diff --git a/src/test/ui/issue-59764.fixed b/src/test/ui/issue-59764.fixed index ff193fce7eb1..ad3bab50cfca 100644 --- a/src/test/ui/issue-59764.fixed +++ b/src/test/ui/issue-59764.fixed @@ -109,6 +109,17 @@ mod renamed_multiple_imports { //~^ ERROR unresolved import `issue_59764::foo::makro` [E0432] } +mod lots_of_whitespace { + use issue_59764::{makro as foobar, + + foobaz, + + + foo::{baz} //~ ERROR unresolved import `issue_59764::foo::makro` [E0432] + + }; +} + // Simple case.. use issue_59764::makro; diff --git a/src/test/ui/issue-59764.rs b/src/test/ui/issue-59764.rs index c68471adaad5..0c6787691de0 100644 --- a/src/test/ui/issue-59764.rs +++ b/src/test/ui/issue-59764.rs @@ -109,6 +109,20 @@ mod renamed_multiple_imports { //~^ ERROR unresolved import `issue_59764::foo::makro` [E0432] } +mod lots_of_whitespace { + use + issue_59764::{ + + foobaz, + + + foo::{baz, + + makro as foobar} //~ ERROR unresolved import `issue_59764::foo::makro` [E0432] + + }; +} + // Simple case.. use issue_59764::foo::makro; diff --git a/src/test/ui/issue-59764.stderr b/src/test/ui/issue-59764.stderr index fe9354731846..89b1f84605dc 100644 --- a/src/test/ui/issue-59764.stderr +++ b/src/test/ui/issue-59764.stderr @@ -196,7 +196,24 @@ LL | use issue_59764::{makro as foobar, foo::{baz}}; | error[E0432]: unresolved import `issue_59764::foo::makro` - --> $DIR/issue-59764.rs:114:5 + --> $DIR/issue-59764.rs:121:17 + | +LL | makro as foobar} + | ^^^^^^^^^^^^^^^ no `makro` in `foo` + | + = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined +help: a macro with this name exists at the root of the crate + | +LL | use issue_59764::{makro as foobar, +LL | +LL | foobaz, +LL | +LL | +LL | foo::{baz} + ... + +error[E0432]: unresolved import `issue_59764::foo::makro` + --> $DIR/issue-59764.rs:128:5 | LL | use issue_59764::foo::makro; | ^^^^^^^^^^^^^^^^^^^^^^^ no `makro` in `foo` @@ -208,7 +225,7 @@ LL | use issue_59764::makro; | ^^^^^^^^^^^^^^^^^^ error: cannot determine resolution for the macro `makro` - --> $DIR/issue-59764.rs:117:1 + --> $DIR/issue-59764.rs:131:1 | LL | makro!(bar); | ^^^^^ @@ -216,12 +233,12 @@ LL | makro!(bar); = note: import resolution is stuck, try simplifying macro imports error[E0425]: cannot find function `bar` in this scope - --> $DIR/issue-59764.rs:121:5 + --> $DIR/issue-59764.rs:135:5 | LL | bar(); | ^^^ not found in this scope -error: aborting due to 17 previous errors +error: aborting due to 18 previous errors Some errors occurred: E0425, E0432. For more information about an error, try `rustc --explain E0425`.