Skip to content

Commit

Permalink
Auto merge of #47574 - zilbuz:issue-14844, r=nikomatsakis
Browse files Browse the repository at this point in the history
Show the used type variable when issuing a "can't use type parameters from outer function" error message

Fix #14844

r? @estebank
  • Loading branch information
bors committed Mar 10, 2018
2 parents 948e3a3 + 0e68bb9 commit 87344aa
Show file tree
Hide file tree
Showing 13 changed files with 309 additions and 43 deletions.
9 changes: 6 additions & 3 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,8 @@ impl<'a> LoweringContext<'a> {
def_node_id,
DefPathData::LifetimeDef(name.as_str()),
DefIndexAddressSpace::High,
Mark::root()
Mark::root(),
span
);

hir::GenericParam::Lifetime(hir::LifetimeDef {
Expand Down Expand Up @@ -1003,7 +1004,8 @@ impl<'a> LoweringContext<'a> {
def_node_id,
DefPathData::ImplTrait,
DefIndexAddressSpace::High,
Mark::root()
Mark::root(),
span
);

let hir_bounds = self.lower_bounds(bounds, itctx);
Expand Down Expand Up @@ -1150,7 +1152,8 @@ impl<'a> LoweringContext<'a> {
def_node_id,
DefPathData::LifetimeDef(name.name().as_str()),
DefIndexAddressSpace::High,
Mark::root()
Mark::root(),
lifetime.span
);
let def_lifetime = hir::Lifetime {
id: def_node_id,
Expand Down
44 changes: 28 additions & 16 deletions src/librustc/hir/map/def_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use syntax::visit;
use syntax::symbol::keywords;
use syntax::symbol::Symbol;
use syntax::parse::token::{self, Token};
use syntax_pos::Span;

use hir::map::{ITEM_LIKE_SPACE, REGULAR_SPACE};

Expand Down Expand Up @@ -57,12 +58,13 @@ impl<'a> DefCollector<'a> {
fn create_def(&mut self,
node_id: NodeId,
data: DefPathData,
address_space: DefIndexAddressSpace)
address_space: DefIndexAddressSpace,
span: Span)
-> DefIndex {
let parent_def = self.parent_def.unwrap();
debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def);
self.definitions
.create_def_with_parent(parent_def, node_id, data, address_space, self.expansion)
.create_def_with_parent(parent_def, node_id, data, address_space, self.expansion, span)
}

pub fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_def: DefIndex, f: F) {
Expand All @@ -83,7 +85,7 @@ impl<'a> DefCollector<'a> {
_ => {}
}

self.create_def(expr.id, DefPathData::Initializer, REGULAR_SPACE);
self.create_def(expr.id, DefPathData::Initializer, REGULAR_SPACE, expr.span);
}

fn visit_macro_invoc(&mut self, id: NodeId, const_expr: bool) {
Expand Down Expand Up @@ -122,7 +124,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
return visit::walk_item(self, i);
}
};
let def = self.create_def(i.id, def_data, ITEM_LIKE_SPACE);
let def = self.create_def(i.id, def_data, ITEM_LIKE_SPACE, i.span);

self.with_parent(def, |this| {
match i.node {
Expand All @@ -131,14 +133,16 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
let variant_def_index =
this.create_def(v.node.data.id(),
DefPathData::EnumVariant(v.node.name.name.as_str()),
REGULAR_SPACE);
REGULAR_SPACE,
v.span);
this.with_parent(variant_def_index, |this| {
for (index, field) in v.node.data.fields().iter().enumerate() {
let name = field.ident.map(|ident| ident.name)
.unwrap_or_else(|| Symbol::intern(&index.to_string()));
this.create_def(field.id,
DefPathData::Field(name.as_str()),
REGULAR_SPACE);
REGULAR_SPACE,
field.span);
}

if let Some(ref expr) = v.node.disr_expr {
Expand All @@ -152,13 +156,17 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
if !struct_def.is_struct() {
this.create_def(struct_def.id(),
DefPathData::StructCtor,
REGULAR_SPACE);
REGULAR_SPACE,
i.span);
}

for (index, field) in struct_def.fields().iter().enumerate() {
let name = field.ident.map(|ident| ident.name)
.unwrap_or_else(|| Symbol::intern(&index.to_string()));
this.create_def(field.id, DefPathData::Field(name.as_str()), REGULAR_SPACE);
this.create_def(field.id,
DefPathData::Field(name.as_str()),
REGULAR_SPACE,
field.span);
}
}
_ => {}
Expand All @@ -168,14 +176,15 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
}

fn visit_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId, _nested: bool) {
self.create_def(id, DefPathData::Misc, ITEM_LIKE_SPACE);
self.create_def(id, DefPathData::Misc, ITEM_LIKE_SPACE, use_tree.span);
visit::walk_use_tree(self, use_tree, id);
}

fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) {
let def = self.create_def(foreign_item.id,
DefPathData::ValueNs(foreign_item.ident.name.as_str()),
REGULAR_SPACE);
REGULAR_SPACE,
foreign_item.span);

self.with_parent(def, |this| {
visit::walk_foreign_item(this, foreign_item);
Expand All @@ -188,14 +197,16 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
self.create_def(
lifetime_def.lifetime.id,
DefPathData::LifetimeDef(lifetime_def.lifetime.ident.name.as_str()),
REGULAR_SPACE
REGULAR_SPACE,
lifetime_def.lifetime.span
);
}
GenericParam::Type(ref ty_param) => {
self.create_def(
ty_param.id,
DefPathData::TypeParam(ty_param.ident.name.as_str()),
REGULAR_SPACE
REGULAR_SPACE,
ty_param.span
);
}
}
Expand All @@ -211,7 +222,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
TraitItemKind::Macro(..) => return self.visit_macro_invoc(ti.id, false),
};

let def = self.create_def(ti.id, def_data, ITEM_LIKE_SPACE);
let def = self.create_def(ti.id, def_data, ITEM_LIKE_SPACE, ti.span);
self.with_parent(def, |this| {
if let TraitItemKind::Const(_, Some(ref expr)) = ti.node {
this.visit_const_expr(expr);
Expand All @@ -229,7 +240,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id, false),
};

let def = self.create_def(ii.id, def_data, ITEM_LIKE_SPACE);
let def = self.create_def(ii.id, def_data, ITEM_LIKE_SPACE, ii.span);
self.with_parent(def, |this| {
if let ImplItemKind::Const(_, ref expr) = ii.node {
this.visit_const_expr(expr);
Expand All @@ -255,7 +266,8 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
ExprKind::Closure(..) => {
let def = self.create_def(expr.id,
DefPathData::ClosureExpr,
REGULAR_SPACE);
REGULAR_SPACE,
expr.span);
self.parent_def = Some(def);
}
_ => {}
Expand All @@ -270,7 +282,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
TyKind::Mac(..) => return self.visit_macro_invoc(ty.id, false),
TyKind::Array(_, ref length) => self.visit_const_expr(length),
TyKind::ImplTrait(..) => {
self.create_def(ty.id, DefPathData::ImplTrait, REGULAR_SPACE);
self.create_def(ty.id, DefPathData::ImplTrait, REGULAR_SPACE, ty.span);
}
TyKind::Typeof(ref expr) => self.visit_const_expr(expr),
_ => {}
Expand Down
31 changes: 29 additions & 2 deletions src/librustc/hir/map/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use std::hash::Hash;
use syntax::ast;
use syntax::ext::hygiene::Mark;
use syntax::symbol::{Symbol, InternedString};
use syntax_pos::{Span, DUMMY_SP};
use util::nodemap::NodeMap;

/// The DefPathTable maps DefIndexes to DefKeys and vice versa.
Expand Down Expand Up @@ -159,6 +160,7 @@ pub struct Definitions {
macro_def_scopes: FxHashMap<Mark, DefId>,
expansions: FxHashMap<DefIndex, Mark>,
next_disambiguator: FxHashMap<(DefIndex, DefPathData), u32>,
def_index_to_span: FxHashMap<DefIndex, Span>,
}

// Unfortunately we have to provide a manual impl of Clone because of the
Expand All @@ -176,6 +178,7 @@ impl Clone for Definitions {
macro_def_scopes: self.macro_def_scopes.clone(),
expansions: self.expansions.clone(),
next_disambiguator: self.next_disambiguator.clone(),
def_index_to_span: self.def_index_to_span.clone(),
}
}
}
Expand Down Expand Up @@ -410,6 +413,7 @@ impl Definitions {
macro_def_scopes: FxHashMap(),
expansions: FxHashMap(),
next_disambiguator: FxHashMap(),
def_index_to_span: FxHashMap(),
}
}

Expand Down Expand Up @@ -493,6 +497,22 @@ impl Definitions {
self.node_to_hir_id[node_id]
}

/// Retrieve the span of the given `DefId` if `DefId` is in the local crate, the span exists and
/// it's not DUMMY_SP
#[inline]
pub fn opt_span(&self, def_id: DefId) -> Option<Span> {
if def_id.krate == LOCAL_CRATE {
let span = self.def_index_to_span.get(&def_id.index).cloned().unwrap_or(DUMMY_SP);
if span != DUMMY_SP {
Some(span)
} else {
None
}
} else {
None
}
}

/// Add a definition with a parent definition.
pub fn create_root_def(&mut self,
crate_name: &str,
Expand Down Expand Up @@ -530,7 +550,8 @@ impl Definitions {
node_id: ast::NodeId,
data: DefPathData,
address_space: DefIndexAddressSpace,
expansion: Mark)
expansion: Mark,
span: Span)
-> DefIndex {
debug!("create_def_with_parent(parent={:?}, node_id={:?}, data={:?})",
parent, node_id, data);
Expand Down Expand Up @@ -583,6 +604,11 @@ impl Definitions {
self.expansions.insert(index, expansion);
}

// The span is added if it isn't DUMMY_SP
if span != DUMMY_SP {
self.def_index_to_span.insert(index, span);
}

index
}

Expand Down Expand Up @@ -692,7 +718,8 @@ macro_rules! define_global_metadata_kind {
ast::DUMMY_NODE_ID,
DefPathData::GlobalMetaData(instance.name().as_str()),
GLOBAL_MD_ADDRESS_SPACE,
Mark::root()
Mark::root(),
DUMMY_SP
);

// Make sure calling def_index does not crash.
Expand Down
Loading

0 comments on commit 87344aa

Please sign in to comment.