diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 98e40d73133..e8adb1d94ba 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1716,9 +1716,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { match self.resolve_crate_relative_path(prefix.span, &prefix.segments, TypeNS) { - Some(def) => + Ok(def) => self.record_def(item.id, PathResolution::new(def, 0)), - None => { + Err(true) => self.record_def(item.id, err_path_resolution()), + Err(false) => { resolve_error(self, prefix.span, ResolutionError::FailedToResolve( @@ -1837,7 +1838,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { trait_path: &Path, path_depth: usize) -> Result { - if let Some(path_res) = self.resolve_path(id, trait_path, path_depth, TypeNS) { + self.resolve_path(id, trait_path, path_depth, TypeNS).and_then(|path_res| { if let Def::Trait(_) = path_res.base_def { debug!("(resolving trait) found trait def: {:?}", path_res); Ok(path_res) @@ -1857,9 +1858,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } err.emit(); - Err(()) + Err(true) } - } else { + }).map_err(|error_reported| { + if error_reported { return } // find possible candidates let trait_name = trait_path.segments.last().unwrap().identifier.name; @@ -1882,8 +1884,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ); resolve_error(self, trait_path.span, error); - Err(()) - } + }) } fn resolve_generics(&mut self, generics: &Generics) { @@ -1892,15 +1893,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { &hir::WherePredicate::BoundPredicate(_) | &hir::WherePredicate::RegionPredicate(_) => {} &hir::WherePredicate::EqPredicate(ref eq_pred) => { - let path_res = self.resolve_path(eq_pred.id, &eq_pred.path, 0, TypeNS); - if let Some(PathResolution { base_def: Def::TyParam(..), .. }) = path_res { - self.record_def(eq_pred.id, path_res.unwrap()); - } else { - resolve_error(self, - eq_pred.span, - ResolutionError::UndeclaredAssociatedType); + self.resolve_path(eq_pred.id, &eq_pred.path, 0, TypeNS).and_then(|path_res| { + if let PathResolution { base_def: Def::TyParam(..), .. } = path_res { + Ok(self.record_def(eq_pred.id, path_res)) + } else { + Err(false) + } + }).map_err(|error_reported| { self.record_def(eq_pred.id, err_path_resolution()); - } + if error_reported { return } + resolve_error(self, eq_pred.span, ResolutionError::UndeclaredAssociatedType); + }).unwrap_or(()); } } } @@ -2170,21 +2173,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // This is a path in the type namespace. Walk through scopes // looking for it. - match resolution { - Some(def) => { - // Write the result into the def map. - debug!("(resolving type) writing resolution for `{}` (id {}) = {:?}", - path_names_to_string(path, 0), - ty.id, - def); - self.record_def(ty.id, def); - } - None => { - self.record_def(ty.id, err_path_resolution()); - - // Keep reporting some errors even if they're ignored above. - self.resolve_path(ty.id, path, 0, TypeNS); + if let Some(def) = resolution { + // Write the result into the def map. + debug!("(resolving type) writing resolution for `{}` (id {}) = {:?}", + path_names_to_string(path, 0), ty.id, def); + self.record_def(ty.id, def); + } else { + self.record_def(ty.id, err_path_resolution()); + // Keep reporting some errors even if they're ignored above. + if let Err(true) = self.resolve_path(ty.id, path, 0, TypeNS) { + // `resolve_path` already reported the error + } else { let kind = if maybe_qself.is_some() { "associated type" } else { @@ -2483,11 +2483,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { PatKind::Struct(ref path, _, _) => { match self.resolve_path(pat_id, path, 0, TypeNS) { - Some(definition) => { + Ok(definition) => { self.record_def(pattern.id, definition); } - result => { - debug!("(resolving pattern) didn't find struct def: {:?}", result); + Err(true) => self.record_def(pattern.id, err_path_resolution()), + Err(false) => { resolve_error( self, path.span, @@ -2554,14 +2554,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } let mut resolution = self.with_no_errors(|this| { - this.resolve_path(id, path, 0, namespace) + this.resolve_path(id, path, 0, namespace).ok() }); for depth in 1..max_assoc_types { if resolution.is_some() { break; } self.with_no_errors(|this| { - resolution = this.resolve_path(id, path, depth, TypeNS); + resolution = this.resolve_path(id, path, depth, TypeNS).ok(); }); } if let Some(Def::Mod(_)) = resolution.map(|r| r.base_def) { @@ -2574,7 +2574,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { /// Skips `path_depth` trailing segments, which is also reflected in the /// returned value. See `middle::def::PathResolution` for more info. fn resolve_path(&mut self, id: NodeId, path: &Path, path_depth: usize, namespace: Namespace) - -> Option { + -> Result { let span = path.span; let segments = &path.segments[..path.segments.len() - path_depth]; @@ -2613,14 +2613,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // // Such behavior is required for backward compatibility. // The same fallback is used when `a` resolves to nothing. - let unqualified_def = resolve_identifier_with_fallback(self, true); - return unqualified_def.and_then(|def| self.adjust_local_def(def, span)).map(mk_res); + let def = resolve_identifier_with_fallback(self, true).ok_or(false); + return def.and_then(|def| self.adjust_local_def(def, span).ok_or(true)).map(mk_res); } let unqualified_def = resolve_identifier_with_fallback(self, false); let def = self.resolve_module_relative_path(span, segments, namespace); match (def, unqualified_def) { - (Some(d), Some(ref ud)) if d == ud.def => { + (Ok(d), Some(ref ud)) if d == ud.def => { self.session .add_lint(lint::builtin::UNUSED_QUALIFICATIONS, id, @@ -2741,7 +2741,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { span: Span, segments: &[hir::PathSegment], namespace: Namespace) - -> Option { + -> Result { let module_path = segments.split_last() .unwrap() .1 @@ -2762,9 +2762,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { }; resolve_error(self, span, ResolutionError::FailedToResolve(&msg)); - return None; + return Err(true); } - Indeterminate => return None, + Indeterminate => return Err(false), Success(resulting_module) => { containing_module = resulting_module; } @@ -2775,7 +2775,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { result.success().map(|binding| { self.check_privacy(containing_module, name, binding, span); binding.def().unwrap() - }) + }).ok_or(false) } /// Invariant: This must be called only during main resolution, not during @@ -2784,7 +2784,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { span: Span, segments: &[hir::PathSegment], namespace: Namespace) - -> Option { + -> Result { let module_path = segments.split_last() .unwrap() .1 @@ -2810,10 +2810,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { }; resolve_error(self, span, ResolutionError::FailedToResolve(&msg)); - return None; + return Err(true); } - Indeterminate => return None, + Indeterminate => return Err(false), Success(resulting_module) => { containing_module = resulting_module; @@ -2825,7 +2825,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { result.success().map(|binding| { self.check_privacy(containing_module, name, binding, span); binding.def().unwrap() - }) + }).ok_or(false) } fn with_no_errors(&mut self, f: F) -> T @@ -3040,25 +3040,25 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { }); self.record_def(expr.id, err_path_resolution()); - match type_res.map(|r| r.base_def) { - Some(Def::Struct(..)) => { - let mut err = resolve_struct_error(self, - expr.span, - ResolutionError::StructVariantUsedAsFunction(&path_name)); - let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?", - path_name); - if self.emit_errors { - err.fileline_help(expr.span, &msg); - } else { - err.span_help(expr.span, &msg); - } - err.emit(); + if let Ok(Def::Struct(..)) = type_res.map(|r| r.base_def) { + let error_variant = ResolutionError::StructVariantUsedAsFunction(&path_name); + let mut err = resolve_struct_error(self, expr.span, error_variant); + + let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?", + path_name); + + if self.emit_errors { + err.fileline_help(expr.span, &msg); + } else { + err.span_help(expr.span, &msg); } - _ => { - // Keep reporting some errors even if they're ignored above. - self.resolve_path(expr.id, path, 0, ValueNS); - + err.emit(); + } else { + // Keep reporting some errors even if they're ignored above. + if let Err(true) = self.resolve_path(expr.id, path, 0, ValueNS) { + // `resolve_path` already reported the error + } else { let mut method_scope = false; self.value_ribs.iter().rev().all(|rib| { method_scope = match rib.kind { @@ -3132,8 +3132,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // check to ensure that the path is actually a structure; that // is checked later during typeck. match self.resolve_path(expr.id, path, 0, TypeNS) { - Some(definition) => self.record_def(expr.id, definition), - None => { + Ok(definition) => self.record_def(expr.id, definition), + Err(true) => self.record_def(expr.id, err_path_resolution()), + Err(false) => { debug!("(resolving expression) didn't find struct def",); resolve_error(self,