Skip to content

Commit bb04da4

Browse files
committed
Don't leak the compiler's internal representation of scopes in error messages.
1 parent 4682271 commit bb04da4

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
@@ -113,6 +113,22 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
113113
}
114114
}
115115

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

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

208234
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)