Skip to content

Commit 87344aa

Browse files
committed
Auto merge of #47574 - zilbuz:issue-14844, r=nikomatsakis
Show the used type variable when issuing a "can't use type parameters from outer function" error message Fix #14844 r? @estebank
2 parents 948e3a3 + 0e68bb9 commit 87344aa

File tree

13 files changed

+309
-43
lines changed

13 files changed

+309
-43
lines changed

src/librustc/hir/lowering.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,8 @@ impl<'a> LoweringContext<'a> {
571571
def_node_id,
572572
DefPathData::LifetimeDef(name.as_str()),
573573
DefIndexAddressSpace::High,
574-
Mark::root()
574+
Mark::root(),
575+
span
575576
);
576577

577578
hir::GenericParam::Lifetime(hir::LifetimeDef {
@@ -1003,7 +1004,8 @@ impl<'a> LoweringContext<'a> {
10031004
def_node_id,
10041005
DefPathData::ImplTrait,
10051006
DefIndexAddressSpace::High,
1006-
Mark::root()
1007+
Mark::root(),
1008+
span
10071009
);
10081010

10091011
let hir_bounds = self.lower_bounds(bounds, itctx);
@@ -1150,7 +1152,8 @@ impl<'a> LoweringContext<'a> {
11501152
def_node_id,
11511153
DefPathData::LifetimeDef(name.name().as_str()),
11521154
DefIndexAddressSpace::High,
1153-
Mark::root()
1155+
Mark::root(),
1156+
lifetime.span
11541157
);
11551158
let def_lifetime = hir::Lifetime {
11561159
id: def_node_id,

src/librustc/hir/map/def_collector.rs

+28-16
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use syntax::visit;
1818
use syntax::symbol::keywords;
1919
use syntax::symbol::Symbol;
2020
use syntax::parse::token::{self, Token};
21+
use syntax_pos::Span;
2122

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

@@ -57,12 +58,13 @@ impl<'a> DefCollector<'a> {
5758
fn create_def(&mut self,
5859
node_id: NodeId,
5960
data: DefPathData,
60-
address_space: DefIndexAddressSpace)
61+
address_space: DefIndexAddressSpace,
62+
span: Span)
6163
-> DefIndex {
6264
let parent_def = self.parent_def.unwrap();
6365
debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def);
6466
self.definitions
65-
.create_def_with_parent(parent_def, node_id, data, address_space, self.expansion)
67+
.create_def_with_parent(parent_def, node_id, data, address_space, self.expansion, span)
6668
}
6769

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

86-
self.create_def(expr.id, DefPathData::Initializer, REGULAR_SPACE);
88+
self.create_def(expr.id, DefPathData::Initializer, REGULAR_SPACE, expr.span);
8789
}
8890

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

127129
self.with_parent(def, |this| {
128130
match i.node {
@@ -131,14 +133,16 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
131133
let variant_def_index =
132134
this.create_def(v.node.data.id(),
133135
DefPathData::EnumVariant(v.node.name.name.as_str()),
134-
REGULAR_SPACE);
136+
REGULAR_SPACE,
137+
v.span);
135138
this.with_parent(variant_def_index, |this| {
136139
for (index, field) in v.node.data.fields().iter().enumerate() {
137140
let name = field.ident.map(|ident| ident.name)
138141
.unwrap_or_else(|| Symbol::intern(&index.to_string()));
139142
this.create_def(field.id,
140143
DefPathData::Field(name.as_str()),
141-
REGULAR_SPACE);
144+
REGULAR_SPACE,
145+
field.span);
142146
}
143147

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

158163
for (index, field) in struct_def.fields().iter().enumerate() {
159164
let name = field.ident.map(|ident| ident.name)
160165
.unwrap_or_else(|| Symbol::intern(&index.to_string()));
161-
this.create_def(field.id, DefPathData::Field(name.as_str()), REGULAR_SPACE);
166+
this.create_def(field.id,
167+
DefPathData::Field(name.as_str()),
168+
REGULAR_SPACE,
169+
field.span);
162170
}
163171
}
164172
_ => {}
@@ -168,14 +176,15 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
168176
}
169177

170178
fn visit_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId, _nested: bool) {
171-
self.create_def(id, DefPathData::Misc, ITEM_LIKE_SPACE);
179+
self.create_def(id, DefPathData::Misc, ITEM_LIKE_SPACE, use_tree.span);
172180
visit::walk_use_tree(self, use_tree, id);
173181
}
174182

175183
fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) {
176184
let def = self.create_def(foreign_item.id,
177185
DefPathData::ValueNs(foreign_item.ident.name.as_str()),
178-
REGULAR_SPACE);
186+
REGULAR_SPACE,
187+
foreign_item.span);
179188

180189
self.with_parent(def, |this| {
181190
visit::walk_foreign_item(this, foreign_item);
@@ -188,14 +197,16 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
188197
self.create_def(
189198
lifetime_def.lifetime.id,
190199
DefPathData::LifetimeDef(lifetime_def.lifetime.ident.name.as_str()),
191-
REGULAR_SPACE
200+
REGULAR_SPACE,
201+
lifetime_def.lifetime.span
192202
);
193203
}
194204
GenericParam::Type(ref ty_param) => {
195205
self.create_def(
196206
ty_param.id,
197207
DefPathData::TypeParam(ty_param.ident.name.as_str()),
198-
REGULAR_SPACE
208+
REGULAR_SPACE,
209+
ty_param.span
199210
);
200211
}
201212
}
@@ -211,7 +222,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
211222
TraitItemKind::Macro(..) => return self.visit_macro_invoc(ti.id, false),
212223
};
213224

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

232-
let def = self.create_def(ii.id, def_data, ITEM_LIKE_SPACE);
243+
let def = self.create_def(ii.id, def_data, ITEM_LIKE_SPACE, ii.span);
233244
self.with_parent(def, |this| {
234245
if let ImplItemKind::Const(_, ref expr) = ii.node {
235246
this.visit_const_expr(expr);
@@ -255,7 +266,8 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
255266
ExprKind::Closure(..) => {
256267
let def = self.create_def(expr.id,
257268
DefPathData::ClosureExpr,
258-
REGULAR_SPACE);
269+
REGULAR_SPACE,
270+
expr.span);
259271
self.parent_def = Some(def);
260272
}
261273
_ => {}
@@ -270,7 +282,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
270282
TyKind::Mac(..) => return self.visit_macro_invoc(ty.id, false),
271283
TyKind::Array(_, ref length) => self.visit_const_expr(length),
272284
TyKind::ImplTrait(..) => {
273-
self.create_def(ty.id, DefPathData::ImplTrait, REGULAR_SPACE);
285+
self.create_def(ty.id, DefPathData::ImplTrait, REGULAR_SPACE, ty.span);
274286
}
275287
TyKind::Typeof(ref expr) => self.visit_const_expr(expr),
276288
_ => {}

src/librustc/hir/map/definitions.rs

+29-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use std::hash::Hash;
2828
use syntax::ast;
2929
use syntax::ext::hygiene::Mark;
3030
use syntax::symbol::{Symbol, InternedString};
31+
use syntax_pos::{Span, DUMMY_SP};
3132
use util::nodemap::NodeMap;
3233

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

164166
// Unfortunately we have to provide a manual impl of Clone because of the
@@ -176,6 +178,7 @@ impl Clone for Definitions {
176178
macro_def_scopes: self.macro_def_scopes.clone(),
177179
expansions: self.expansions.clone(),
178180
next_disambiguator: self.next_disambiguator.clone(),
181+
def_index_to_span: self.def_index_to_span.clone(),
179182
}
180183
}
181184
}
@@ -410,6 +413,7 @@ impl Definitions {
410413
macro_def_scopes: FxHashMap(),
411414
expansions: FxHashMap(),
412415
next_disambiguator: FxHashMap(),
416+
def_index_to_span: FxHashMap(),
413417
}
414418
}
415419

@@ -493,6 +497,22 @@ impl Definitions {
493497
self.node_to_hir_id[node_id]
494498
}
495499

500+
/// Retrieve the span of the given `DefId` if `DefId` is in the local crate, the span exists and
501+
/// it's not DUMMY_SP
502+
#[inline]
503+
pub fn opt_span(&self, def_id: DefId) -> Option<Span> {
504+
if def_id.krate == LOCAL_CRATE {
505+
let span = self.def_index_to_span.get(&def_id.index).cloned().unwrap_or(DUMMY_SP);
506+
if span != DUMMY_SP {
507+
Some(span)
508+
} else {
509+
None
510+
}
511+
} else {
512+
None
513+
}
514+
}
515+
496516
/// Add a definition with a parent definition.
497517
pub fn create_root_def(&mut self,
498518
crate_name: &str,
@@ -530,7 +550,8 @@ impl Definitions {
530550
node_id: ast::NodeId,
531551
data: DefPathData,
532552
address_space: DefIndexAddressSpace,
533-
expansion: Mark)
553+
expansion: Mark,
554+
span: Span)
534555
-> DefIndex {
535556
debug!("create_def_with_parent(parent={:?}, node_id={:?}, data={:?})",
536557
parent, node_id, data);
@@ -583,6 +604,11 @@ impl Definitions {
583604
self.expansions.insert(index, expansion);
584605
}
585606

607+
// The span is added if it isn't DUMMY_SP
608+
if span != DUMMY_SP {
609+
self.def_index_to_span.insert(index, span);
610+
}
611+
586612
index
587613
}
588614

@@ -692,7 +718,8 @@ macro_rules! define_global_metadata_kind {
692718
ast::DUMMY_NODE_ID,
693719
DefPathData::GlobalMetaData(instance.name().as_str()),
694720
GLOBAL_MD_ADDRESS_SPACE,
695-
Mark::root()
721+
Mark::root(),
722+
DUMMY_SP
696723
);
697724

698725
// Make sure calling def_index does not crash.

0 commit comments

Comments
 (0)