Make new type param suggestion more targetted

Do not suggest new type param when encountering a missing type in an ADT
field with generic parameters.

Fix #72640.
This commit is contained in:
Esteban Küber 2020-06-13 11:12:29 -07:00
parent bb8674837a
commit 4606168dd5
5 changed files with 24 additions and 7 deletions

View file

@ -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;
}

View file

@ -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 (

View file

@ -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 {
@ -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 {
@ -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() }
}
}
@ -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 {

View file

@ -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() {}

View file

@ -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`.