Auto merge of #31321 - jseyfried:cleanup, r=nrc

The first commit improves detection of unused imports -- it should have been part of #30325. Right now, the unused import in the changed test would not be reported.

The rest of the commits are miscellaneous, independent clean-ups in resolve that I didn't think warranted individual PRs.

r? @nrc
This commit is contained in:
bors 2016-02-05 03:03:45 +00:00
commit dcf8ef2723
11 changed files with 131 additions and 293 deletions

View File

@ -20,7 +20,7 @@ use front::map as ast_map;
use session::Session;
use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
use middle::cstore::InlinedItem;
use middle::ty::{self, Ty};
use middle::ty;
use std::cell::RefCell;
use std::collections::hash_map::Entry;

View File

@ -26,7 +26,6 @@ use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
use syntax::{abi, ast};
use syntax::attr::{self, AttrMetaMethods};
use syntax::codemap::{self, Span};
use syntax::ast::{TyIs, TyUs, TyI8, TyU8, TyI16, TyU16, TyI32, TyU32, TyI64, TyU64};
use rustc_front::hir;
use rustc_front::intravisit::{self, Visitor};

View File

@ -142,29 +142,17 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
}
fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
// Check each statement.
for statement in &block.stmts {
match statement.node {
StmtDecl(ref declaration, _) => {
match declaration.node {
DeclItem(_) => {
return true;
}
_ => {
// Keep searching.
}
}
}
_ => {
// Keep searching.
fn is_item(statement: &hir::Stmt) -> bool {
if let StmtDecl(ref declaration, _) = statement.node {
if let DeclItem(_) = declaration.node {
return true;
}
}
false
}
// If we found no items, we don't need to create
// an anonymous module.
return false;
// If any statements are items, we need to create an anonymous module
block.stmts.iter().any(is_item)
}
/// Constructs the reduced graph for one item.
@ -309,7 +297,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
let external_module = self.new_extern_crate_module(parent_link, def);
self.define(parent, name, TypeNS, (external_module, sp));
self.build_reduced_graph_for_external_crate(&external_module);
self.build_reduced_graph_for_external_crate(external_module);
}
parent
}
@ -365,7 +353,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
for variant in &(*enum_definition).variants {
let item_def_id = self.ast_map.local_def_id(item.id);
self.build_reduced_graph_for_variant(variant, item_def_id,
&module, variant_modifiers);
module, variant_modifiers);
}
parent
}
@ -421,7 +409,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
};
let modifiers = DefModifiers::PUBLIC; // NB: not DefModifiers::IMPORTABLE
self.define(&module_parent, item.name, ns, (def, item.span, modifiers));
self.define(module_parent, item.name, ns, (def, item.span, modifiers));
self.trait_item_map.insert((item.name, def_id), item_def_id);
}

View File

@ -662,10 +662,11 @@ enum ResolveResult<T> {
}
impl<T> ResolveResult<T> {
fn success(&self) -> bool {
match *self {
Success(_) => true,
_ => false,
fn and_then<U, F: FnOnce(T) -> ResolveResult<U>>(self, f: F) -> ResolveResult<U> {
match self {
Failed(msg) => Failed(msg),
Indeterminate => Indeterminate,
Success(t) => f(t),
}
}
}
@ -789,7 +790,7 @@ enum ParentLink<'a> {
/// One node in the tree of modules.
pub struct ModuleS<'a> {
parent_link: ParentLink<'a>,
def: Cell<Option<Def>>,
def: Option<Def>,
is_public: bool,
is_extern_crate: bool,
@ -839,7 +840,7 @@ impl<'a> ModuleS<'a> {
fn new(parent_link: ParentLink<'a>, def: Option<Def>, external: bool, is_public: bool) -> Self {
ModuleS {
parent_link: parent_link,
def: Cell::new(def),
def: def,
is_public: is_public,
is_extern_crate: false,
children: RefCell::new(HashMap::new()),
@ -877,18 +878,18 @@ impl<'a> ModuleS<'a> {
}
fn def_id(&self) -> Option<DefId> {
self.def.get().as_ref().map(Def::def_id)
self.def.as_ref().map(Def::def_id)
}
fn is_normal(&self) -> bool {
match self.def.get() {
match self.def {
Some(Def::Mod(_)) | Some(Def::ForeignMod(_)) => true,
_ => false,
}
}
fn is_trait(&self) -> bool {
match self.def.get() {
match self.def {
Some(Def::Trait(_)) => true,
_ => false,
}
@ -987,7 +988,7 @@ impl<'a> NameBinding<'a> {
fn def(&self) -> Option<Def> {
match self.def_or_module {
DefOrModule::Def(def) => Some(def),
DefOrModule::Module(ref module) => module.def.get(),
DefOrModule::Module(ref module) => module.def,
}
}
@ -1197,7 +1198,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
#[inline]
fn record_import_use(&mut self, import_id: NodeId, name: Name) {
fn record_import_use(&mut self, name: Name, ns: Namespace, resolution: &ImportResolution<'a>) {
let import_id = resolution.id;
self.used_imports.insert((import_id, ns));
match resolution.target.as_ref().and_then(|target| target.target_module.def_id()) {
Some(DefId { krate, .. }) => { self.used_crates.insert(krate); }
_ => {}
};
if !self.make_glob_map {
return;
}
@ -1249,12 +1257,12 @@ 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, false) {
match self.resolve_name_in_module(search_module, name, TypeNS, false, true) {
Failed(None) => {
let segment_name = name.as_str();
let module_name = module_to_string(search_module);
let mut span = span;
let msg = if "???" == &module_name[..] {
let msg = if "???" == &module_name {
span.hi = span.lo + Pos::from_usize(segment_name.len());
match search_parent_externals(name, &self.current_module) {
@ -1328,8 +1336,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
use_lexical_scope: UseLexicalScopeFlag,
span: Span)
-> ResolveResult<(Module<'a>, LastPrivate)> {
let module_path_len = module_path.len();
assert!(module_path_len > 0);
if module_path.len() == 0 {
return Success((self.graph_root, LastMod(AllPublic))) // Use the crate root
}
debug!("(resolving module path for import) processing `{}` rooted at `{}`",
names_to_string(module_path),
@ -1380,16 +1389,22 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// 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.
match self.resolve_module_in_lexical_scope(module_, module_path[0]) {
match self.resolve_item_in_lexical_scope(module_,
module_path[0],
TypeNS,
true) {
Failed(err) => return Failed(err),
Indeterminate => {
debug!("(resolving module path for import) indeterminate; bailing");
return Indeterminate;
}
Success(containing_module) => {
search_module = containing_module;
start_index = 1;
last_private = LastMod(AllPublic);
Success((target, _)) => match target.binding.module() {
Some(containing_module) => {
search_module = containing_module;
start_index = 1;
last_private = LastMod(AllPublic);
}
None => return Failed(None),
}
}
}
@ -1423,47 +1438,29 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
namespace,
module_to_string(&*module_));
// The current module node is handled specially. First, check for
// its immediate children.
build_reduced_graph::populate_module_if_necessary(self, &module_);
if let Some(binding) = module_.get_child(name, namespace) {
debug!("top name bindings succeeded");
return Success((Target::new(module_, binding, Shadowable::Never), false));
}
// Now check for its import directives. We don't have to have resolved
// all its imports in the usual way; this is because chains of
// adjacent import statements are processed as though they mutated the
// current scope.
if let Some(import_resolution) =
module_.import_resolutions.borrow().get(&(name, namespace)) {
match import_resolution.target.clone() {
None => {
// Not found; continue.
debug!("(resolving item in lexical scope) found import resolution, but not \
in namespace {:?}",
namespace);
}
Some(target) => {
debug!("(resolving item in lexical scope) using import resolution");
// track used imports and extern crates as well
let id = import_resolution.id;
if record_used {
self.used_imports.insert((id, namespace));
self.record_import_use(id, name);
if let Some(DefId{krate: kid, ..}) = target.target_module.def_id() {
self.used_crates.insert(kid);
}
}
return Success((target, false));
}
}
}
// Finally, proceed up the scope chain looking for parent modules.
// Proceed up the scope chain looking for parent modules.
let mut search_module = module_;
loop {
// Resolve the name in the parent module.
match self.resolve_name_in_module(search_module, name, namespace, true, record_used) {
Failed(Some((span, msg))) => {
resolve_error(self, span, ResolutionError::FailedToResolve(&*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 item in lexical scope) indeterminate higher scope; bailing");
return Indeterminate;
}
Success((target, used_reexport)) => {
// We found the module.
debug!("(resolving item in lexical scope) found name in module, done");
return Success((target, used_reexport));
}
}
// Go to the next parent.
match search_module.parent_link {
NoParentLink => {
@ -1485,55 +1482,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
search_module = parent_module_node;
}
}
// Resolve the name in the parent module.
match self.resolve_name_in_module(search_module, name, namespace, true) {
Failed(Some((span, msg))) => {
resolve_error(self, span, ResolutionError::FailedToResolve(&*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 item in lexical scope) indeterminate higher scope; bailing");
return Indeterminate;
}
Success((target, used_reexport)) => {
// We found the module.
debug!("(resolving item in lexical scope) found name in module, done");
return Success((target, used_reexport));
}
}
}
}
/// Resolves a module name in the current lexical scope.
fn resolve_module_in_lexical_scope(&mut self,
module_: Module<'a>,
name: Name)
-> ResolveResult<Module<'a>> {
// If this module is an anonymous module, resolve the item in the
// lexical scope. Otherwise, resolve the item from the crate root.
let resolve_result = self.resolve_item_in_lexical_scope(module_, name, TypeNS, true);
match resolve_result {
Success((target, _)) => {
if let Some(module_def) = target.binding.module() {
return Success(module_def)
} else {
debug!("!!! (resolving module in lexical scope) module \
wasn't actually a module!");
return Failed(None);
}
}
Indeterminate => {
debug!("(resolving module in lexical scope) indeterminate; bailing");
return Indeterminate;
}
Failed(err) => {
debug!("(resolving module in lexical scope) failed to resolve");
return Failed(err);
}
}
}
@ -1612,14 +1560,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
module_: Module<'a>,
name: Name,
namespace: Namespace,
allow_private_imports: bool)
allow_private_imports: bool,
record_used: bool)
-> ResolveResult<(Target<'a>, bool)> {
debug!("(resolving name in module) resolving `{}` in `{}`",
name,
module_to_string(&*module_));
// First, check the direct children of the module.
build_reduced_graph::populate_module_if_necessary(self, &module_);
build_reduced_graph::populate_module_if_necessary(self, module_);
if let Some(binding) = module_.get_child(name, namespace) {
debug!("(resolving name in module) found node as child");
@ -1633,22 +1582,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
debug!("(resolving name in module) import unresolved; bailing out");
return Indeterminate;
}
match import_resolution.target.clone() {
None => {
debug!("(resolving name in module) name found, but not in namespace {:?}",
namespace);
}
Some(target) => {
debug!("(resolving name in module) resolved to import");
// track used imports and extern crates as well
let id = import_resolution.id;
self.used_imports.insert((id, namespace));
self.record_import_use(id, name);
if let Some(DefId{krate: kid, ..}) = target.target_module.def_id() {
self.used_crates.insert(kid);
}
return Success((target, true));
if let Some(target) = import_resolution.target.clone() {
debug!("(resolving name in module) resolved to import");
if record_used {
self.record_import_use(name, namespace, &import_resolution);
}
return Success((target, true));
}
}
Some(..) | None => {} // Continue.
@ -1670,7 +1609,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
// Descend into children and anonymous children.
build_reduced_graph::populate_module_if_necessary(self, &module_);
build_reduced_graph::populate_module_if_necessary(self, module_);
module_.for_each_local_child(|_, _, child_node| {
match child_node.module() {
@ -2835,9 +2774,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
}
// Check the items.
let module = self.current_module;
let name = identifier.unhygienic_name;
self.resolve_item_by_name_in_lexical_scope(name, namespace, record_used)
.map(LocalDef::from_def)
match self.resolve_item_in_lexical_scope(module, name, namespace, record_used) {
Success((target, _)) => target.binding.def().map(LocalDef::from_def),
Failed(Some((span, msg))) => {
resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
None
}
_ => None,
}
}
// Resolve a local definition, potentially adjusting for closures.
@ -2967,7 +2914,8 @@ 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, false) {
let result = self.resolve_name_in_module(containing_module, name, namespace, false, true);
let def = match result {
Success((Target { binding, .. }, _)) => {
let (def, lp) = binding.def_and_lp();
(def, last_private.or(lp))
@ -2999,7 +2947,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let containing_module;
let last_private;
match self.resolve_module_path_from_root(root_module,
&module_path[..],
&module_path,
0,
span,
LastMod(AllPublic)) {
@ -3008,7 +2956,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
Some((span, msg)) => (span, msg),
None => {
let msg = format!("Use of undeclared module `::{}`",
names_to_string(&module_path[..]));
names_to_string(&module_path));
(span, msg)
}
};
@ -3026,7 +2974,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
let name = segments.last().unwrap().identifier.name;
match self.resolve_name_in_module(containing_module, name, namespace, false) {
match self.resolve_name_in_module(containing_module, name, namespace, false, true) {
Success((Target { binding, .. }, _)) => {
let (def, lp) = binding.def_and_lp();
Some((def, last_private.or(lp)))
@ -3068,6 +3016,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
if let Success((target, _)) = self.resolve_name_in_module(module,
ident.unhygienic_name,
namespace,
true,
true) {
if let Some(def) = target.binding.def() {
return Some(LocalDef::from_def(def));
@ -3079,49 +3028,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
None
}
fn resolve_item_by_name_in_lexical_scope(&mut self,
name: Name,
namespace: Namespace,
record_used: bool)
-> Option<Def> {
// Check the items.
let module = self.current_module;
match self.resolve_item_in_lexical_scope(module, name, namespace, record_used) {
Success((target, _)) => {
match target.binding.def() {
None => {
// This can happen if we were looking for a type and
// found a module instead. Modules don't have defs.
debug!("(resolving item path by identifier in lexical scope) failed to \
resolve {} after success...",
name);
None
}
Some(def) => {
debug!("(resolving item path in lexical scope) resolved `{}` to item",
name);
// This lookup is "all public" because it only searched
// for one identifier in the current module (couldn't
// have passed through reexports or anything like that.
Some(def)
}
}
}
Indeterminate => None,
Failed(err) => {
debug!("(resolving item path by identifier in lexical scope) failed to \
resolve `{}`",
name);
if let Some((span, msg)) = err {
resolve_error(self, span, ResolutionError::FailedToResolve(&*msg))
}
None
}
}
}
fn with_no_errors<T, F>(&mut self, f: F) -> T
where F: FnOnce(&mut Resolver) -> T
{
@ -3564,13 +3470,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
};
if self.trait_item_map.contains_key(&(name, did)) {
add_trait_info(&mut found_traits, did, name);
let id = import.id;
self.used_imports.insert((id, TypeNS));
let trait_name = self.get_trait_name(did);
self.record_import_use(id, trait_name);
if let Some(DefId{krate: kid, ..}) = target.target_module.def_id() {
self.used_crates.insert(kid);
}
self.record_import_use(trait_name, TypeNS, &import);
}
}

View File

@ -257,7 +257,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
errors.extend(self.resolve_imports_for_module(module_));
self.resolver.current_module = orig_module;
build_reduced_graph::populate_module_if_necessary(self.resolver, &module_);
build_reduced_graph::populate_module_if_necessary(self.resolver, module_);
module_.for_each_local_child(|_, _, child_node| {
match child_node.module() {
None => {
@ -332,92 +332,45 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
module_: Module<'b>,
import_directive: &ImportDirective)
-> ResolveResult<()> {
let mut resolution_result = ResolveResult::Failed(None);
let module_path = &import_directive.module_path;
debug!("(resolving import for module) resolving import `{}::...` in `{}`",
names_to_string(&module_path[..]),
names_to_string(&import_directive.module_path),
module_to_string(&*module_));
// First, resolve the module path for the directive, if necessary.
let container = if module_path.is_empty() {
// Use the crate root.
Some((self.resolver.graph_root, LastMod(AllPublic)))
} else {
match self.resolver.resolve_module_path(module_,
&module_path[..],
UseLexicalScopeFlag::DontUseLexicalScope,
import_directive.span) {
ResolveResult::Failed(err) => {
resolution_result = ResolveResult::Failed(err);
None
}
ResolveResult::Indeterminate => {
resolution_result = ResolveResult::Indeterminate;
None
}
ResolveResult::Success(container) => Some(container),
}
};
match container {
None => {}
Some((containing_module, lp)) => {
self.resolver
.resolve_module_path(module_,
&import_directive.module_path,
UseLexicalScopeFlag::DontUseLexicalScope,
import_directive.span)
.and_then(|(containing_module, lp)| {
// We found the module that the target is contained
// within. Attempt to resolve the import within it.
match import_directive.subclass {
SingleImport(target, source) => {
resolution_result = self.resolve_single_import(&module_,
containing_module,
target,
source,
import_directive,
lp);
}
GlobImport => {
resolution_result = self.resolve_glob_import(&module_,
containing_module,
import_directive,
lp);
}
if let SingleImport(target, source) = import_directive.subclass {
self.resolve_single_import(module_,
containing_module,
target,
source,
import_directive,
lp)
} else {
self.resolve_glob_import(module_, containing_module, import_directive, lp)
}
}
}
// Decrement the count of unresolved imports.
match resolution_result {
ResolveResult::Success(()) => {
})
.and_then(|()| {
// Decrement the count of unresolved imports.
assert!(self.resolver.unresolved_imports >= 1);
self.resolver.unresolved_imports -= 1;
}
_ => {
// Nothing to do here; just return the error.
}
}
// Decrement the count of unresolved globs if necessary. But only if
// the resolution result is a success -- other cases will
// be handled by the main loop.
if resolution_result.success() {
match import_directive.subclass {
GlobImport => {
if let GlobImport = import_directive.subclass {
module_.dec_glob_count();
if import_directive.is_public {
module_.dec_pub_glob_count();
}
}
SingleImport(..) => {
// Ignore.
if import_directive.is_public {
module_.dec_pub_count();
}
}
if import_directive.is_public {
module_.dec_pub_count();
}
}
return resolution_result;
Success(())
})
}
/// Resolves the name in the namespace of the module because it is being imported by
@ -460,12 +413,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
let target = resolution.target.clone();
if let Some(Target { target_module, binding, shadowable: _ }) = target {
// track used imports and extern crates as well
self.resolver.used_imports.insert((resolution.id, ns));
self.resolver.record_import_use(resolution.id, name);
if let Some(DefId { krate, .. }) = target_module.def_id() {
self.resolver.used_crates.insert(krate);
}
self.resolver.record_import_use(name, ns, &resolution);
(Success((target_module, binding)), true)
} else {
(Failed(None), false)
@ -517,9 +465,9 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
// We need to resolve both namespaces for this to succeed.
let (value_result, value_used_reexport) =
self.resolve_name_in_module(&target_module, source, ValueNS, module_);
self.resolve_name_in_module(target_module, source, ValueNS, module_);
let (type_result, type_used_reexport) =
self.resolve_name_in_module(&target_module, source, TypeNS, module_);
self.resolve_name_in_module(target_module, source, TypeNS, module_);
match (&value_result, &type_result) {
(&Success((_, ref name_binding)), _) if !value_used_reexport &&
@ -637,7 +585,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
if let (&Failed(_), &Failed(_)) = (&value_result, &type_result) {
let msg = format!("There is no `{}` in `{}`{}",
source,
module_to_string(&target_module), lev_suggestion);
module_to_string(target_module), lev_suggestion);
return Failed(Some((directive.span, msg)));
}
@ -763,7 +711,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
}
// Add all children from the containing module.
build_reduced_graph::populate_module_if_necessary(self.resolver, &target_module);
build_reduced_graph::populate_module_if_necessary(self.resolver, target_module);
target_module.for_each_local_child(|name, ns, name_binding| {
self.merge_import_resolution(module_,

View File

@ -26,7 +26,7 @@ use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType};
use middle::def_id::DefId;
use middle::infer;
use middle::pat_util;
use middle::subst::{self, Substs};
use middle::subst;
use rustc::front::map as hir_map;
use rustc_front::hir;
use trans::{type_of, adt, machine, monomorphize};

View File

@ -15,7 +15,7 @@ use super::namespace::crate_root_namespace;
use trans::common::CrateContext;
use middle::def_id::DefId;
use middle::infer;
use middle::subst::{self, Substs};
use middle::subst;
use middle::ty::{self, Ty};
use rustc_front::hir;

View File

@ -50,7 +50,6 @@ use middle::ty::cast::{CastKind, CastTy};
use syntax::codemap::Span;
use rustc_front::hir;
use syntax::ast;
use syntax::ast::UintTy::TyU8;
/// Reifies a cast check to be checked once we have full type information for

View File

@ -17,7 +17,7 @@ use astconv::AstConv;
use check::{self, FnCtxt};
use front::map as hir_map;
use middle::ty::{self, Ty, ToPolyTraitRef, ToPredicate, TypeFoldable};
use middle::cstore::{self, CrateStore, DefLike};
use middle::cstore::{self, CrateStore};
use middle::def::Def;
use middle::def_id::DefId;
use middle::lang_items::FnOnceTraitLangItem;

View File

@ -92,7 +92,7 @@ use middle::infer;
use middle::infer::{TypeOrigin, type_variable};
use middle::pat_util::{self, pat_id_map};
use middle::privacy::{AllPublic, LastMod};
use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace};
use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace};
use middle::traits::{self, report_fulfillment_errors};
use middle::ty::{GenericPredicates, TypeScheme};
use middle::ty::{Disr, ParamTy, ParameterEnvironment};

View File

@ -56,7 +56,10 @@ mod bar {
use foo::Point;
use foo::Square; //~ ERROR unused import
pub fn cc(_p: Point) -> super::Square {
super::Square
fn f() -> super::Square {
super::Square
}
f()
}
}