Skip to content

Commit 825c536

Browse files
eddybnikomatsakis
authored andcommitted
Don't leak the compiler's internal representation of scopes in error messages.
1 parent 544d7e2 commit 825c536

File tree

3 files changed

+99
-15
lines changed

3 files changed

+99
-15
lines changed

src/librustc/infer/error_reporting.rs

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,22 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
114114
}
115115
}
116116

117+
fn trait_item_scope_tag(item: &hir::TraitItem) -> &'static str {
118+
match item.node {
119+
hir::MethodTraitItem(..) => "method body",
120+
hir::ConstTraitItem(..) |
121+
hir::TypeTraitItem(..) => "associated item"
122+
}
123+
}
124+
125+
fn impl_item_scope_tag(item: &hir::ImplItem) -> &'static str {
126+
match item.node {
127+
hir::ImplItemKind::Method(..) => "method body",
128+
hir::ImplItemKind::Const(..) |
129+
hir::ImplItemKind::Type(_) => "associated item"
130+
}
131+
}
132+
117133
fn explain_span<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
118134
heading: &str, span: Span)
119135
-> (String, Option<Span>) {
@@ -149,6 +165,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
149165
},
150166
Some(ast_map::NodeStmt(_)) => "statement",
151167
Some(ast_map::NodeItem(it)) => item_scope_tag(&it),
168+
Some(ast_map::NodeTraitItem(it)) => trait_item_scope_tag(&it),
169+
Some(ast_map::NodeImplItem(it)) => impl_item_scope_tag(&it),
152170
Some(_) | None => {
153171
err.span_note(span, &unknown_scope());
154172
return;
@@ -187,23 +205,31 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
187205
}
188206
};
189207

190-
match self.map.find(fr.scope.node_id(&self.region_maps)) {
191-
Some(ast_map::NodeBlock(ref blk)) => {
192-
let (msg, opt_span) = explain_span(self, "block", blk.span);
193-
(format!("{} {}", prefix, msg), opt_span)
194-
}
195-
Some(ast_map::NodeItem(it)) => {
196-
let tag = item_scope_tag(&it);
197-
let (msg, opt_span) = explain_span(self, tag, it.span);
198-
(format!("{} {}", prefix, msg), opt_span)
208+
let node = fr.scope.node_id(&self.region_maps);
209+
let unknown;
210+
let tag = match self.map.find(node) {
211+
Some(ast_map::NodeBlock(_)) |
212+
Some(ast_map::NodeExpr(_)) => "body",
213+
Some(ast_map::NodeItem(it)) => item_scope_tag(&it),
214+
Some(ast_map::NodeTraitItem(it)) => trait_item_scope_tag(&it),
215+
Some(ast_map::NodeImplItem(it)) => impl_item_scope_tag(&it),
216+
217+
// this really should not happen, but it does:
218+
// FIXME(#27942)
219+
Some(_) => {
220+
unknown = format!("unexpected node ({}) for scope {:?}. \
221+
Please report a bug.",
222+
self.map.node_to_string(node), fr.scope);
223+
&unknown
199224
}
200-
Some(_) | None => {
201-
// this really should not happen, but it does:
202-
// FIXME(#27942)
203-
(format!("{} unknown free region bounded by scope {:?}",
204-
prefix, fr.scope), None)
225+
None => {
226+
unknown = format!("unknown node for scope {:?}. \
227+
Please report a bug.", fr.scope);
228+
&unknown
205229
}
206-
}
230+
};
231+
let (msg, opt_span) = explain_span(self, tag, self.map.span(node));
232+
(format!("{} {}", prefix, msg), opt_span)
207233
}
208234

209235
ty::ReStatic => ("the static lifetime".to_owned(), None),

src/test/compile-fail/issue-27942.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
pub trait Resources<'a> {}
12+
13+
pub trait Buffer<'a, R: Resources<'a>> {
14+
fn select(&self) -> BufferViewHandle<R>;
15+
//~^ ERROR mismatched types
16+
//~| lifetime mismatch
17+
//~| NOTE expected type `Resources<'_>`
18+
//~| NOTE found type `Resources<'a>`
19+
//~| NOTE the lifetime 'a as defined on the method body at 14:4...
20+
//~| NOTE ...does not necessarily outlive the anonymous lifetime #1 defined on the method body
21+
//~| ERROR mismatched types
22+
//~| lifetime mismatch
23+
//~| NOTE expected type `Resources<'_>`
24+
//~| NOTE found type `Resources<'a>`
25+
//~| NOTE the anonymous lifetime #1 defined on the method body at 14:4...
26+
//~| NOTE ...does not necessarily outlive the lifetime 'a as defined on the method body
27+
}
28+
29+
pub struct BufferViewHandle<'a, R: 'a+Resources<'a>>(&'a R);
30+
31+
fn main() {}

src/test/compile-fail/issue-37884.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
struct RepeatMut<'a, T>(T, &'a ());
12+
13+
impl<'a, T: 'a> Iterator for RepeatMut<'a, T> {
14+
type Item = &'a mut T;
15+
fn next(&'a mut self) -> Option<Self::Item>
16+
//~^ ERROR method not compatible with trait
17+
//~| lifetime mismatch
18+
//~| NOTE expected type `fn(&mut RepeatMut<'a, T>) -> std::option::Option<&mut T>`
19+
//~| NOTE found type `fn(&'a mut RepeatMut<'a, T>) -> std::option::Option<&mut T>`
20+
{
21+
//~^ NOTE the anonymous lifetime #1 defined on the body
22+
//~| NOTE ...does not necessarily outlive the lifetime 'a as defined on the body
23+
Some(&mut self.0)
24+
}
25+
}
26+
27+
fn main() {}

0 commit comments

Comments
 (0)