Skip to content

Commit 4606168

Browse files
committed
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.
1 parent bb86748 commit 4606168

File tree

5 files changed

+24
-7
lines changed

5 files changed

+24
-7
lines changed

src/librustc_resolve/build_reduced_graph.rs

+1
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
485485
module_path.push(Segment {
486486
ident: Ident { name: kw::PathRoot, span: source.ident.span },
487487
id: Some(self.r.next_node_id()),
488+
has_args: false,
488489
});
489490
source.ident.name = crate_name;
490491
}

src/librustc_resolve/late/diagnostics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -920,7 +920,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
920920
path: &[Segment],
921921
) -> Option<(Span, &'static str, String, Applicability)> {
922922
let ident = match path {
923-
[segment] => segment.ident,
923+
[segment] if !segment.has_args => segment.ident,
924924
_ => return None,
925925
};
926926
match (

src/librustc_resolve/lib.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -225,13 +225,15 @@ enum VisResolutionError<'a> {
225225
ModuleOnly(Span),
226226
}
227227

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

237239
impl Segment {
@@ -240,7 +242,7 @@ impl Segment {
240242
}
241243

242244
fn from_ident(ident: Ident) -> Segment {
243-
Segment { ident, id: None }
245+
Segment { ident, id: None, has_args: false }
244246
}
245247

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

251253
impl<'a> From<&'a ast::PathSegment> for Segment {
252254
fn from(seg: &'a ast::PathSegment) -> Segment {
253-
Segment { ident: seg.ident, id: Some(seg.id) }
255+
Segment { ident: seg.ident, id: Some(seg.id), has_args: seg.args.is_some() }
254256
}
255257
}
256258

@@ -2017,7 +2019,7 @@ impl<'a> Resolver<'a> {
20172019
path, opt_ns, record_used, path_span, crate_lint,
20182020
);
20192021

2020-
for (i, &Segment { ident, id }) in path.iter().enumerate() {
2022+
for (i, &Segment { ident, id, has_args: _ }) in path.iter().enumerate() {
20212023
debug!("resolve_path ident {} {:?} {:?}", i, ident, id);
20222024
let record_segment_res = |this: &mut Self, res| {
20232025
if record_used {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
struct S {
2+
m: Vec<Hashmap<String, ()>>, //~ ERROR cannot find type `Hashmap` in this scope
3+
//~^ NOTE not found in this scope
4+
}
5+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0412]: cannot find type `Hashmap` in this scope
2+
--> $DIR/type-not-found-in-adt-field.rs:2:12
3+
|
4+
LL | m: Vec<Hashmap<String, ()>>,
5+
| ^^^^^^^ not found in this scope
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0412`.

0 commit comments

Comments
 (0)