Skip to content

Commit

Permalink
Fix use placement for suggestions near main.
Browse files Browse the repository at this point in the history
  • Loading branch information
ehuss committed May 18, 2021
1 parent 5f10d31 commit 1400cb0
Show file tree
Hide file tree
Showing 11 changed files with 167 additions and 20 deletions.
16 changes: 8 additions & 8 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,15 +330,15 @@ impl UsePlacementFinder {
if self.span.map_or(true, |span| item.span < span)
&& !item.span.from_expansion()
{
self.span = Some(item.span.shrink_to_lo());
// don't insert between attributes and an item
if item.attrs.is_empty() {
self.span = Some(item.span.shrink_to_lo());
} else {
// find the first attribute on the item
for attr in &item.attrs {
if self.span.map_or(true, |span| attr.span < span) {
self.span = Some(attr.span.shrink_to_lo());
}
// find the first attribute on the item
// FIXME: This is broken for active attributes.
for attr in &item.attrs {
if !attr.span.is_dummy()
&& self.span.map_or(true, |span| attr.span < span)
{
self.span = Some(attr.span.shrink_to_lo());
}
}
}
Expand Down
16 changes: 8 additions & 8 deletions compiler/rustc_typeck/src/check/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1557,16 +1557,16 @@ impl intravisit::Visitor<'tcx> for UsePlacementFinder<'tcx> {
_ => {
if self.span.map_or(true, |span| item.span < span) {
if !item.span.from_expansion() {
self.span = Some(item.span.shrink_to_lo());
// Don't insert between attributes and an item.
let attrs = self.tcx.hir().attrs(item.hir_id());
if attrs.is_empty() {
self.span = Some(item.span.shrink_to_lo());
} else {
// Find the first attribute on the item.
for attr in attrs {
if self.span.map_or(true, |span| attr.span < span) {
self.span = Some(attr.span.shrink_to_lo());
}
// Find the first attribute on the item.
// FIXME: This is broken for active attributes.
for attr in attrs {
if !attr.span.is_dummy()
&& self.span.map_or(true, |span| attr.span < span)
{
self.span = Some(attr.span.shrink_to_lo());
}
}
}
Expand Down
39 changes: 39 additions & 0 deletions src/test/ui/resolve/use_suggestion_placement.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// run-rustfix
#![allow(dead_code)]

use m::A;

use std::collections::HashMap;

macro_rules! y {
() => {}
}

mod m {
pub const A: i32 = 0;
}

mod foo {
// FIXME: UsePlacementFinder is broken because active attributes are
// removed, and thus the `derive` attribute here is not in the AST.
// An inert attribute should work, though.
// #[derive(Debug)]
use std::path::Path;

#[allow(warnings)]
pub struct Foo;

// test whether the use suggestion isn't
// placed into the expansion of `#[derive(Debug)]
type Bar = Path; //~ ERROR cannot find
}

fn main() {
y!();
let _ = A; //~ ERROR cannot find
foo();
}

fn foo() {
type Dict<K, V> = HashMap<K, V>; //~ ERROR cannot find
}
9 changes: 8 additions & 1 deletion src/test/ui/resolve/use_suggestion_placement.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// run-rustfix
#![allow(dead_code)]

macro_rules! y {
() => {}
}
Expand All @@ -7,7 +10,11 @@ mod m {
}

mod foo {
#[derive(Debug)]
// FIXME: UsePlacementFinder is broken because active attributes are
// removed, and thus the `derive` attribute here is not in the AST.
// An inert attribute should work, though.
// #[derive(Debug)]
#[allow(warnings)]
pub struct Foo;

// test whether the use suggestion isn't
Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/resolve/use_suggestion_placement.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0412]: cannot find type `Path` in this scope
--> $DIR/use_suggestion_placement.rs:15:16
--> $DIR/use_suggestion_placement.rs:22:16
|
LL | type Bar = Path;
| ^^^^ not found in this scope
Expand All @@ -10,7 +10,7 @@ LL | use std::path::Path;
|

error[E0425]: cannot find value `A` in this scope
--> $DIR/use_suggestion_placement.rs:20:13
--> $DIR/use_suggestion_placement.rs:27:13
|
LL | let _ = A;
| ^ not found in this scope
Expand All @@ -21,7 +21,7 @@ LL | use m::A;
|

error[E0412]: cannot find type `HashMap` in this scope
--> $DIR/use_suggestion_placement.rs:25:23
--> $DIR/use_suggestion_placement.rs:32:23
|
LL | type Dict<K, V> = HashMap<K, V>;
| ^^^^^^^ not found in this scope
Expand Down
13 changes: 13 additions & 0 deletions src/test/ui/suggestions/use-placement-resolve.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// compile-flags: --test
// run-rustfix
// Checks that the `use` suggestion appears *below* this inner attribute.
// There was an issue where the test synthetic #[allow(dead)] attribute on
// main which has a dummy span caused the suggestion to be placed at the top
// of the file.
#![allow(unused)]

use std::fmt::Debug;

fn main() {}

fn foobar<T: Debug>(x: T) {} //~ ERROR expected trait, found derive macro
11 changes: 11 additions & 0 deletions src/test/ui/suggestions/use-placement-resolve.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// compile-flags: --test
// run-rustfix
// Checks that the `use` suggestion appears *below* this inner attribute.
// There was an issue where the test synthetic #[allow(dead)] attribute on
// main which has a dummy span caused the suggestion to be placed at the top
// of the file.
#![allow(unused)]

fn main() {}

fn foobar<T: Debug>(x: T) {} //~ ERROR expected trait, found derive macro
14 changes: 14 additions & 0 deletions src/test/ui/suggestions/use-placement-resolve.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error[E0404]: expected trait, found derive macro `Debug`
--> $DIR/use-placement-resolve.rs:11:14
|
LL | fn foobar<T: Debug>(x: T) {}
| ^^^^^ not a trait
|
help: consider importing this trait instead
|
LL | use std::fmt::Debug;
|

error: aborting due to previous error

For more information about this error, try `rustc --explain E0404`.
22 changes: 22 additions & 0 deletions src/test/ui/suggestions/use-placement-typeck.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// compile-flags: --test
// run-rustfix
// Checks that the `use` suggestion appears *below* this inner attribute.
// There was an issue where the test synthetic #[allow(dead)] attribute on
// main which has a dummy span caused the suggestion to be placed at the top
// of the file.
#![allow(unused)]

use m::Foo;

fn main() {
let s = m::S;
s.abc(); //~ ERROR no method named `abc`
}

mod m {
pub trait Foo {
fn abc(&self) {}
}
pub struct S;
impl Foo for S{}
}
20 changes: 20 additions & 0 deletions src/test/ui/suggestions/use-placement-typeck.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// compile-flags: --test
// run-rustfix
// Checks that the `use` suggestion appears *below* this inner attribute.
// There was an issue where the test synthetic #[allow(dead)] attribute on
// main which has a dummy span caused the suggestion to be placed at the top
// of the file.
#![allow(unused)]

fn main() {
let s = m::S;
s.abc(); //~ ERROR no method named `abc`
}

mod m {
pub trait Foo {
fn abc(&self) {}
}
pub struct S;
impl Foo for S{}
}
21 changes: 21 additions & 0 deletions src/test/ui/suggestions/use-placement-typeck.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0599]: no method named `abc` found for struct `S` in the current scope
--> $DIR/use-placement-typeck.rs:11:7
|
LL | s.abc();
| ^^^ method not found in `S`
...
LL | fn abc(&self) {}
| --- the method is available for `S` here
LL | }
LL | pub struct S;
| ------------- method `abc` not found for this
|
= help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
|
LL | use m::Foo;
|

error: aborting due to previous error

For more information about this error, try `rustc --explain E0599`.

0 comments on commit 1400cb0

Please sign in to comment.