Auto merge of #31212 - jseyfried:fix_ICE_in_resolve, r=nrc
This fixes an ICE introduced by #31065 that occurs when a path cannot be resolved because of a certain class of unresolved import (`Indeterminate` imports). For example, this currently causes an ICE: ```rust mod foo { pub use self::*; } fn main() { foo::f() } ``` r? @nrc
This commit is contained in:
commit
ebe92e55f7
3 changed files with 35 additions and 73 deletions
|
@ -44,7 +44,6 @@ use self::RibKind::*;
|
|||
use self::UseLexicalScopeFlag::*;
|
||||
use self::ModulePrefixResult::*;
|
||||
use self::AssocItemResolveResult::*;
|
||||
use self::NameSearchType::*;
|
||||
use self::BareIdentifierPatternResolution::*;
|
||||
use self::ParentLink::*;
|
||||
use self::FallbackChecks::*;
|
||||
|
@ -784,16 +783,6 @@ enum AssocItemResolveResult {
|
|||
ResolveAttempt(Option<PathResolution>),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
enum NameSearchType {
|
||||
/// We're doing a name search in order to resolve a `use` directive.
|
||||
ImportSearch,
|
||||
|
||||
/// We're doing a name search in order to resolve a path type, a path
|
||||
/// expression, or a path pattern.
|
||||
PathSearch,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum BareIdentifierPatternResolution {
|
||||
FoundStructOrEnumVariant(Def, LastPrivate),
|
||||
|
@ -1370,7 +1359,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
module_path: &[Name],
|
||||
index: usize,
|
||||
span: Span,
|
||||
name_search_type: NameSearchType,
|
||||
lp: LastPrivate)
|
||||
-> ResolveResult<(Module<'a>, LastPrivate)> {
|
||||
fn search_parent_externals<'a>(needle: Name, module: Module<'a>)
|
||||
|
@ -1396,11 +1384,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
// modules as we go.
|
||||
while index < module_path_len {
|
||||
let name = module_path[index];
|
||||
match self.resolve_name_in_module(search_module,
|
||||
name,
|
||||
TypeNS,
|
||||
name_search_type,
|
||||
false) {
|
||||
match self.resolve_name_in_module(search_module, name, TypeNS, false) {
|
||||
Failed(None) => {
|
||||
let segment_name = name.as_str();
|
||||
let module_name = module_to_string(search_module);
|
||||
|
@ -1477,8 +1461,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
module_: Module<'a>,
|
||||
module_path: &[Name],
|
||||
use_lexical_scope: UseLexicalScopeFlag,
|
||||
span: Span,
|
||||
name_search_type: NameSearchType)
|
||||
span: Span)
|
||||
-> ResolveResult<(Module<'a>, LastPrivate)> {
|
||||
let module_path_len = module_path.len();
|
||||
assert!(module_path_len > 0);
|
||||
|
@ -1559,7 +1542,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
module_path,
|
||||
start_index,
|
||||
span,
|
||||
name_search_type,
|
||||
last_private)
|
||||
}
|
||||
|
||||
|
@ -1658,11 +1640,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
}
|
||||
|
||||
// Resolve the name in the parent module.
|
||||
match self.resolve_name_in_module(search_module,
|
||||
name,
|
||||
namespace,
|
||||
PathSearch,
|
||||
true) {
|
||||
match self.resolve_name_in_module(search_module, name, namespace, true) {
|
||||
Failed(Some((span, msg))) => {
|
||||
resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
|
||||
}
|
||||
|
@ -1787,7 +1765,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
module_: Module<'a>,
|
||||
name: Name,
|
||||
namespace: Namespace,
|
||||
name_search_type: NameSearchType,
|
||||
allow_private_imports: bool)
|
||||
-> ResolveResult<(Target<'a>, bool)> {
|
||||
debug!("(resolving name in module) resolving `{}` in `{}`",
|
||||
|
@ -1811,14 +1788,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
// Next, check the module's imports if necessary.
|
||||
|
||||
// If this is a search of all imports, we should be done with glob
|
||||
// resolution at this point.
|
||||
if name_search_type == PathSearch {
|
||||
assert_eq!(module_.glob_count.get(), 0);
|
||||
}
|
||||
|
||||
// Check the list of resolved imports.
|
||||
let children = module_.import_resolutions.borrow();
|
||||
match children.get(&name) {
|
||||
|
@ -2912,9 +2881,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
Indeterminate => {
|
||||
panic!("unexpected indeterminate result");
|
||||
}
|
||||
Indeterminate => return BareIdentifierPatternUnresolved,
|
||||
Failed(err) => {
|
||||
match err {
|
||||
Some((span, msg)) => {
|
||||
|
@ -3154,11 +3121,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
let containing_module;
|
||||
let last_private;
|
||||
let current_module = self.current_module;
|
||||
match self.resolve_module_path(current_module,
|
||||
&module_path[..],
|
||||
UseLexicalScope,
|
||||
span,
|
||||
PathSearch) {
|
||||
match self.resolve_module_path(current_module, &module_path, UseLexicalScope, span) {
|
||||
Failed(err) => {
|
||||
let (span, msg) = match err {
|
||||
Some((span, msg)) => (span, msg),
|
||||
|
@ -3172,7 +3135,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
|
||||
return None;
|
||||
}
|
||||
Indeterminate => panic!("indeterminate unexpected"),
|
||||
Indeterminate => return None,
|
||||
Success((resulting_module, resulting_last_private)) => {
|
||||
containing_module = resulting_module;
|
||||
last_private = resulting_last_private;
|
||||
|
@ -3180,11 +3143,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
}
|
||||
|
||||
let name = segments.last().unwrap().identifier.name;
|
||||
let def = match self.resolve_name_in_module(containing_module,
|
||||
name,
|
||||
namespace,
|
||||
NameSearchType::PathSearch,
|
||||
false) {
|
||||
let def = match self.resolve_name_in_module(containing_module, name, namespace, false) {
|
||||
Success((Target { binding, .. }, _)) => {
|
||||
let (def, lp) = binding.def_and_lp();
|
||||
(def, last_private.or(lp))
|
||||
|
@ -3219,7 +3178,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
&module_path[..],
|
||||
0,
|
||||
span,
|
||||
PathSearch,
|
||||
LastMod(AllPublic)) {
|
||||
Failed(err) => {
|
||||
let (span, msg) = match err {
|
||||
|
@ -3235,9 +3193,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
return None;
|
||||
}
|
||||
|
||||
Indeterminate => {
|
||||
panic!("indeterminate unexpected");
|
||||
}
|
||||
Indeterminate => return None,
|
||||
|
||||
Success((resulting_module, resulting_last_private)) => {
|
||||
containing_module = resulting_module;
|
||||
|
@ -3246,11 +3202,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
}
|
||||
|
||||
let name = segments.last().unwrap().identifier.name;
|
||||
match self.resolve_name_in_module(containing_module,
|
||||
name,
|
||||
namespace,
|
||||
NameSearchType::PathSearch,
|
||||
false) {
|
||||
match self.resolve_name_in_module(containing_module, name, namespace, false) {
|
||||
Success((Target { binding, .. }, _)) => {
|
||||
let (def, lp) = binding.def_and_lp();
|
||||
Some((def, last_private.or(lp)))
|
||||
|
@ -3292,7 +3244,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
if let Success((target, _)) = self.resolve_name_in_module(module,
|
||||
ident.unhygienic_name,
|
||||
namespace,
|
||||
PathSearch,
|
||||
true) {
|
||||
if let Some(def) = target.binding.def() {
|
||||
return Some(LocalDef::from_def(def));
|
||||
|
@ -3332,9 +3283,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
Indeterminate => {
|
||||
panic!("unexpected indeterminate result");
|
||||
}
|
||||
Indeterminate => None,
|
||||
Failed(err) => {
|
||||
debug!("(resolving item path by identifier in lexical scope) failed to resolve {}",
|
||||
name);
|
||||
|
@ -3390,11 +3339,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
match this.resolve_module_path(root,
|
||||
&name_path[..],
|
||||
UseLexicalScope,
|
||||
span,
|
||||
PathSearch) {
|
||||
match this.resolve_module_path(root, &name_path, UseLexicalScope, span) {
|
||||
Success((module, _)) => Some(module),
|
||||
_ => None,
|
||||
}
|
||||
|
@ -3640,10 +3585,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
let current_module = self.current_module;
|
||||
|
||||
match self.resolve_module_path(current_module,
|
||||
&name_path[..],
|
||||
UseLexicalScope,
|
||||
expr.span,
|
||||
PathSearch) {
|
||||
&name_path[..],
|
||||
UseLexicalScope,
|
||||
expr.span) {
|
||||
Success(_) => {
|
||||
context = UnresolvedNameContext::PathIsMod(expr.id);
|
||||
},
|
||||
|
|
|
@ -16,7 +16,6 @@ use Namespace::{self, TypeNS, ValueNS};
|
|||
use {NameBindings, NameBinding};
|
||||
use NamespaceResult::{BoundResult, UnboundResult, UnknownResult};
|
||||
use NamespaceResult;
|
||||
use NameSearchType;
|
||||
use ResolveResult;
|
||||
use Resolver;
|
||||
use UseLexicalScopeFlag;
|
||||
|
@ -321,8 +320,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
|
|||
match self.resolver.resolve_module_path(module_,
|
||||
&module_path[..],
|
||||
UseLexicalScopeFlag::DontUseLexicalScope,
|
||||
import_directive.span,
|
||||
NameSearchType::ImportSearch) {
|
||||
import_directive.span) {
|
||||
ResolveResult::Failed(err) => {
|
||||
resolution_result = ResolveResult::Failed(err);
|
||||
None
|
||||
|
|
20
src/test/compile-fail/issue-31212.rs
Normal file
20
src/test/compile-fail/issue-31212.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// This checks that a path that cannot be resolved because of an indeterminate import
|
||||
// does not trigger an ICE.
|
||||
|
||||
mod foo {
|
||||
pub use self::*; //~ ERROR unresolved
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo::f(); //~ ERROR unresolved
|
||||
}
|
Loading…
Add table
Reference in a new issue