Skip to content

Commit 43440a4

Browse files
committed
Rollup merge of rust-lang#36212 - razielgn:updated-e0493-to-new-format, r=jonathandturner
Updated e0493 to new format (+ bonus). Part of rust-lang#35233. Fixes rust-lang#35999. r? @jonathandturner I'm not satisfied with the bonus part, there has to be an easier way to reach into the `Drop`'s span implementation. I'm all ears. :)
2 parents 8d64649 + 059094f commit 43440a4

File tree

3 files changed

+53
-1
lines changed

3 files changed

+53
-1
lines changed

src/librustc_mir/transform/qualify_consts.rs

+33
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use rustc_data_structures::bitvec::BitVector;
1818
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
1919
use rustc::dep_graph::DepNode;
2020
use rustc::hir;
21+
use rustc::hir::map as hir_map;
2122
use rustc::hir::def_id::DefId;
2223
use rustc::hir::intravisit::FnKind;
2324
use rustc::hir::map::blocks::FnLikeNode;
@@ -252,14 +253,46 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
252253

253254
let mut err =
254255
struct_span_err!(self.tcx.sess, self.span, E0493, "{}", msg);
256+
255257
if self.mode != Mode::Const {
256258
help!(&mut err,
257259
"in Nightly builds, add `#![feature(drop_types_in_const)]` \
258260
to the crate attributes to enable");
261+
} else {
262+
self.find_drop_implementation_method_span()
263+
.map(|span| err.span_label(span, &format!("destructor defined here")));
264+
265+
err.span_label(self.span, &format!("constants cannot have destructors"));
259266
}
267+
260268
err.emit();
261269
}
262270

271+
fn find_drop_implementation_method_span(&self) -> Option<Span> {
272+
self.tcx.lang_items
273+
.drop_trait()
274+
.and_then(|drop_trait_id| {
275+
let mut span = None;
276+
277+
self.tcx
278+
.lookup_trait_def(drop_trait_id)
279+
.for_each_relevant_impl(self.tcx, self.mir.return_ty, |impl_did| {
280+
self.tcx.map
281+
.as_local_node_id(impl_did)
282+
.and_then(|impl_node_id| self.tcx.map.find(impl_node_id))
283+
.map(|node| {
284+
if let hir_map::NodeItem(item) = node {
285+
if let hir::ItemImpl(_, _, _, _, _, ref methods) = item.node {
286+
span = methods.first().map(|method| method.span);
287+
}
288+
}
289+
});
290+
});
291+
292+
span
293+
})
294+
}
295+
263296
/// Check if an Lvalue with the current qualifications could
264297
/// be consumed, by either an operand or a Deref projection.
265298
fn try_consume(&mut self) -> bool {

src/test/compile-fail/E0493.rs renamed to src/test/ui/span/E0493.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,15 @@ impl Drop for Foo {
1616
fn drop(&mut self) {}
1717
}
1818

19-
const F : Foo = Foo { a : 0 }; //~ ERROR E0493
19+
struct Bar {
20+
a: u32
21+
}
22+
23+
impl Drop for Bar {
24+
fn drop(&mut self) {}
25+
}
26+
27+
const F : Foo = Foo { a : 0 };
2028

2129
fn main() {
2230
}

src/test/ui/span/E0493.stderr

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0493]: constants are not allowed to have destructors
2+
--> $DIR/E0493.rs:27:17
3+
|
4+
16 | fn drop(&mut self) {}
5+
| --------------------- destructor defined here
6+
...
7+
27 | const F : Foo = Foo { a : 0 };
8+
| ^^^^^^^^^^^^^ constants cannot have destructors
9+
10+
error: aborting due to previous error
11+

0 commit comments

Comments
 (0)