Skip to content

Commit e06ce71

Browse files
committed
Auto merge of #38552 - eddyb:bad-blocks, r=arielb1
Don't leak the compiler's internal representation of scopes in error messages. Fixes #37884 (actually fixes #27942, which was made worse by #37412) by handling more node types. Ideally we'd turn the unknown node type situations into ICEs and fix them as they show up in errors. But we might want to backport this patch so I was less aggressive.
2 parents 01677ee + 987f52f commit e06ce71

File tree

3 files changed

+99
-15
lines changed

3 files changed

+99
-15
lines changed

src/librustc/infer/error_reporting.rs

+41-15
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::TraitItemKind::Method(..) => "method body",
119+
hir::TraitItemKind::Const(..) |
120+
hir::TraitItemKind::Type(..) => "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

+31
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

+27
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)