Skip to content

Commit b0f81a3

Browse files
committed
Rollup merge of #32789 - jseyfried:fix_duplicate_resolve_errors, r=eddyb
resolve: Avoid emitting redundant path resolution errors This PR avoids emitting redundant path resolution errors in `resolve` (fixes #32760). r? @eddyb
2 parents 2a88ca4 + 07dac97 commit b0f81a3

23 files changed

+76
-97
lines changed

src/librustc_resolve/lib.rs

+69-66
Original file line numberDiff line numberDiff line change
@@ -1714,9 +1714,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
17141714
match self.resolve_crate_relative_path(prefix.span,
17151715
&prefix.segments,
17161716
TypeNS) {
1717-
Some(def) =>
1717+
Ok(def) =>
17181718
self.record_def(item.id, PathResolution::new(def, 0)),
1719-
None => {
1719+
Err(true) => self.record_def(item.id, err_path_resolution()),
1720+
Err(false) => {
17201721
resolve_error(self,
17211722
prefix.span,
17221723
ResolutionError::FailedToResolve(
@@ -1835,7 +1836,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
18351836
trait_path: &Path,
18361837
path_depth: usize)
18371838
-> Result<PathResolution, ()> {
1838-
if let Some(path_res) = self.resolve_path(id, trait_path, path_depth, TypeNS) {
1839+
self.resolve_path(id, trait_path, path_depth, TypeNS).and_then(|path_res| {
18391840
if let Def::Trait(_) = path_res.base_def {
18401841
debug!("(resolving trait) found trait def: {:?}", path_res);
18411842
Ok(path_res)
@@ -1855,9 +1856,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
18551856
}
18561857
}
18571858
err.emit();
1858-
Err(())
1859+
Err(true)
18591860
}
1860-
} else {
1861+
}).map_err(|error_reported| {
1862+
if error_reported { return }
18611863

18621864
// find possible candidates
18631865
let trait_name = trait_path.segments.last().unwrap().identifier.name;
@@ -1880,8 +1882,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
18801882
);
18811883

18821884
resolve_error(self, trait_path.span, error);
1883-
Err(())
1884-
}
1885+
})
18851886
}
18861887

18871888
fn resolve_generics(&mut self, generics: &Generics) {
@@ -1890,15 +1891,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
18901891
&hir::WherePredicate::BoundPredicate(_) |
18911892
&hir::WherePredicate::RegionPredicate(_) => {}
18921893
&hir::WherePredicate::EqPredicate(ref eq_pred) => {
1893-
let path_res = self.resolve_path(eq_pred.id, &eq_pred.path, 0, TypeNS);
1894-
if let Some(PathResolution { base_def: Def::TyParam(..), .. }) = path_res {
1895-
self.record_def(eq_pred.id, path_res.unwrap());
1896-
} else {
1897-
resolve_error(self,
1898-
eq_pred.span,
1899-
ResolutionError::UndeclaredAssociatedType);
1894+
self.resolve_path(eq_pred.id, &eq_pred.path, 0, TypeNS).and_then(|path_res| {
1895+
if let PathResolution { base_def: Def::TyParam(..), .. } = path_res {
1896+
Ok(self.record_def(eq_pred.id, path_res))
1897+
} else {
1898+
Err(false)
1899+
}
1900+
}).map_err(|error_reported| {
19001901
self.record_def(eq_pred.id, err_path_resolution());
1901-
}
1902+
if error_reported { return }
1903+
let error_variant = ResolutionError::UndeclaredAssociatedType;
1904+
resolve_error(self, eq_pred.span, error_variant);
1905+
}).unwrap_or(());
19021906
}
19031907
}
19041908
}
@@ -2168,21 +2172,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
21682172

21692173
// This is a path in the type namespace. Walk through scopes
21702174
// looking for it.
2171-
match resolution {
2172-
Some(def) => {
2173-
// Write the result into the def map.
2174-
debug!("(resolving type) writing resolution for `{}` (id {}) = {:?}",
2175-
path_names_to_string(path, 0),
2176-
ty.id,
2177-
def);
2178-
self.record_def(ty.id, def);
2179-
}
2180-
None => {
2181-
self.record_def(ty.id, err_path_resolution());
2182-
2183-
// Keep reporting some errors even if they're ignored above.
2184-
self.resolve_path(ty.id, path, 0, TypeNS);
2175+
if let Some(def) = resolution {
2176+
// Write the result into the def map.
2177+
debug!("(resolving type) writing resolution for `{}` (id {}) = {:?}",
2178+
path_names_to_string(path, 0), ty.id, def);
2179+
self.record_def(ty.id, def);
2180+
} else {
2181+
self.record_def(ty.id, err_path_resolution());
21852182

2183+
// Keep reporting some errors even if they're ignored above.
2184+
if let Err(true) = self.resolve_path(ty.id, path, 0, TypeNS) {
2185+
// `resolve_path` already reported the error
2186+
} else {
21862187
let kind = if maybe_qself.is_some() {
21872188
"associated type"
21882189
} else {
@@ -2481,11 +2482,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
24812482

24822483
PatKind::Struct(ref path, _, _) => {
24832484
match self.resolve_path(pat_id, path, 0, TypeNS) {
2484-
Some(definition) => {
2485+
Ok(definition) => {
24852486
self.record_def(pattern.id, definition);
24862487
}
2487-
result => {
2488-
debug!("(resolving pattern) didn't find struct def: {:?}", result);
2488+
Err(true) => self.record_def(pattern.id, err_path_resolution()),
2489+
Err(false) => {
24892490
resolve_error(
24902491
self,
24912492
path.span,
@@ -2552,14 +2553,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
25522553
}
25532554

25542555
let mut resolution = self.with_no_errors(|this| {
2555-
this.resolve_path(id, path, 0, namespace)
2556+
this.resolve_path(id, path, 0, namespace).ok()
25562557
});
25572558
for depth in 1..max_assoc_types {
25582559
if resolution.is_some() {
25592560
break;
25602561
}
25612562
self.with_no_errors(|this| {
2562-
resolution = this.resolve_path(id, path, depth, TypeNS);
2563+
resolution = this.resolve_path(id, path, depth, TypeNS).ok();
25632564
});
25642565
}
25652566
if let Some(Def::Mod(_)) = resolution.map(|r| r.base_def) {
@@ -2572,7 +2573,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
25722573
/// Skips `path_depth` trailing segments, which is also reflected in the
25732574
/// returned value. See `hir::def::PathResolution` for more info.
25742575
fn resolve_path(&mut self, id: NodeId, path: &Path, path_depth: usize, namespace: Namespace)
2575-
-> Option<PathResolution> {
2576+
-> Result<PathResolution, bool /* true if an error was reported */ > {
25762577
let span = path.span;
25772578
let segments = &path.segments[..path.segments.len() - path_depth];
25782579

@@ -2611,14 +2612,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
26112612
//
26122613
// Such behavior is required for backward compatibility.
26132614
// The same fallback is used when `a` resolves to nothing.
2614-
let unqualified_def = resolve_identifier_with_fallback(self, true);
2615-
return unqualified_def.and_then(|def| self.adjust_local_def(def, span)).map(mk_res);
2615+
let def = resolve_identifier_with_fallback(self, true).ok_or(false);
2616+
return def.and_then(|def| self.adjust_local_def(def, span).ok_or(true)).map(mk_res);
26162617
}
26172618

26182619
let unqualified_def = resolve_identifier_with_fallback(self, false);
26192620
let def = self.resolve_module_relative_path(span, segments, namespace);
26202621
match (def, unqualified_def) {
2621-
(Some(d), Some(ref ud)) if d == ud.def => {
2622+
(Ok(d), Some(ref ud)) if d == ud.def => {
26222623
self.session
26232624
.add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
26242625
id,
@@ -2739,7 +2740,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
27392740
span: Span,
27402741
segments: &[hir::PathSegment],
27412742
namespace: Namespace)
2742-
-> Option<Def> {
2743+
-> Result<Def, bool /* true if an error was reported */> {
27432744
let module_path = segments.split_last()
27442745
.unwrap()
27452746
.1
@@ -2760,9 +2761,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
27602761
};
27612762

27622763
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
2763-
return None;
2764+
return Err(true);
27642765
}
2765-
Indeterminate => return None,
2766+
Indeterminate => return Err(false),
27662767
Success(resulting_module) => {
27672768
containing_module = resulting_module;
27682769
}
@@ -2773,7 +2774,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
27732774
result.success().map(|binding| {
27742775
self.check_privacy(containing_module, name, binding, span);
27752776
binding.def().unwrap()
2776-
})
2777+
}).ok_or(false)
27772778
}
27782779

27792780
/// Invariant: This must be called only during main resolution, not during
@@ -2782,7 +2783,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
27822783
span: Span,
27832784
segments: &[hir::PathSegment],
27842785
namespace: Namespace)
2785-
-> Option<Def> {
2786+
-> Result<Def, bool /* true if an error was reported */> {
27862787
let module_path = segments.split_last()
27872788
.unwrap()
27882789
.1
@@ -2808,10 +2809,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
28082809
};
28092810

28102811
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
2811-
return None;
2812+
return Err(true);
28122813
}
28132814

2814-
Indeterminate => return None,
2815+
Indeterminate => return Err(false),
28152816

28162817
Success(resulting_module) => {
28172818
containing_module = resulting_module;
@@ -2823,7 +2824,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
28232824
result.success().map(|binding| {
28242825
self.check_privacy(containing_module, name, binding, span);
28252826
binding.def().unwrap()
2826-
})
2827+
}).ok_or(false)
28272828
}
28282829

28292830
fn with_no_errors<T, F>(&mut self, f: F) -> T
@@ -3038,25 +3039,26 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
30383039
});
30393040

30403041
self.record_def(expr.id, err_path_resolution());
3041-
match type_res.map(|r| r.base_def) {
3042-
Some(Def::Struct(..)) => {
3043-
let mut err = resolve_struct_error(self,
3044-
expr.span,
3045-
ResolutionError::StructVariantUsedAsFunction(&path_name));
3046-
3047-
let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?",
3048-
path_name);
3049-
if self.emit_errors {
3050-
err.fileline_help(expr.span, &msg);
3051-
} else {
3052-
err.span_help(expr.span, &msg);
3053-
}
3054-
err.emit();
3055-
}
3056-
_ => {
3057-
// Keep reporting some errors even if they're ignored above.
3058-
self.resolve_path(expr.id, path, 0, ValueNS);
30593042

3043+
if let Ok(Def::Struct(..)) = type_res.map(|r| r.base_def) {
3044+
let error_variant =
3045+
ResolutionError::StructVariantUsedAsFunction(&path_name);
3046+
let mut err = resolve_struct_error(self, expr.span, error_variant);
3047+
3048+
let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?",
3049+
path_name);
3050+
3051+
if self.emit_errors {
3052+
err.fileline_help(expr.span, &msg);
3053+
} else {
3054+
err.span_help(expr.span, &msg);
3055+
}
3056+
err.emit();
3057+
} else {
3058+
// Keep reporting some errors even if they're ignored above.
3059+
if let Err(true) = self.resolve_path(expr.id, path, 0, ValueNS) {
3060+
// `resolve_path` already reported the error
3061+
} else {
30603062
let mut method_scope = false;
30613063
self.value_ribs.iter().rev().all(|rib| {
30623064
method_scope = match rib.kind {
@@ -3130,8 +3132,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
31303132
// check to ensure that the path is actually a structure; that
31313133
// is checked later during typeck.
31323134
match self.resolve_path(expr.id, path, 0, TypeNS) {
3133-
Some(definition) => self.record_def(expr.id, definition),
3134-
None => {
3135+
Ok(definition) => self.record_def(expr.id, definition),
3136+
Err(true) => self.record_def(expr.id, err_path_resolution()),
3137+
Err(false) => {
31353138
debug!("(resolving expression) didn't find struct def",);
31363139

31373140
resolve_error(self,

src/test/compile-fail-fulldeps/macro-crate-doesnt-resolve.rs

-1
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,4 @@ extern crate macro_crate_test;
1616
fn main() {
1717
macro_crate_test::foo();
1818
//~^ ERROR failed to resolve. Use of undeclared type or module `macro_crate_test`
19-
//~^^ ERROR unresolved name `macro_crate_test::foo`
2019
}

src/test/compile-fail/bad-module.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// error-pattern: unresolved name
11+
// error-pattern: failed to resolve. Use of undeclared type or module `thing`
1212

1313
fn main() { let foo = thing::len(Vec::new()); }

src/test/compile-fail/bad-type-env-capture.rs

-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,5 @@
1010

1111
fn foo<T>() {
1212
fn bar(b: T) { } //~ ERROR can't use type parameters from outer
13-
//~^ ERROR type name `T` is undefined or not in scope
1413
}
1514
fn main() { }

src/test/compile-fail/export-fully-qualified.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// error-pattern: unresolved name
11+
// error-pattern: failed to resolve. Use of undeclared type or module `foo`
1212

1313
// In this test baz isn't resolved when called as foo.baz even though
1414
// it's called from inside foo. This is somewhat surprising and may

src/test/compile-fail/export2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// error-pattern: unresolved name
11+
// error-pattern: failed to resolve. Use of undeclared type or module `bar`
1212

1313
mod foo {
1414
pub fn x() { bar::x(); }

src/test/compile-fail/inner-static-type-parameter.rs

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ enum Bar<T> { What } //~ ERROR parameter `T` is never used
1515
fn foo<T>() {
1616
static a: Bar<T> = Bar::What;
1717
//~^ ERROR cannot use an outer type parameter in this context
18-
//~| ERROR type name `T` is undefined or not in scope
1918
}
2019

2120
fn main() {

src/test/compile-fail/issue-12796.rs

-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ trait Trait {
1212
fn outer(&self) {
1313
fn inner(_: &Self) {
1414
//~^ ERROR can't use type parameters from outer function
15-
//~^^ ERROR use of `Self` outside of an impl or trait
1615
}
1716
}
1817
}

src/test/compile-fail/issue-3021-b.rs

-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ fn siphash(k0 : u64) {
1717
impl siphash {
1818
pub fn reset(&mut self) {
1919
self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR can't capture dynamic environment
20-
//~^ ERROR unresolved name `k0`
2120
}
2221
}
2322
}

src/test/compile-fail/issue-3021-c.rs

-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ fn siphash<T>() {
1313
trait t {
1414
fn g(&self, x: T) -> T; //~ ERROR can't use type parameters from outer function; try using
1515
//~^ ERROR can't use type parameters from outer function; try using
16-
//~^^ ERROR type name `T` is undefined or not in scope
17-
//~^^^ ERROR type name `T` is undefined or not in scope
1816
}
1917
}
2018

src/test/compile-fail/issue-3021-d.rs

-2
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,7 @@ fn siphash(k0 : u64, k1 : u64) {
2929
impl siphash for SipState {
3030
fn reset(&self) {
3131
self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR can't capture dynamic environment
32-
//~^ ERROR unresolved name `k0`
3332
self.v1 = k1 ^ 0x646f72616e646f6d; //~ ERROR can't capture dynamic environment
34-
//~^ ERROR unresolved name `k1`
3533
}
3634
fn result(&self) -> u64 { return mk_result(self); }
3735
}

src/test/compile-fail/issue-3021.rs

-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ fn siphash(k0 : u64) {
2020
impl SipHash for SipState {
2121
fn reset(&self) {
2222
self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR can't capture dynamic environment
23-
//~^ ERROR unresolved name `k0`
2423
}
2524
}
2625
panic!();

src/test/compile-fail/issue-3214.rs

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
fn foo<T>() {
1212
struct foo {
1313
x: T, //~ ERROR can't use type parameters from outer function;
14-
//~^ ERROR type name `T` is undefined or not in scope
1514
}
1615

1716
impl<T> Drop for foo<T> {

src/test/compile-fail/issue-3521-2.rs

-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ fn main() {
1313

1414
static y: isize = foo + 1;
1515
//~^ ERROR attempt to use a non-constant value in a constant
16-
//~| ERROR unresolved name `foo`
1716

1817
println!("{}", y);
1918
}

src/test/compile-fail/issue-3521.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ fn main() {
1515
enum Stuff {
1616
Bar = foo
1717
//~^ ERROR attempt to use a non-constant value in a constant
18-
//~| ERROR unresolved name `foo`
19-
//~^^^ ERROR constant evaluation error: non-constant path in constant expression
18+
//~^^ ERROR constant evaluation error: non-constant path in constant expression
2019
}
2120

2221
println!("{}", Stuff::Bar);

0 commit comments

Comments
 (0)