Skip to content

Commit 93bb780

Browse files
committed
review comments and tweaks
1 parent 55e4e2d commit 93bb780

File tree

6 files changed

+119
-78
lines changed

6 files changed

+119
-78
lines changed

src/librustc_resolve/late.rs

Lines changed: 62 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -316,22 +316,7 @@ impl<'a> PathSource<'a> {
316316
}
317317
}
318318

319-
struct LateResolutionVisitor<'a, 'b> {
320-
r: &'b mut Resolver<'a>,
321-
322-
/// The module that represents the current item scope.
323-
parent_scope: ParentScope<'a>,
324-
325-
/// The current set of local scopes for types and values.
326-
/// FIXME #4948: Reuse ribs to avoid allocation.
327-
ribs: PerNS<Vec<Rib<'a>>>,
328-
329-
/// The current set of local scopes, for labels.
330-
label_ribs: Vec<Rib<'a, NodeId>>,
331-
332-
/// The trait that the current context can refer to.
333-
current_trait_ref: Option<(Module<'a>, TraitRef)>,
334-
319+
struct DiagnosticMetadata {
335320
/// The current trait's associated types' ident, used for diagnostic suggestions.
336321
current_trait_assoc_types: Vec<Ident>,
337322

@@ -352,7 +337,27 @@ struct LateResolutionVisitor<'a, 'b> {
352337
current_type_ascription: Vec<Span>,
353338

354339
/// Only used for better errors on `let <pat>: <expr, not type>;`.
355-
current_let_binding: Option<(Span, Span)>,
340+
current_let_binding: Option<(Span, Option<Span>, Option<Span>)>,
341+
}
342+
343+
struct LateResolutionVisitor<'a, 'b> {
344+
r: &'b mut Resolver<'a>,
345+
346+
/// The module that represents the current item scope.
347+
parent_scope: ParentScope<'a>,
348+
349+
/// The current set of local scopes for types and values.
350+
/// FIXME #4948: Reuse ribs to avoid allocation.
351+
ribs: PerNS<Vec<Rib<'a>>>,
352+
353+
/// The current set of local scopes, for labels.
354+
label_ribs: Vec<Rib<'a, NodeId>>,
355+
356+
/// The trait that the current context can refer to.
357+
current_trait_ref: Option<(Module<'a>, TraitRef)>,
358+
359+
/// Fields used to add information to diagnostic errors.
360+
diagnostic_metadata: DiagnosticMetadata,
356361
}
357362

358363
/// Walks the whole crate in DFS order, visiting each item, resolving names as it goes.
@@ -376,18 +381,18 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
376381
self.resolve_expr(expr, None);
377382
}
378383
fn visit_local(&mut self, local: &'tcx Local) {
379-
debug!("visit_local {:?} {:?} {:?}", local, local.pat, local.pat.kind);
380-
let val = match local {
381-
Local { pat, ty: Some(ty), init: None, .. } => match pat.kind {
382-
// We check for this to avoid tuple struct fields.
383-
PatKind::Wild => None,
384-
_ => Some((pat.span, ty.span)),
385-
},
386-
_ => None,
384+
let local_spans = match local.pat.kind {
385+
// We check for this to avoid tuple struct fields.
386+
PatKind::Wild => None,
387+
_ => Some((
388+
local.pat.span,
389+
local.ty.as_ref().map(|ty| ty.span),
390+
local.init.as_ref().map(|init| init.span),
391+
)),
387392
};
388-
let original = replace(&mut self.current_let_binding, val);
393+
let original = replace(&mut self.diagnostic_metadata.current_let_binding, local_spans);
389394
self.resolve_local(local);
390-
self.current_let_binding = original;
395+
self.diagnostic_metadata.current_let_binding = original;
391396
}
392397
fn visit_ty(&mut self, ty: &'tcx Ty) {
393398
match ty.kind {
@@ -429,7 +434,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
429434
}
430435
}
431436
fn visit_fn(&mut self, fn_kind: FnKind<'tcx>, declaration: &'tcx FnDecl, sp: Span, _: NodeId) {
432-
let previous_value = replace(&mut self.current_function, Some(sp));
437+
let previous_value = replace(&mut self.diagnostic_metadata.current_function, Some(sp));
433438
debug!("(resolving function) entering function");
434439
let rib_kind = match fn_kind {
435440
FnKind::ItemFn(..) => FnItemRibKind,
@@ -455,7 +460,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
455460
debug!("(resolving function) leaving function");
456461
})
457462
});
458-
self.current_function = previous_value;
463+
self.diagnostic_metadata.current_function = previous_value;
459464
}
460465

461466
fn visit_generics(&mut self, generics: &'tcx Generics) {
@@ -489,7 +494,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
489494
// (We however cannot ban `Self` for defaults on *all* generic
490495
// lists; e.g. trait generics can usefully refer to `Self`,
491496
// such as in the case of `trait Add<Rhs = Self>`.)
492-
if self.current_self_item.is_some() { // (`Some` if + only if we are in ADT's generics.)
497+
if self.diagnostic_metadata.current_self_item.is_some() {
498+
// (`Some` if + only if we are in ADT's generics.)
493499
default_ban_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), Res::Err);
494500
}
495501

@@ -541,13 +547,15 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
541547
},
542548
label_ribs: Vec::new(),
543549
current_trait_ref: None,
544-
current_trait_assoc_types: Vec::new(),
545-
current_self_type: None,
546-
current_self_item: None,
547-
current_function: None,
548-
unused_labels: Default::default(),
549-
current_type_ascription: Vec::new(),
550-
current_let_binding: None,
550+
diagnostic_metadata: DiagnosticMetadata {
551+
current_trait_assoc_types: Vec::new(),
552+
current_self_type: None,
553+
current_self_item: None,
554+
current_function: None,
555+
unused_labels: Default::default(),
556+
current_type_ascription: Vec::new(),
557+
current_let_binding: None,
558+
}
551559
}
552560
}
553561

@@ -907,16 +915,22 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
907915

908916
fn with_current_self_type<T>(&mut self, self_type: &Ty, f: impl FnOnce(&mut Self) -> T) -> T {
909917
// Handle nested impls (inside fn bodies)
910-
let previous_value = replace(&mut self.current_self_type, Some(self_type.clone()));
918+
let previous_value = replace(
919+
&mut self.diagnostic_metadata.current_self_type,
920+
Some(self_type.clone()),
921+
);
911922
let result = f(self);
912-
self.current_self_type = previous_value;
923+
self.diagnostic_metadata.current_self_type = previous_value;
913924
result
914925
}
915926

916927
fn with_current_self_item<T>(&mut self, self_item: &Item, f: impl FnOnce(&mut Self) -> T) -> T {
917-
let previous_value = replace(&mut self.current_self_item, Some(self_item.id));
928+
let previous_value = replace(
929+
&mut self.diagnostic_metadata.current_self_item,
930+
Some(self_item.id),
931+
);
918932
let result = f(self);
919-
self.current_self_item = previous_value;
933+
self.diagnostic_metadata.current_self_item = previous_value;
920934
result
921935
}
922936

@@ -927,14 +941,14 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
927941
f: impl FnOnce(&mut Self) -> T,
928942
) -> T {
929943
let trait_assoc_types = replace(
930-
&mut self.current_trait_assoc_types,
944+
&mut self.diagnostic_metadata.current_trait_assoc_types,
931945
trait_items.iter().filter_map(|item| match &item.kind {
932946
TraitItemKind::Type(bounds, _) if bounds.len() == 0 => Some(item.ident),
933947
_ => None,
934948
}).collect(),
935949
);
936950
let result = f(self);
937-
self.current_trait_assoc_types = trait_assoc_types;
951+
self.diagnostic_metadata.current_trait_assoc_types = trait_assoc_types;
938952
result
939953
}
940954

@@ -1761,7 +1775,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
17611775

17621776
fn with_resolved_label(&mut self, label: Option<Label>, id: NodeId, f: impl FnOnce(&mut Self)) {
17631777
if let Some(label) = label {
1764-
self.unused_labels.insert(id, label.ident.span);
1778+
self.diagnostic_metadata.unused_labels.insert(id, label.ident.span);
17651779
self.with_label_rib(NormalRibKind, |this| {
17661780
let ident = label.ident.modern_and_legacy();
17671781
this.label_ribs.last_mut().unwrap().bindings.insert(ident, id);
@@ -1865,7 +1879,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
18651879
Some(node_id) => {
18661880
// Since this res is a label, it is never read.
18671881
self.r.label_res_map.insert(expr.id, node_id);
1868-
self.unused_labels.remove(&node_id);
1882+
self.diagnostic_metadata.unused_labels.remove(&node_id);
18691883
}
18701884
}
18711885

@@ -1927,9 +1941,9 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
19271941
}
19281942
}
19291943
ExprKind::Type(ref type_expr, _) => {
1930-
self.current_type_ascription.push(type_expr.span);
1944+
self.diagnostic_metadata.current_type_ascription.push(type_expr.span);
19311945
visit::walk_expr(self, expr);
1932-
self.current_type_ascription.pop();
1946+
self.diagnostic_metadata.current_type_ascription.pop();
19331947
}
19341948
// `async |x| ...` gets desugared to `|x| future_from_generator(|| ...)`, so we need to
19351949
// resolve the arguments within the proper scopes so that usages of them inside the
@@ -2088,7 +2102,7 @@ impl<'a> Resolver<'a> {
20882102
pub(crate) fn late_resolve_crate(&mut self, krate: &Crate) {
20892103
let mut late_resolution_visitor = LateResolutionVisitor::new(self);
20902104
visit::walk_crate(&mut late_resolution_visitor, krate);
2091-
for (id, span) in late_resolution_visitor.unused_labels.iter() {
2105+
for (id, span) in late_resolution_visitor.diagnostic_metadata.unused_labels.iter() {
20922106
self.session.buffer_lint(lint::builtin::UNUSED_LABELS, *id, *span, "unused label");
20932107
}
20942108
}

src/librustc_resolve/late/diagnostics.rs

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,23 @@ impl<'a> LateResolutionVisitor<'a, '_> {
7272
let path_str = Segment::names_to_string(path);
7373
let item_str = path.last().unwrap().ident;
7474
let code = source.error_code(res.is_some());
75-
let (base_msg, fallback_label, base_span, is_local) = if let Some(res) = res {
75+
let (base_msg, fallback_label, base_span, could_be_expr) = if let Some(res) = res {
7676
(format!("expected {}, found {} `{}`", expected, res.descr(), path_str),
7777
format!("not a {}", expected),
7878
span,
7979
match res {
80+
Res::Def(DefKind::Fn, _) => {
81+
// Verify whether this is a fn call or an Fn used as a type.
82+
self.r.session.source_map().span_to_snippet(span).map(|snippet| {
83+
snippet.ends_with(')')
84+
}).unwrap_or(false)
85+
}
86+
Res::Def(DefKind::Ctor(..), _) |
87+
Res::Def(DefKind::Method, _) |
88+
Res::Def(DefKind::Const, _) |
89+
Res::Def(DefKind::AssocConst, _) |
90+
Res::SelfCtor(_) |
91+
Res::PrimTy(_) |
8092
Res::Local(_) => true,
8193
_ => false,
8294
})
@@ -139,7 +151,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
139151
"`self` value is a keyword only available in methods with a `self` parameter",
140152
),
141153
});
142-
if let Some(span) = &self.current_function {
154+
if let Some(span) = &self.diagnostic_metadata.current_function {
143155
err.span_label(*span, "this function doesn't have a `self` parameter");
144156
}
145157
return (err, Vec::new());
@@ -262,19 +274,17 @@ impl<'a> LateResolutionVisitor<'a, '_> {
262274
if !levenshtein_worked {
263275
err.span_label(base_span, fallback_label);
264276
self.type_ascription_suggestion(&mut err, base_span);
265-
if let Some(span) = self.current_let_binding.and_then(|(pat_sp, ty_sp)| {
266-
if ty_sp.contains(base_span) && is_local {
267-
Some(pat_sp.between(ty_sp))
268-
} else {
269-
None
277+
match self.diagnostic_metadata.current_let_binding {
278+
Some((pat_sp, Some(ty_sp), None))
279+
if ty_sp.contains(base_span) && could_be_expr => {
280+
err.span_suggestion_short(
281+
pat_sp.between(ty_sp),
282+
"use `=` if you meant to assign",
283+
" = ".to_string(),
284+
Applicability::MaybeIncorrect,
285+
);
270286
}
271-
}) {
272-
err.span_suggestion(
273-
span,
274-
"maybe you meant to assign a value instead of defining this let binding's type",
275-
" = ".to_string(),
276-
Applicability::MaybeIncorrect,
277-
);
287+
_ => {}
278288
}
279289
}
280290
(err, candidates)
@@ -510,7 +520,9 @@ impl<'a> LateResolutionVisitor<'a, '_> {
510520

511521
// Fields are generally expected in the same contexts as locals.
512522
if filter_fn(Res::Local(ast::DUMMY_NODE_ID)) {
513-
if let Some(node_id) = self.current_self_type.as_ref().and_then(extract_node_id) {
523+
if let Some(node_id) = self.diagnostic_metadata.current_self_type.as_ref()
524+
.and_then(extract_node_id)
525+
{
514526
// Look for a field with the same name in the current self_type.
515527
if let Some(resolution) = self.r.partial_res_map.get(&node_id) {
516528
match resolution.base_res() {
@@ -529,7 +541,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
529541
}
530542
}
531543

532-
for assoc_type_ident in &self.current_trait_assoc_types {
544+
for assoc_type_ident in &self.diagnostic_metadata.current_trait_assoc_types {
533545
if *assoc_type_ident == ident {
534546
return Some(AssocSuggestion::AssocItem);
535547
}
@@ -663,11 +675,9 @@ impl<'a> LateResolutionVisitor<'a, '_> {
663675
err: &mut DiagnosticBuilder<'_>,
664676
base_span: Span,
665677
) {
666-
debug!("type_ascription_suggetion {:?}", base_span);
667678
let cm = self.r.session.source_map();
668679
let base_snippet = cm.span_to_snippet(base_span);
669-
debug!("self.current_type_ascription {:?}", self.current_type_ascription);
670-
if let Some(sp) = self.current_type_ascription.last() {
680+
if let Some(sp) = self.diagnostic_metadata.current_type_ascription.last() {
671681
let mut sp = *sp;
672682
loop {
673683
// Try to find the `:`; bail on first non-':' / non-whitespace.

src/libsyntax/parse/parser/stmt.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ impl<'a> Parser<'a> {
239239
err.span_suggestion_short(
240240
colon_sp,
241241
"use `=` if you meant to assign",
242-
"=".to_string(),
242+
" =".to_string(),
243243
Applicability::MachineApplicable
244244
);
245245
err.emit();

src/test/ui/privacy/privacy-ns2.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ fn test_single2() {
3939
use foo2::Bar;
4040

4141
let _x : Box<Bar>; //~ ERROR expected type, found function `Bar`
42+
let _x : Bar(); //~ ERROR expected type, found function `Bar`
4243
}
4344

4445
fn test_list2() {

src/test/ui/privacy/privacy-ns2.stderr

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,25 @@ LL | use foo3::Bar;
4848
|
4949

5050
error[E0573]: expected type, found function `Bar`
51-
--> $DIR/privacy-ns2.rs:47:17
51+
--> $DIR/privacy-ns2.rs:42:14
52+
|
53+
LL | let _x : Bar();
54+
| ^^^^^ not a type
55+
help: use `=` if you meant to assign
56+
|
57+
LL | let _x = Bar();
58+
| ^
59+
help: possible better candidates are found in other modules, you can import them into scope
60+
|
61+
LL | use foo1::Bar;
62+
|
63+
LL | use foo2::Bar;
64+
|
65+
LL | use foo3::Bar;
66+
|
67+
68+
error[E0573]: expected type, found function `Bar`
69+
--> $DIR/privacy-ns2.rs:48:17
5270
|
5371
LL | let _x: Box<Bar>;
5472
| ^^^
@@ -67,24 +85,24 @@ LL | use foo3::Bar;
6785
|
6886

6987
error[E0603]: trait `Bar` is private
70-
--> $DIR/privacy-ns2.rs:60:15
88+
--> $DIR/privacy-ns2.rs:61:15
7189
|
7290
LL | use foo3::Bar;
7391
| ^^^
7492

7593
error[E0603]: trait `Bar` is private
76-
--> $DIR/privacy-ns2.rs:64:15
94+
--> $DIR/privacy-ns2.rs:65:15
7795
|
7896
LL | use foo3::Bar;
7997
| ^^^
8098

8199
error[E0603]: trait `Bar` is private
82-
--> $DIR/privacy-ns2.rs:71:16
100+
--> $DIR/privacy-ns2.rs:72:16
83101
|
84102
LL | use foo3::{Bar,Baz};
85103
| ^^^
86104

87-
error: aborting due to 7 previous errors
105+
error: aborting due to 8 previous errors
88106

89107
Some errors have detailed explanations: E0423, E0573, E0603.
90108
For more information about an error, try `rustc --explain E0423`.

0 commit comments

Comments
 (0)