Skip to content

Commit 32cfdfc

Browse files
committed
---
yaml --- r: 227651 b: refs/heads/try c: 6061707 h: refs/heads/master i: 227649: b87adee 227647: 7ab28f8 v: v3
1 parent 2766aa3 commit 32cfdfc

File tree

7 files changed

+332
-368
lines changed

7 files changed

+332
-368
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: aca2057ed5fb7af3f8905b2bc01f72fa001c35c8
33
refs/heads/snap-stage3: 1af31d4974e33027a68126fa5a5a3c2c6491824f
4-
refs/heads/try: 96ad4a486381497da00ad12413bfc0fbac201189
4+
refs/heads/try: 6061707348ada3245de306c9d38d07250293e58e
55
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
66
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
77
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try/src/librustc/middle/infer/error_reporting.rs

Lines changed: 124 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ use std::collections::HashSet;
7575
use ast_map;
7676
use middle::def;
7777
use middle::infer;
78+
use middle::region;
7879
use middle::subst;
7980
use middle::ty::{self, Ty};
8081
use middle::ty::{Region, ReFree};
@@ -84,16 +85,135 @@ use std::string::String;
8485
use syntax::ast;
8586
use syntax::ast_util::name_to_dummy_lifetime;
8687
use syntax::owned_slice::OwnedSlice;
87-
use syntax::codemap;
88+
use syntax::codemap::{Pos, Span};
8889
use syntax::parse::token;
8990
use syntax::print::pprust;
9091
use syntax::ptr::P;
91-
use util::ppaux::note_and_explain_region;
9292

9393
// Note: only import UserString, not Repr, since user-facing error
9494
// messages shouldn't include debug serializations.
9595
use util::ppaux::UserString;
9696

97+
pub fn note_and_explain_region(tcx: &ty::ctxt,
98+
prefix: &str,
99+
region: ty::Region,
100+
suffix: &str) {
101+
fn item_scope_tag(item: &ast::Item) -> &'static str {
102+
match item.node {
103+
ast::ItemImpl(..) => "impl",
104+
ast::ItemStruct(..) => "struct",
105+
ast::ItemEnum(..) => "enum",
106+
ast::ItemTrait(..) => "trait",
107+
ast::ItemFn(..) => "function body",
108+
_ => "item"
109+
}
110+
}
111+
112+
fn explain_span(tcx: &ty::ctxt, heading: &str, span: Span)
113+
-> (String, Option<Span>) {
114+
let lo = tcx.sess.codemap().lookup_char_pos_adj(span.lo);
115+
(format!("the {} at {}:{}", heading, lo.line, lo.col.to_usize()),
116+
Some(span))
117+
}
118+
119+
let (description, span) = match region {
120+
ty::ReScope(scope) => {
121+
let new_string;
122+
let unknown_scope = || {
123+
format!("{}unknown scope: {:?}{}. Please report a bug.",
124+
prefix, scope, suffix)
125+
};
126+
let span = match scope.span(&tcx.map) {
127+
Some(s) => s,
128+
None => return tcx.sess.note(&unknown_scope())
129+
};
130+
let tag = match tcx.map.find(scope.node_id()) {
131+
Some(ast_map::NodeBlock(_)) => "block",
132+
Some(ast_map::NodeExpr(expr)) => match expr.node {
133+
ast::ExprCall(..) => "call",
134+
ast::ExprMethodCall(..) => "method call",
135+
ast::ExprMatch(_, _, ast::MatchSource::IfLetDesugar { .. }) => "if let",
136+
ast::ExprMatch(_, _, ast::MatchSource::WhileLetDesugar) => "while let",
137+
ast::ExprMatch(_, _, ast::MatchSource::ForLoopDesugar) => "for",
138+
ast::ExprMatch(..) => "match",
139+
_ => "expression",
140+
},
141+
Some(ast_map::NodeStmt(_)) => "statement",
142+
Some(ast_map::NodeItem(it)) => item_scope_tag(&*it),
143+
Some(_) | None => {
144+
return tcx.sess.span_note(span, &unknown_scope());
145+
}
146+
};
147+
let scope_decorated_tag = match scope {
148+
region::CodeExtent::Misc(_) => tag,
149+
region::CodeExtent::ParameterScope { .. } => {
150+
"scope of parameters for function"
151+
}
152+
region::CodeExtent::DestructionScope(_) => {
153+
new_string = format!("destruction scope surrounding {}", tag);
154+
&new_string[..]
155+
}
156+
region::CodeExtent::Remainder(r) => {
157+
new_string = format!("block suffix following statement {}",
158+
r.first_statement_index);
159+
&new_string[..]
160+
}
161+
};
162+
explain_span(tcx, scope_decorated_tag, span)
163+
}
164+
165+
ty::ReFree(ref fr) => {
166+
let prefix = match fr.bound_region {
167+
ty::BrAnon(idx) => {
168+
format!("the anonymous lifetime #{} defined on", idx + 1)
169+
}
170+
ty::BrFresh(_) => "an anonymous lifetime defined on".to_owned(),
171+
_ => {
172+
format!("the lifetime {} as defined on",
173+
fr.bound_region.user_string(tcx))
174+
}
175+
};
176+
177+
match tcx.map.find(fr.scope.node_id) {
178+
Some(ast_map::NodeBlock(ref blk)) => {
179+
let (msg, opt_span) = explain_span(tcx, "block", blk.span);
180+
(format!("{} {}", prefix, msg), opt_span)
181+
}
182+
Some(ast_map::NodeItem(it)) => {
183+
let tag = item_scope_tag(&*it);
184+
let (msg, opt_span) = explain_span(tcx, tag, it.span);
185+
(format!("{} {}", prefix, msg), opt_span)
186+
}
187+
Some(_) | None => {
188+
// this really should not happen
189+
(format!("{} unknown free region bounded by scope {:?}",
190+
prefix, fr.scope), None)
191+
}
192+
}
193+
}
194+
195+
ty::ReStatic => ("the static lifetime".to_owned(), None),
196+
197+
ty::ReEmpty => ("the empty lifetime".to_owned(), None),
198+
199+
ty::ReEarlyBound(ref data) => {
200+
(format!("{}", token::get_name(data.name)), None)
201+
}
202+
203+
// I believe these cases should not occur (except when debugging,
204+
// perhaps)
205+
ty::ReInfer(_) | ty::ReLateBound(..) => {
206+
(format!("lifetime {:?}", region), None)
207+
}
208+
};
209+
let message = format!("{}{}{}", prefix, description, suffix);
210+
if let Some(span) = span {
211+
tcx.sess.span_note(span, &message);
212+
} else {
213+
tcx.sess.note(&message);
214+
}
215+
}
216+
97217
pub trait ErrorReporting<'tcx> {
98218
fn report_region_errors(&self,
99219
errors: &Vec<RegionResolutionError<'tcx>>);
@@ -161,7 +281,7 @@ trait ErrorReportingHelpers<'tcx> {
161281
ident: ast::Ident,
162282
opt_explicit_self: Option<&ast::ExplicitSelf_>,
163283
generics: &ast::Generics,
164-
span: codemap::Span);
284+
span: Span);
165285
}
166286

167287
impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
@@ -1430,7 +1550,7 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
14301550
ident: ast::Ident,
14311551
opt_explicit_self: Option<&ast::ExplicitSelf_>,
14321552
generics: &ast::Generics,
1433-
span: codemap::Span) {
1553+
span: Span) {
14341554
let suggested_fn = pprust::fun_to_string(decl, unsafety, constness, ident,
14351555
opt_explicit_self, generics);
14361556
let msg = format!("consider using an explicit lifetime \

branches/try/src/librustc/middle/ty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ use middle::def::{self, DefMap, ExportMap};
4848
use middle::dependency_format;
4949
use middle::fast_reject;
5050
use middle::free_region::FreeRegionMap;
51+
use middle::infer::error_reporting::note_and_explain_region;
5152
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
5253
use middle::mem_categorization as mc;
5354
use middle::region;
@@ -61,7 +62,6 @@ use middle::traits;
6162
use middle::ty;
6263
use middle::ty_fold::{self, TypeFoldable, TypeFolder};
6364
use middle::ty_walk::{self, TypeWalker};
64-
use util::ppaux::note_and_explain_region;
6565
use util::ppaux::{Repr, UserString};
6666
use util::common::{memoized, ErrorReported};
6767
use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet};

0 commit comments

Comments
 (0)