about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-11-22 11:32:52 +0000
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-11-28 23:30:03 +0000
commitcb9f14e987732fa1406911633d9bf4e7eee45978 (patch)
tree9ac6781d648c3b79fb0d8df3173acc277b59b0a5
parent39c267a8d5ab141faaf5d4b33a20cac62cdc4507 (diff)
downloadrust-cb9f14e987732fa1406911633d9bf4e7eee45978.tar.gz
rust-cb9f14e987732fa1406911633d9bf4e7eee45978.zip
Use `Def::Err` to signal that an error has already been reported where possible.
-rw-r--r--src/librustc_resolve/lib.rs111
1 files changed, 48 insertions, 63 deletions
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 058c8266a35..7b73582449b 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -584,13 +584,9 @@ impl<'a> Visitor for Resolver<'a> {
         self.resolve_type(ty);
     }
     fn visit_poly_trait_ref(&mut self, tref: &ast::PolyTraitRef, m: &ast::TraitBoundModifier) {
-        match self.resolve_trait_reference(tref.trait_ref.ref_id, &tref.trait_ref.path, 0, None) {
-            Ok(def) => self.record_def(tref.trait_ref.ref_id, def),
-            Err(_) => {
-                // error already reported
-                self.record_def(tref.trait_ref.ref_id, err_path_resolution())
-            }
-        }
+        let def =
+            self.resolve_trait_reference(tref.trait_ref.ref_id, &tref.trait_ref.path, 0, None);
+        self.record_def(tref.trait_ref.ref_id, def);
         visit::walk_poly_trait_ref(self, tref, m);
     }
     fn visit_variant(&mut self,
@@ -1205,8 +1201,7 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
         let namespace = if is_value { ValueNS } else { TypeNS };
         match self.resolve_crate_relative_path(path.span, &path.segments, namespace) {
             Ok(binding) => path.def = binding.def(),
-            Err(true) => {}
-            Err(false) => {
+            None => {
                 let path_name = &format!("{}", path);
                 let error =
                     ResolutionError::UnresolvedName {
@@ -1844,12 +1839,11 @@ impl<'a> Resolver<'a> {
                             match self.resolve_crate_relative_path(prefix.span,
                                                                    &prefix.segments,
                                                                    TypeNS) {
-                                Ok(binding) => {
+                                Some(binding) => {
                                     let def = binding.def();
                                     self.record_def(item.id, PathResolution::new(def));
                                 }
-                                Err(true) => self.record_def(item.id, err_path_resolution()),
-                                Err(false) => {
+                                None => {
                                     resolve_error(self,
                                                   prefix.span,
                                                   ResolutionError::FailedToResolve(
@@ -1935,14 +1929,14 @@ impl<'a> Resolver<'a> {
                                trait_path: &Path,
                                path_depth: usize,
                                generics: Option<&Generics>)
-                               -> Result<PathResolution, ()> {
-        self.resolve_path(id, trait_path, path_depth, TypeNS).and_then(|path_res| {
+                               -> PathResolution {
+        if let Some(path_res) = self.resolve_path(id, trait_path, path_depth, TypeNS) {
             match path_res.base_def {
                 Def::Trait(_) => {
                     debug!("(resolving trait) found trait def: {:?}", path_res);
-                    return Ok(path_res);
+                    return path_res;
                 }
-                Def::Err => return Err(true),
+                Def::Err => return err_path_resolution(),
                 _ => {}
             }
 
@@ -1963,10 +1957,7 @@ impl<'a> Resolver<'a> {
                 err.note(&format!("type aliases cannot be used for traits"));
             }
             err.emit();
-            Err(true)
-        }).map_err(|error_reported| {
-            if error_reported { return }
-
+        } else {
             // find possible candidates
             let trait_name = trait_path.segments.last().unwrap().identifier.name;
             let candidates =
@@ -1988,7 +1979,8 @@ impl<'a> Resolver<'a> {
                 );
 
             resolve_error(self, trait_path.span, error);
-        })
+        }
+        err_path_resolution()
     }
 
     fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T
@@ -2011,16 +2003,13 @@ impl<'a> Resolver<'a> {
         let mut new_val = None;
         let mut new_id = None;
         if let Some(trait_ref) = opt_trait_ref {
-            if let Ok(path_res) = self.resolve_trait_reference(trait_ref.ref_id,
-                                                               &trait_ref.path,
-                                                               0,
-                                                               generics) {
-                assert!(path_res.depth == 0);
-                self.record_def(trait_ref.ref_id, path_res);
+            let path_res =
+                self.resolve_trait_reference(trait_ref.ref_id, &trait_ref.path, 0, generics);
+            assert!(path_res.depth == 0);
+            self.record_def(trait_ref.ref_id, path_res);
+            if path_res.base_def != Def::Err {
                 new_val = Some((path_res.base_def.def_id(), trait_ref.clone()));
                 new_id = Some(path_res.base_def.def_id());
-            } else {
-                self.record_def(trait_ref.ref_id, err_path_resolution());
             }
             visit::walk_trait_ref(self, trait_ref);
         }
@@ -2276,9 +2265,8 @@ impl<'a> Resolver<'a> {
                     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 result = self.resolve_path(ty.id, path, 0, TypeNS);
+                    if result.map(|resolution| resolution.base_def) != Some(Def::Err) {
                         let kind = if maybe_qself.is_some() {
                             "associated type"
                         } else {
@@ -2420,7 +2408,7 @@ impl<'a> Resolver<'a> {
                 resolution
             }
         } else {
-            if let Err(false) = self.resolve_path(pat_id, path, 0, namespace) {
+            if self.resolve_path(pat_id, path, 0, namespace).is_none() {
                 resolve_error(
                     self,
                     path.span,
@@ -2553,7 +2541,7 @@ impl<'a> Resolver<'a> {
                 }
                 max_assoc_types = path.segments.len() - qself.position;
                 // Make sure the trait is valid.
-                let _ = self.resolve_trait_reference(id, path, max_assoc_types, None);
+                self.resolve_trait_reference(id, path, max_assoc_types, None);
             }
             None => {
                 max_assoc_types = path.segments.len();
@@ -2561,18 +2549,20 @@ impl<'a> Resolver<'a> {
         }
 
         let mut resolution = self.with_no_errors(|this| {
-            this.resolve_path(id, path, 0, namespace).ok()
+            this.resolve_path(id, path, 0, namespace)
         });
+        if resolution.map(|res| res.base_def) == Some(Def::Err) { resolution = None; }
         for depth in 1..max_assoc_types {
             if resolution.is_some() {
                 break;
             }
             self.with_no_errors(|this| {
-                let partial_resolution = this.resolve_path(id, path, depth, TypeNS).ok();
+                let partial_resolution = this.resolve_path(id, path, depth, TypeNS);
                 if let Some(Def::Mod(..)) = partial_resolution.map(|r| r.base_def) {
                     // Modules cannot have associated items
                 } else {
                     resolution = partial_resolution;
+                    if resolution.map(|res| res.base_def) == Some(Def::Err) { resolution = None; }
                 }
             });
         }
@@ -2582,7 +2572,7 @@ impl<'a> Resolver<'a> {
     /// Skips `path_depth` trailing segments, which is also reflected in the
     /// returned value. See `hir::def::PathResolution` for more info.
     fn resolve_path(&mut self, id: NodeId, path: &Path, path_depth: usize, namespace: Namespace)
-                    -> Result<PathResolution, bool /* true if an error was reported */ > {
+                    -> Option<PathResolution> {
         debug!("resolve_path(id={:?} path={:?}, path_depth={:?})", id, path, path_depth);
 
         let span = path.span;
@@ -2623,15 +2613,15 @@ impl<'a> Resolver<'a> {
             //
             // Such behavior is required for backward compatibility.
             // The same fallback is used when `a` resolves to nothing.
-            let def = resolve_identifier_with_fallback(self, Some(span)).ok_or(false);
-            return def.and_then(|def| self.adjust_local_def(def, span).ok_or(true)).map(mk_res);
+            let def = resolve_identifier_with_fallback(self, Some(span));
+            return def.map(|def| mk_res(self.adjust_local_def(def, span)));
         }
 
         let unqualified_def = resolve_identifier_with_fallback(self, None);
         let qualified_binding = self.resolve_module_relative_path(span, segments, namespace);
         match (qualified_binding, unqualified_def) {
-            (Ok(binding), Some(ref ud)) if binding.def() == ud.def &&
-                                           segments[0].identifier.name != "$crate" => {
+            (Some(binding), Some(ref ud)) if binding.def() == ud.def &&
+                                             segments[0].identifier.name != "$crate" => {
                 self.session
                     .add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
                               id,
@@ -2659,7 +2649,7 @@ impl<'a> Resolver<'a> {
     }
 
     // Resolve a local definition, potentially adjusting for closures.
-    fn adjust_local_def(&mut self, local_def: LocalDef, span: Span) -> Option<Def> {
+    fn adjust_local_def(&mut self, local_def: LocalDef, span: Span) -> Def {
         let ribs = match local_def.ribs {
             Some((ns, i)) => &self.ribs[ns][i + 1..],
             None => &[] as &[_],
@@ -2705,14 +2695,14 @@ impl<'a> Resolver<'a> {
                             resolve_error(self,
                                           span,
                                           ResolutionError::CannotCaptureDynamicEnvironmentInFnItem);
-                            return None;
+                            return Def::Err;
                         }
                         ConstantItemRibKind => {
                             // Still doesn't deal with upvars
                             resolve_error(self,
                                           span,
                                           ResolutionError::AttemptToUseNonConstantValueInConstant);
-                            return None;
+                            return Def::Err;
                         }
                     }
                 }
@@ -2731,19 +2721,19 @@ impl<'a> Resolver<'a> {
                             resolve_error(self,
                                           span,
                                           ResolutionError::TypeParametersFromOuterFunction);
-                            return None;
+                            return Def::Err;
                         }
                         ConstantItemRibKind => {
                             // see #9186
                             resolve_error(self, span, ResolutionError::OuterTypeParameterContext);
-                            return None;
+                            return Def::Err;
                         }
                     }
                 }
             }
             _ => {}
         }
-        return Some(def);
+        return def;
     }
 
     // resolve a "module-relative" path, e.g. a::b::c
@@ -2751,8 +2741,7 @@ impl<'a> Resolver<'a> {
                                     span: Span,
                                     segments: &[ast::PathSegment],
                                     namespace: Namespace)
-                                    -> Result<&'a NameBinding<'a>,
-                                              bool /* true if an error was reported */> {
+                                    -> Option<&'a NameBinding<'a>> {
         let module_path =
             segments.split_last().unwrap().1.iter().map(|ps| ps.identifier).collect::<Vec<_>>();
 
@@ -2761,22 +2750,20 @@ impl<'a> Resolver<'a> {
                 if let Some((span, msg)) = err {
                     resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
                 }
-                return Err(true);
+                return Some(self.dummy_binding);
             }
-            Indeterminate => return Err(false),
+            Indeterminate => return None,
             Success(module) => module,
         };
 
         let name = segments.last().unwrap().identifier.name;
-        let result = self.resolve_name_in_module(module, name, namespace, false, Some(span));
-        result.success().ok_or(false)
+        self.resolve_name_in_module(module, name, namespace, false, Some(span)).success()
     }
 
     /// Invariant: This must be called only during main resolution, not during
     /// import resolution.
     fn resolve_crate_relative_path<T>(&mut self, span: Span, segments: &[T], namespace: Namespace)
-                                      -> Result<&'a NameBinding<'a>,
-                                                bool /* true if an error was reported */>
+                                      -> Option<&'a NameBinding<'a>>
         where T: Named,
     {
         let module_path = segments.split_last().unwrap().1.iter().map(T::ident).collect::<Vec<_>>();
@@ -2787,17 +2774,16 @@ impl<'a> Resolver<'a> {
                 if let Some((span, msg)) = err {
                     resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
                 }
-                return Err(true);
+                return Some(self.dummy_binding);
             }
 
-            Indeterminate => return Err(false),
+            Indeterminate => return None,
 
             Success(module) => module,
         };
 
         let name = segments.last().unwrap().ident().name;
-        let result = self.resolve_name_in_module(module, name, namespace, false, Some(span));
-        result.success().ok_or(false)
+        self.resolve_name_in_module(module, name, namespace, false, Some(span)).success()
     }
 
     fn with_no_errors<T, F>(&mut self, f: F) -> T
@@ -2963,7 +2949,7 @@ impl<'a> Resolver<'a> {
 
                     self.record_def(expr.id, err_path_resolution());
 
-                    if let Ok(Def::Struct(..)) = type_res.map(|r| r.base_def) {
+                    if let Some(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);
@@ -2979,9 +2965,8 @@ impl<'a> Resolver<'a> {
                         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 result = self.resolve_path(expr.id, path, 0, ValueNS);
+                        if result.map(|resolution| resolution.base_def) != Some(Def::Err) {
                             let mut method_scope = false;
                             let mut is_static = false;
                             self.ribs[ValueNS].iter().rev().all(|rib| {