Skip to content

Commit

Permalink
Make new type param suggestion more targetted
Browse files Browse the repository at this point in the history
Do not suggest new type param when encountering a missing type in an ADT
field with generic parameters.

Fix #72640.
  • Loading branch information
estebank committed Jun 13, 2020
1 parent bb86748 commit 4606168
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 7 deletions.
1 change: 1 addition & 0 deletions src/librustc_resolve/build_reduced_graph.rs
Expand Up @@ -485,6 +485,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
module_path.push(Segment {
ident: Ident { name: kw::PathRoot, span: source.ident.span },
id: Some(self.r.next_node_id()),
has_args: false,
});
source.ident.name = crate_name;
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_resolve/late/diagnostics.rs
Expand Up @@ -920,7 +920,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
path: &[Segment],
) -> Option<(Span, &'static str, String, Applicability)> {
let ident = match path {
[segment] => segment.ident,
[segment] if !segment.has_args => segment.ident,
_ => return None,
};
match (
Expand Down
14 changes: 8 additions & 6 deletions src/librustc_resolve/lib.rs
Expand Up @@ -225,13 +225,15 @@ enum VisResolutionError<'a> {
ModuleOnly(Span),
}

// A minimal representation of a path segment. We use this in resolve because
// we synthesize 'path segments' which don't have the rest of an AST or HIR
// `PathSegment`.
/// A minimal representation of a path segment. We use this in resolve because we synthesize 'path
/// segments' which don't have the rest of an AST or HIR `PathSegment`.
#[derive(Clone, Copy, Debug)]
pub struct Segment {
ident: Ident,
id: Option<NodeId>,
/// Signals whether this `PathSegment` has generic arguments. Used to avoid providing
/// nonsensical suggestions.
has_args: bool,
}

impl Segment {
Expand All @@ -240,7 +242,7 @@ impl Segment {
}

fn from_ident(ident: Ident) -> Segment {
Segment { ident, id: None }
Segment { ident, id: None, has_args: false }
}

fn names_to_string(segments: &[Segment]) -> String {
Expand All @@ -250,7 +252,7 @@ impl Segment {

impl<'a> From<&'a ast::PathSegment> for Segment {
fn from(seg: &'a ast::PathSegment) -> Segment {
Segment { ident: seg.ident, id: Some(seg.id) }
Segment { ident: seg.ident, id: Some(seg.id), has_args: seg.args.is_some() }
}
}

Expand Down Expand Up @@ -2017,7 +2019,7 @@ impl<'a> Resolver<'a> {
path, opt_ns, record_used, path_span, crate_lint,
);

for (i, &Segment { ident, id }) in path.iter().enumerate() {
for (i, &Segment { ident, id, has_args: _ }) in path.iter().enumerate() {
debug!("resolve_path ident {} {:?} {:?}", i, ident, id);
let record_segment_res = |this: &mut Self, res| {
if record_used {
Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/suggestions/type-not-found-in-adt-field.rs
@@ -0,0 +1,5 @@
struct S {
m: Vec<Hashmap<String, ()>>, //~ ERROR cannot find type `Hashmap` in this scope
//~^ NOTE not found in this scope
}
fn main() {}
9 changes: 9 additions & 0 deletions src/test/ui/suggestions/type-not-found-in-adt-field.stderr
@@ -0,0 +1,9 @@
error[E0412]: cannot find type `Hashmap` in this scope
--> $DIR/type-not-found-in-adt-field.rs:2:12
|
LL | m: Vec<Hashmap<String, ()>>,
| ^^^^^^^ not found in this scope

error: aborting due to previous error

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

0 comments on commit 4606168

Please sign in to comment.