diff options
| -rw-r--r-- | src/librustc/hir/lowering.rs | 13 | ||||
| -rw-r--r-- | src/librustc_resolve/lib.rs | 70 |
2 files changed, 61 insertions, 22 deletions
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index f2154f885fa..a87f2747a57 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -155,18 +155,7 @@ pub trait Resolver { /// Given suffix ["b","c","d"], creates a HIR path for `[::crate_root]::b::c::d` and resolves /// it based on `is_value`. fn resolve_str_path(&mut self, span: Span, crate_root: Option<&str>, - components: &[&str], is_value: bool) -> hir::Path { - let mut path = hir::Path { - span, - def: Def::Err, - segments: iter::once(keywords::CrateRoot.name()).chain({ - crate_root.into_iter().chain(components.iter().cloned()).map(Symbol::intern) - }).map(hir::PathSegment::from_name).collect(), - }; - - self.resolve_hir_path(&mut path, is_value); - path - } + components: &[&str], is_value: bool) -> hir::Path; } #[derive(Clone, Copy, Debug)] diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index d9ae776a4d7..fdbed251799 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1407,6 +1407,64 @@ impl<'a, 'b: 'a> ty::DefIdTree for &'a Resolver<'b> { impl<'a> hir::lowering::Resolver for Resolver<'a> { fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool) { + self.resolve_hir_path_cb(path, is_value, + |resolver, span, error| resolve_error(resolver, span, error)) + } + + fn resolve_str_path(&mut self, span: Span, crate_root: Option<&str>, + components: &[&str], is_value: bool) -> hir::Path { + self.resolve_str_path_cb(span, crate_root, components, is_value, + |resolver, span, error| resolve_error(resolver, span, error)) + } + + fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution> { + self.def_map.get(&id).cloned() + } + + fn definitions(&mut self) -> &mut Definitions { + &mut self.definitions + } +} + +impl<'a> Resolver<'a> { + /// resolve_str_path, but takes a callback in case there was an error + fn resolve_str_path_cb<F>(&mut self, span: Span, crate_root: Option<&str>, + components: &[&str], is_value: bool, error_callback: F) -> hir::Path + where F: for<'b, 'c> FnOnce(&'c mut Resolver, Span, ResolutionError<'b>) + { + use std::iter; + let mut path = hir::Path { + span, + def: Def::Err, + segments: iter::once(keywords::CrateRoot.name()).chain({ + crate_root.into_iter().chain(components.iter().cloned()).map(Symbol::intern) + }).map(hir::PathSegment::from_name).collect(), + }; + + self.resolve_hir_path_cb(&mut path, is_value, error_callback); + path + } + + /// Rustdoc uses this to resolve things in a recoverable way. ResolutionError<'a> + /// isn't something that can be returned because it can't be made to live that long, + /// and also it's a private type. Fortunately rustdoc doesn't need to know the error, + /// just that an error occured. + pub fn resolve_str_path_error(&mut self, span: Span, crate_root: Option<&str>, + components: &[&str], is_value: bool) -> Result<hir::Path, ()> { + let mut errored = false; + let path = self.resolve_str_path_cb(span, crate_root, components, is_value, + |_, _, _| errored = true); + if errored || path.def == Def::Err { + Err(()) + } else { + Ok(path) + } + } + + /// resolve_hir_path, but takes a callback in case there was an error + fn resolve_hir_path_cb<F>(&mut self, path: &mut hir::Path, is_value: bool, error_callback: F) + where F: for<'c, 'b> FnOnce(&'c mut Resolver, Span, ResolutionError<'b>) + { let namespace = if is_value { ValueNS } else { TypeNS }; let hir::Path { ref segments, span, ref mut def } = *path; let path: Vec<SpannedIdent> = segments.iter() @@ -1418,24 +1476,16 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> { *def = path_res.base_def(), PathResult::NonModule(..) => match self.resolve_path(&path, None, true, span) { PathResult::Failed(span, msg, _) => { - resolve_error(self, span, ResolutionError::FailedToResolve(&msg)); + error_callback(self, span, ResolutionError::FailedToResolve(&msg)); } _ => {} }, PathResult::Indeterminate => unreachable!(), PathResult::Failed(span, msg, _) => { - resolve_error(self, span, ResolutionError::FailedToResolve(&msg)); + error_callback(self, span, ResolutionError::FailedToResolve(&msg)); } } } - - fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution> { - self.def_map.get(&id).cloned() - } - - fn definitions(&mut self) -> &mut Definitions { - &mut self.definitions - } } impl<'a> Resolver<'a> { |
