Skip to content

Commit

Permalink
Rollup merge of rust-lang#36212 - razielgn:updated-e0493-to-new-forma…
Browse files Browse the repository at this point in the history
…t, 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. :)
  • Loading branch information
Manishearth committed Sep 4, 2016
2 parents 8d64649 + 059094f commit 43440a4
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 1 deletion.
33 changes: 33 additions & 0 deletions src/librustc_mir/transform/qualify_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use rustc_data_structures::bitvec::BitVector;
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
use rustc::dep_graph::DepNode;
use rustc::hir;
use rustc::hir::map as hir_map;
use rustc::hir::def_id::DefId;
use rustc::hir::intravisit::FnKind;
use rustc::hir::map::blocks::FnLikeNode;
Expand Down Expand Up @@ -252,14 +253,46 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {

let mut err =
struct_span_err!(self.tcx.sess, self.span, E0493, "{}", msg);

if self.mode != Mode::Const {
help!(&mut err,
"in Nightly builds, add `#![feature(drop_types_in_const)]` \
to the crate attributes to enable");
} else {
self.find_drop_implementation_method_span()
.map(|span| err.span_label(span, &format!("destructor defined here")));

err.span_label(self.span, &format!("constants cannot have destructors"));
}

err.emit();
}

fn find_drop_implementation_method_span(&self) -> Option<Span> {
self.tcx.lang_items
.drop_trait()
.and_then(|drop_trait_id| {
let mut span = None;

self.tcx
.lookup_trait_def(drop_trait_id)
.for_each_relevant_impl(self.tcx, self.mir.return_ty, |impl_did| {
self.tcx.map
.as_local_node_id(impl_did)
.and_then(|impl_node_id| self.tcx.map.find(impl_node_id))
.map(|node| {
if let hir_map::NodeItem(item) = node {
if let hir::ItemImpl(_, _, _, _, _, ref methods) = item.node {
span = methods.first().map(|method| method.span);
}
}
});
});

span
})
}

/// Check if an Lvalue with the current qualifications could
/// be consumed, by either an operand or a Deref projection.
fn try_consume(&mut self) -> bool {
Expand Down
10 changes: 9 additions & 1 deletion src/test/compile-fail/E0493.rs → src/test/ui/span/E0493.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,15 @@ impl Drop for Foo {
fn drop(&mut self) {}
}

const F : Foo = Foo { a : 0 }; //~ ERROR E0493
struct Bar {
a: u32
}

impl Drop for Bar {
fn drop(&mut self) {}
}

const F : Foo = Foo { a : 0 };

fn main() {
}
11 changes: 11 additions & 0 deletions src/test/ui/span/E0493.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error[E0493]: constants are not allowed to have destructors
--> $DIR/E0493.rs:27:17
|
16 | fn drop(&mut self) {}
| --------------------- destructor defined here
...
27 | const F : Foo = Foo { a : 0 };
| ^^^^^^^^^^^^^ constants cannot have destructors

error: aborting due to previous error

0 comments on commit 43440a4

Please sign in to comment.