}
}
+type ErrorMessage = Option<(Span, String)>;
+
enum ResolveResult<T> {
- Failed, // Failed to resolve the name.
- Indeterminate, // Couldn't determine due to unresolved globs.
- Success(T) // Successfully resolved the import.
+ Failed(ErrorMessage), // Failed to resolve the name, optional helpful error message.
+ Indeterminate, // Couldn't determine due to unresolved globs.
+ Success(T) // Successfully resolved the import.
}
impl<T> ResolveResult<T> {
ViewItemExternCrate(name, _, node_id) => {
// n.b. we don't need to look at the path option here, because cstore already did
- for &crate_id in self.session.cstore.find_extern_mod_stmt_cnum(node_id).iter() {
+ for &crate_id in self.session.cstore
+ .find_extern_mod_stmt_cnum(node_id).iter() {
let def_id = DefId { krate: crate_id, node: 0 };
self.external_exports.insert(def_id);
- let parent_link = ModuleParentLink(parent.module().downgrade(), name);
+ let parent_link =
+ ModuleParentLink(parent.module().downgrade(), name);
let external_module = Rc::new(Module::new(parent_link,
Some(def_id),
NormalModuleKind,
debug!("(build reduced graph for item) found extern `{}`",
self.module_to_str(&*external_module));
parent.module().external_module_children.borrow_mut()
- .insert(name.name,
- external_module.clone());
+ .insert(name.name, external_module.clone());
self.build_reduced_graph_for_external_crate(external_module);
}
}
let import_directive = imports.get(import_index);
match self.resolve_import_for_module(module.clone(),
import_directive) {
- Failed => {
- // We presumably emitted an error. Continue.
- let msg = format!("failed to resolve import `{}`",
- self.import_path_to_str(
- import_directive.module_path
- .as_slice(),
- import_directive.subclass));
- self.resolve_error(import_directive.span, msg.as_slice());
- }
- Indeterminate => {
- // Bail out. We'll come around next time.
- break;
- }
- Success(()) => {
- // Good. Continue.
+ Failed(err) => {
+ let (span, help) = match err {
+ Some((span, msg)) => (span, format!(". {}", msg)),
+ None => (import_directive.span, String::new())
+ };
+ let msg = format!("unresolved import `{}`{}",
+ self.import_path_to_str(
+ import_directive.module_path
+ .as_slice(),
+ import_directive.subclass),
+ help);
+ self.resolve_error(span, msg.as_slice());
}
+ Indeterminate => break, // Bail out. We'll come around next time.
+ Success(()) => () // Good. Continue.
}
module.resolved_import_count
module_: Rc<Module>,
import_directive: &ImportDirective)
-> ResolveResult<()> {
- let mut resolution_result = Failed;
+ let mut resolution_result = Failed(None);
let module_path = &import_directive.module_path;
debug!("(resolving import for module) resolving import `{}::...` in \
DontUseLexicalScope,
import_directive.span,
ImportSearch) {
-
- Failed => None,
+ Failed(err) => {
+ resolution_result = Failed(err);
+ None
+ },
Indeterminate => {
resolution_result = Indeterminate;
None
}
if value_result.is_unbound() && type_result.is_unbound() {
- let msg = format!("unresolved import: there is no \
- `{}` in `{}`",
+ let msg = format!("There is no `{}` in `{}`",
token::get_ident(source),
self.module_to_str(&*containing_module));
- self.resolve_error(directive.span, msg.as_slice());
- return Failed;
+ return Failed(Some((directive.span, msg)));
}
let value_used_public = value_used_reexport || value_used_public;
let type_used_public = type_used_reexport || type_used_public;
TypeNS,
name_search_type,
false) {
- Failed => {
+ Failed(None) => {
let segment_name = token::get_ident(name);
let module_name = self.module_to_str(&*search_module);
- if "???" == module_name.as_slice() {
- let span = Span {
- lo: span.lo,
- hi: span.lo + Pos::from_uint(segment_name.get().len()),
- expn_info: span.expn_info,
- };
+ let mut span = span;
+ let msg = if "???" == module_name.as_slice() {
+ span.hi = span.lo + Pos::from_uint(segment_name.get().len());
- match search_parent_externals(name.name, &self.current_module) {
+ match search_parent_externals(name.name,
+ &self.current_module) {
Some(module) => {
let path_str = self.idents_to_str(module_path);
let target_mod_str = self.module_to_str(&*module);
- let current_mod_str = self.module_to_str(&*self.current_module);
+ let current_mod_str =
+ self.module_to_str(&*self.current_module);
let prefix = if target_mod_str == current_mod_str {
"self::".to_string()
format!("{}::", target_mod_str)
};
- self.resolve_error(span, format!("unresolved import. Did you mean \
- `{}{}`?",
- prefix, path_str).as_slice());
+ format!("Did you mean `{}{}`?", prefix, path_str)
},
- None => self.resolve_error(span, format!("unresolved import. Maybe a \
- missing `extern crate {}`?",
- segment_name).as_slice()),
+ None => format!("Maybe a missing `extern crate {}`?",
+ segment_name),
}
+ } else {
+ format!("Could not find `{}` in `{}`.",
+ segment_name,
+ module_name)
+ };
- return Failed;
- }
- self.resolve_error(span,
- format!("unresolved import: could not \
- find `{}` in `{}`.",
- segment_name,
- module_name).as_slice());
- return Failed;
+ return Failed(Some((span, msg)));
}
+ Failed(err) => return Failed(err),
Indeterminate => {
debug!("(resolving module path for import) module \
resolution is indeterminate: {}",
Some(ref type_def) => {
match type_def.module_def {
None => {
- // Not a module.
- self.resolve_error(
- span,
- format!("not a module `{}`",
- token::get_ident(name))
- .as_slice());
- return Failed;
+ let msg = format!("Not a module `{}`",
+ token::get_ident(name));
+
+ return Failed(Some((span, msg)));
}
Some(ref module_def) => {
// If we're doing the search for an
module_def.kind.get()) {
(ImportSearch, TraitModuleKind) |
(ImportSearch, ImplModuleKind) => {
- self.resolve_error(
- span,
- "cannot import from a trait \
- or type implementation");
- return Failed;
+ let msg =
+ "Cannot import from a trait or \
+ type implementation".to_string();
+ return Failed(Some((span, msg)));
}
(_, _) => {
search_module = module_def.clone();
}
None => {
// There are no type bindings at all.
- self.resolve_error(
- span,
- format!("not a module `{}`",
- token::get_ident(name)).as_slice());
- return Failed;
+ let msg = format!("Not a module `{}`",
+ token::get_ident(name));
+ return Failed(Some((span, msg)));
}
}
}
let start_index;
let last_private;
match module_prefix_result {
- Failed => {
+ Failed(None) => {
let mpath = self.idents_to_str(module_path);
- match mpath.as_slice().rfind(':') {
+ let mpath = mpath.as_slice();
+ match mpath.rfind(':') {
Some(idx) => {
- self.resolve_error(
- span,
- format!("unresolved import: could not find `{}` \
- in `{}`",
- // idx +- 1 to account for the colons on \
- // either side
- mpath.as_slice().slice_from(idx + 1),
- mpath.as_slice()
- .slice_to(idx - 1)).as_slice());
+ let msg = format!("Could not find `{}` in `{}`",
+ // idx +- 1 to account for the
+ // colons on either side
+ mpath.slice_from(idx + 1),
+ mpath.slice_to(idx - 1));
+ return Failed(Some((span, msg)));
},
- None => (),
- };
- return Failed;
+ None => return Failed(None),
+ }
}
+ Failed(err) => return Failed(err),
Indeterminate => {
debug!("(resolving module path for import) indeterminate; \
bailing");
// This is not a crate-relative path. We resolve the
// first component of the path in the current lexical
// scope and then proceed to resolve below that.
- let result = self.resolve_module_in_lexical_scope(
- module_,
- module_path[0]);
- match result {
- Failed => {
- self.resolve_error(span, "unresolved name");
- return Failed;
- }
+ match self.resolve_module_in_lexical_scope(
+ module_,
+ module_path[0]) {
+ Failed(err) => return Failed(err),
Indeterminate => {
debug!("(resolving module path for import) \
indeterminate; bailing");
// No more parents. This module was unresolved.
debug!("(resolving item in lexical scope) unresolved \
module");
- return Failed;
+ return Failed(None);
}
ModuleParentLink(parent_module_node, _) => {
match search_module.kind.get() {
scope) unresolved module: not \
searching through module \
parents");
- return Failed;
+ return Failed(None);
}
ExternModuleKind |
TraitModuleKind |
namespace,
PathSearch,
true) {
- Failed => {
- // Continue up the search chain.
- }
+ Failed(Some((span, msg))) =>
+ self.resolve_error(span, format!("failed to resolve. {}",
+ msg)),
+ Failed(None) => (), // Continue up the search chain.
Indeterminate => {
// We couldn't see through the higher scope because of an
// unresolved import higher up. Bail.
debug!("!!! (resolving module in lexical \
scope) module wasn't actually a \
module!");
- return Failed;
+ return Failed(None);
}
Some(ref module_def) => {
return Success(module_def.clone());
None => {
debug!("!!! (resolving module in lexical scope) module
wasn't actually a module!");
- return Failed;
+ return Failed(None);
}
}
}
bailing");
return Indeterminate;
}
- Failed => {
- debug!("(resolving module in lexical scope) failed to \
- resolve");
- return Failed;
+ Failed(err) => {
+ debug!("(resolving module in lexical scope) failed to resolve");
+ return Failed(err);
}
}
}
debug!("(resolving module prefix) resolving `super` at {}",
self.module_to_str(&*containing_module));
match self.get_nearest_normal_module_parent(containing_module) {
- None => return Failed,
+ None => return Failed(None),
Some(new_module) => {
containing_module = new_module;
i += 1;
// We're out of luck.
debug!("(resolving name in module) failed to resolve `{}`",
token::get_name(name).get());
- return Failed;
+ return Failed(None);
}
fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
Indeterminate => {
fail!("unexpected indeterminate result");
}
+ Failed(err) => {
+ match err {
+ Some((span, msg)) => {
+ self.resolve_error(span, format!("failed to resolve: {}",
+ msg));
+ }
+ None => ()
+ }
- Failed => {
debug!("(resolve bare identifier pattern) failed to find {}",
token::get_ident(name));
return BareIdentifierPatternUnresolved;
UseLexicalScope,
path.span,
PathSearch) {
- Failed => {
- let msg = format!("use of undeclared module `{}`",
- self.idents_to_str(module_path_idents.as_slice()));
- self.resolve_error(path.span, msg.as_slice());
- return None;
- }
+ Failed(err) => {
+ let (span, msg) = match err {
+ Some((span, msg)) => (span, msg),
+ None => {
+ let msg = format!("Use of undeclared module `{}`",
+ self.idents_to_str(
+ module_path_idents.as_slice()));
+ (path.span, msg)
+ }
+ };
- Indeterminate => {
- fail!("indeterminate unexpected");
+ self.resolve_error(span, format!("failed to resolve. {}",
+ msg.as_slice()));
+ return None;
}
-
+ Indeterminate => fail!("indeterminate unexpected"),
Success((resulting_module, resulting_last_private)) => {
containing_module = resulting_module;
last_private = resulting_last_private;
path.span,
PathSearch,
LastMod(AllPublic)) {
- Failed => {
- let msg = format!("use of undeclared module `::{}`",
- self.idents_to_str(module_path_idents.as_slice()));
- self.resolve_error(path.span, msg.as_slice());
+ Failed(err) => {
+ let (span, msg) = match err {
+ Some((span, msg)) => (span, msg),
+ None => {
+ let msg = format!("Use of undeclared module `::{}`",
+ self.idents_to_str(
+ module_path_idents.as_slice()));
+ (path.span, msg)
+ }
+ };
+
+ self.resolve_error(span, format!("failed to resolve. {}",
+ msg.as_slice()));
return None;
}
Indeterminate => {
fail!("unexpected indeterminate result");
}
- Failed => {
+ Failed(err) => {
+ match err {
+ Some((span, msg)) =>
+ self.resolve_error(span, format!("failed to resolve. {}", msg)),
+ None => ()
+ }
+
debug!("(resolving item path by identifier in lexical scope) \
failed to resolve {}", token::get_ident(ident));
return None;
rs
}
- fn resolve_error(&self, span: Span, s: &str) {
+ fn resolve_error<T: Str>(&self, span: Span, s: T) {
if self.emit_errors {
- self.session.span_err(span, s);
+ self.session.span_err(span, s.as_slice());
}
}