diff options
| author | Manish Goregaokar <manishsmail@gmail.com> | 2016-09-04 07:52:36 +0530 |
|---|---|---|
| committer | Manish Goregaokar <manishsmail@gmail.com> | 2016-09-04 21:00:59 +0800 |
| commit | 43440a4a6e3f2bf38288ed7cb03962ea9e5c8a11 (patch) | |
| tree | 28e3b7610c44bfb3aa4e1a072793b26d8bd4d835 /src | |
| parent | 8d6464998220dd69a0f61c6e41e5aeb6e35328a0 (diff) | |
| parent | 059094f3f264a683e624ae57b475264b5ce8511c (diff) | |
Rollup merge of #36212 - razielgn:updated-e0493-to-new-format, r=jonathandturner
Updated e0493 to new format (+ bonus). Part of #35233. Fixes #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. :)
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_mir/transform/qualify_consts.rs | 33 | ||||
| -rw-r--r-- | src/test/ui/span/E0493.rs (renamed from src/test/compile-fail/E0493.rs) | 10 | ||||
| -rw-r--r-- | src/test/ui/span/E0493.stderr | 11 |
3 files changed, 53 insertions, 1 deletions
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 6c6a5f7fc74..02a643b76d5 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -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; @@ -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 { diff --git a/src/test/compile-fail/E0493.rs b/src/test/ui/span/E0493.rs index 689f469533d..ea4526b70f6 100644 --- a/src/test/compile-fail/E0493.rs +++ b/src/test/ui/span/E0493.rs @@ -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() { } diff --git a/src/test/ui/span/E0493.stderr b/src/test/ui/span/E0493.stderr new file mode 100644 index 00000000000..afcc9a240eb --- /dev/null +++ b/src/test/ui/span/E0493.stderr @@ -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 + |
