Skip to content

Commit 5360e5d

Browse files
committed
More accurate description of unresolved imported item
State when the element that couldn't be found was expected to be a module, a generic item, a value or a macro. State what scope the E0433 the item couldn't be found in, when available.
1 parent fa1a67b commit 5360e5d

File tree

231 files changed

+758
-621
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

231 files changed

+758
-621
lines changed

compiler/rustc_resolve/src/build_reduced_graph.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -307,9 +307,15 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
307307
PathResult::NonModule(partial_res) => {
308308
expected_found_error(partial_res.expect_full_res())
309309
}
310-
PathResult::Failed { span, label, suggestion, .. } => {
311-
Err(VisResolutionError::FailedToResolve(span, label, suggestion))
312-
}
310+
PathResult::Failed {
311+
span, label, suggestion, segment_name, item_type, ..
312+
} => Err(VisResolutionError::FailedToResolve(
313+
span,
314+
segment_name,
315+
label,
316+
suggestion,
317+
item_type,
318+
)),
313319
PathResult::Indeterminate => Err(VisResolutionError::Indeterminate(path.span)),
314320
}
315321
}

compiler/rustc_resolve/src/diagnostics.rs

+43-10
Original file line numberDiff line numberDiff line change
@@ -794,9 +794,32 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
794794
ResolutionError::SelfImportOnlyInImportListWithNonEmptyPrefix => {
795795
self.dcx().create_err(errs::SelfImportOnlyInImportListWithNonEmptyPrefix { span })
796796
}
797-
ResolutionError::FailedToResolve { segment, label, suggestion, module } => {
798-
let mut err =
799-
struct_span_code_err!(self.dcx(), span, E0433, "failed to resolve: {}", &label);
797+
ResolutionError::FailedToResolve { segment, label, suggestion, module, item_type } => {
798+
let mut err = struct_span_code_err!(
799+
self.dcx(),
800+
span,
801+
E0433,
802+
"cannot find {item_type} `{segment}` in {}",
803+
match module {
804+
Some(ModuleOrUniformRoot::CurrentScope) | None => "this scope".to_string(),
805+
Some(ModuleOrUniformRoot::Module(module)) => {
806+
match module.kind {
807+
ModuleKind::Def(_, _, name) if name == kw::Empty => {
808+
"the crate root".to_string()
809+
}
810+
ModuleKind::Def(kind, def_id, name) => {
811+
format!("{} `{name}`", kind.descr(def_id))
812+
}
813+
ModuleKind::Block => "this scope".to_string(),
814+
}
815+
}
816+
Some(ModuleOrUniformRoot::CrateRootAndExternPrelude) => {
817+
"the crate root or the list of imported crates".to_string()
818+
}
819+
Some(ModuleOrUniformRoot::ExternPrelude) =>
820+
"the list of imported crates".to_string(),
821+
},
822+
);
800823
err.span_label(span, label);
801824

802825
if let Some((suggestions, msg, applicability)) = suggestion {
@@ -809,7 +832,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
809832

810833
if let Some(ModuleOrUniformRoot::Module(module)) = module
811834
&& let Some(module) = module.opt_def_id()
812-
&& let Some(segment) = segment
813835
{
814836
self.find_cfg_stripped(&mut err, &segment, module);
815837
}
@@ -989,10 +1011,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
9891011
VisResolutionError::AncestorOnly(span) => {
9901012
self.dcx().create_err(errs::AncestorOnly(span))
9911013
}
992-
VisResolutionError::FailedToResolve(span, label, suggestion) => self.into_struct_error(
993-
span,
994-
ResolutionError::FailedToResolve { segment: None, label, suggestion, module: None },
995-
),
1014+
VisResolutionError::FailedToResolve(span, segment, label, suggestion, item_type) => {
1015+
self.into_struct_error(
1016+
span,
1017+
ResolutionError::FailedToResolve {
1018+
segment,
1019+
label,
1020+
suggestion,
1021+
module: None,
1022+
item_type,
1023+
},
1024+
)
1025+
}
9961026
VisResolutionError::ExpectedFound(span, path_str, res) => {
9971027
self.dcx().create_err(errs::ExpectedModuleFound { span, res, path_str })
9981028
}
@@ -1997,16 +2027,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
19972027
)
19982028
} else if ident.name == sym::core {
19992029
(
2000-
format!("maybe a missing crate `{ident}`?"),
2030+
format!("you might be missing a crate named `{ident}`"),
20012031
Some((
20022032
vec![(ident.span, "std".to_string())],
20032033
"try using `std` instead of `core`".to_string(),
20042034
Applicability::MaybeIncorrect,
20052035
)),
20062036
)
2037+
} else if ident.is_raw_guess() {
2038+
// We're unlikely to have a crate called `r#super`, don't suggest anything.
2039+
("unresolved import".to_string(), None)
20072040
} else if self.tcx.sess.is_rust_2015() {
20082041
(
2009-
format!("maybe a missing crate `{ident}`?"),
2042+
format!("you might be missing a crate named `{ident}`"),
20102043
Some((
20112044
vec![],
20122045
format!(

compiler/rustc_resolve/src/ident.rs

+67-29
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use rustc_ast::{self as ast, NodeId};
2-
use rustc_errors::ErrorGuaranteed;
2+
use rustc_errors::{Applicability, ErrorGuaranteed};
33
use rustc_hir::def::{DefKind, Namespace, NonMacroAttrKind, PartialRes, PerNS};
44
use rustc_middle::bug;
55
use rustc_middle::ty;
@@ -1463,9 +1463,28 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
14631463
continue;
14641464
}
14651465
}
1466-
return PathResult::failed(ident, false, finalize.is_some(), module, || {
1467-
("there are too many leading `super` keywords".to_string(), None)
1468-
});
1466+
let mut item_type = "module";
1467+
let mut suggestion = None;
1468+
let label = if path.len() == 1
1469+
&& let Some(ribs) = ribs
1470+
&& let RibKind::Normal = ribs[ValueNS][ribs[ValueNS].len() - 1].kind
1471+
{
1472+
item_type = "item";
1473+
suggestion = Some((vec![(ident.span.shrink_to_lo(), "r#".to_string())], "if you still want to call your identifier `super`, use the raw identifier format".to_string(), Applicability::MachineApplicable));
1474+
"can't use `super` as an identifier"
1475+
} else if segment_idx == 0 {
1476+
"can't use `super` on the crate root, there are no further modules to go \"up\" to"
1477+
} else {
1478+
"there are too many leading `super` keywords"
1479+
};
1480+
return PathResult::failed(
1481+
ident,
1482+
false,
1483+
finalize.is_some(),
1484+
module,
1485+
|| (label.to_string(), suggestion),
1486+
item_type,
1487+
);
14691488
}
14701489
if segment_idx == 0 {
14711490
if name == kw::SelfLower {
@@ -1497,19 +1516,26 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
14971516

14981517
// Report special messages for path segment keywords in wrong positions.
14991518
if ident.is_path_segment_keyword() && segment_idx != 0 {
1500-
return PathResult::failed(ident, false, finalize.is_some(), module, || {
1501-
let name_str = if name == kw::PathRoot {
1502-
"crate root".to_string()
1503-
} else {
1504-
format!("`{name}`")
1505-
};
1506-
let label = if segment_idx == 1 && path[0].ident.name == kw::PathRoot {
1507-
format!("global paths cannot start with {name_str}")
1508-
} else {
1509-
format!("{name_str} in paths can only be used in start position")
1510-
};
1511-
(label, None)
1512-
});
1519+
return PathResult::failed(
1520+
ident,
1521+
false,
1522+
finalize.is_some(),
1523+
module,
1524+
|| {
1525+
let name_str = if name == kw::PathRoot {
1526+
"crate root".to_string()
1527+
} else {
1528+
format!("`{name}`")
1529+
};
1530+
let label = if segment_idx == 1 && path[0].ident.name == kw::PathRoot {
1531+
format!("global paths cannot start with {name_str}")
1532+
} else {
1533+
format!("{name_str} in paths can only be used in start position")
1534+
};
1535+
(label, None)
1536+
},
1537+
"module",
1538+
);
15131539
}
15141540

15151541
let binding = if let Some(module) = module {
@@ -1605,6 +1631,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
16051631
);
16061632
(label, None)
16071633
},
1634+
"module",
16081635
);
16091636
}
16101637
}
@@ -1619,18 +1646,29 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
16191646
}
16201647
}
16211648

1622-
return PathResult::failed(ident, is_last, finalize.is_some(), module, || {
1623-
self.report_path_resolution_error(
1624-
path,
1625-
opt_ns,
1626-
parent_scope,
1627-
ribs,
1628-
ignore_binding,
1629-
module,
1630-
segment_idx,
1631-
ident,
1632-
)
1633-
});
1649+
return PathResult::failed(
1650+
ident,
1651+
is_last,
1652+
finalize.is_some(),
1653+
module,
1654+
|| {
1655+
self.report_path_resolution_error(
1656+
path,
1657+
opt_ns,
1658+
parent_scope,
1659+
ribs,
1660+
ignore_binding,
1661+
module,
1662+
segment_idx,
1663+
ident,
1664+
)
1665+
},
1666+
match opt_ns {
1667+
Some(ValueNS) if path.len() == 1 => "item or value",
1668+
Some(ns) if path.len() - 1 == segment_idx => ns.descr(),
1669+
Some(_) | None => "item",
1670+
},
1671+
);
16341672
}
16351673
}
16361674
}

compiler/rustc_resolve/src/imports.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -900,16 +900,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
900900
label,
901901
suggestion,
902902
module,
903+
item_type,
903904
} => {
904905
if no_ambiguity {
905906
assert!(import.imported_module.get().is_none());
906907
self.report_error(
907908
span,
908909
ResolutionError::FailedToResolve {
909-
segment: Some(segment_name),
910+
segment: segment_name,
910911
label,
911912
suggestion,
912913
module,
914+
item_type,
913915
},
914916
);
915917
}

compiler/rustc_resolve/src/late.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -4273,14 +4273,16 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
42734273
suggestion,
42744274
module,
42754275
segment_name,
4276+
item_type,
42764277
} => {
42774278
return Err(respan(
42784279
span,
42794280
ResolutionError::FailedToResolve {
4280-
segment: Some(segment_name),
4281+
segment: segment_name,
42814282
label,
42824283
suggestion,
42834284
module,
4285+
item_type,
42844286
},
42854287
));
42864288
}

compiler/rustc_resolve/src/lib.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -228,10 +228,11 @@ enum ResolutionError<'a> {
228228
SelfImportOnlyInImportListWithNonEmptyPrefix,
229229
/// Error E0433: failed to resolve.
230230
FailedToResolve {
231-
segment: Option<Symbol>,
231+
segment: Symbol,
232232
label: String,
233233
suggestion: Option<Suggestion>,
234234
module: Option<ModuleOrUniformRoot<'a>>,
235+
item_type: &'static str,
235236
},
236237
/// Error E0434: can't capture dynamic environment in a fn item.
237238
CannotCaptureDynamicEnvironmentInFnItem,
@@ -287,7 +288,7 @@ enum ResolutionError<'a> {
287288
enum VisResolutionError<'a> {
288289
Relative2018(Span, &'a ast::Path),
289290
AncestorOnly(Span),
290-
FailedToResolve(Span, String, Option<Suggestion>),
291+
FailedToResolve(Span, Symbol, String, Option<Suggestion>, &'static str),
291292
ExpectedFound(Span, String, Res),
292293
Indeterminate(Span),
293294
ModuleOnly(Span),
@@ -428,6 +429,7 @@ enum PathResult<'a> {
428429
module: Option<ModuleOrUniformRoot<'a>>,
429430
/// The segment name of target
430431
segment_name: Symbol,
432+
item_type: &'static str,
431433
},
432434
}
433435

@@ -438,6 +440,7 @@ impl<'a> PathResult<'a> {
438440
finalize: bool,
439441
module: Option<ModuleOrUniformRoot<'a>>,
440442
label_and_suggestion: impl FnOnce() -> (String, Option<Suggestion>),
443+
item_type: &'static str,
441444
) -> PathResult<'a> {
442445
let (label, suggestion) =
443446
if finalize { label_and_suggestion() } else { (String::new(), None) };
@@ -448,6 +451,7 @@ impl<'a> PathResult<'a> {
448451
suggestion,
449452
is_error_from_last_segment,
450453
module,
454+
item_type,
451455
}
452456
}
453457
}

0 commit comments

Comments
 (0)