diff options
| author | Eduard Burtescu <edy.burt@gmail.com> | 2016-05-05 08:11:28 +0300 |
|---|---|---|
| committer | Eduard Burtescu <edy.burt@gmail.com> | 2016-05-07 19:14:33 +0300 |
| commit | ed66fe48e94df2cd0dee5af4afa44d7fb50cb0cf (patch) | |
| tree | 0a875e37191033361b5c3a04aa8494551157922a /src/librustc_mir | |
| parent | 4f5900aefac42cec488a68c041ecd538c04b84fd (diff) | |
| download | rust-ed66fe48e94df2cd0dee5af4afa44d7fb50cb0cf.tar.gz rust-ed66fe48e94df2cd0dee5af4afa44d7fb50cb0cf.zip | |
Implement RFC 1440 "Allow Drop types in statics/const functions".
Diffstat (limited to 'src/librustc_mir')
| -rw-r--r-- | src/librustc_mir/diagnostics.rs | 2 | ||||
| -rw-r--r-- | src/librustc_mir/transform/qualify_consts.rs | 37 |
2 files changed, 33 insertions, 6 deletions
diff --git a/src/librustc_mir/diagnostics.rs b/src/librustc_mir/diagnostics.rs index 30d3a39e473..65d51d20528 100644 --- a/src/librustc_mir/diagnostics.rs +++ b/src/librustc_mir/diagnostics.rs @@ -345,7 +345,7 @@ impl Drop for Foo { const F : Foo = Foo { a : 0 }; // error: constants are not allowed to have destructors static S : Foo = Foo { a : 0 }; -// error: statics are not allowed to have destructors +// error: destructors in statics are an unstable feature ``` To solve this issue, please use a type which does allow the usage of type with diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 7728d43774f..90823528973 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -222,13 +222,40 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx> { } /// Check for NEEDS_DROP (from an ADT or const fn call) and - /// error, unless we're in a function. + /// error, unless we're in a function, or the feature-gate + /// for globals with destructors is enabled. fn deny_drop(&self) { - if self.mode != Mode::Fn && self.qualif.intersects(Qualif::NEEDS_DROP) { - span_err!(self.tcx.sess, self.span, E0493, - "{}s are not allowed to have destructors", - self.mode); + if self.mode == Mode::Fn || !self.qualif.intersects(Qualif::NEEDS_DROP) { + return; + } + + // Static and const fn's allow destructors, but they're feature-gated. + let msg = if self.mode != Mode::Const { + // Feature-gate for globals with destructors is enabled. + if self.tcx.sess.features.borrow().drop_types_in_const { + return; + } + + // This comes from a macro that has #[allow_internal_unstable]. + if self.tcx.sess.codemap().span_allows_unstable(self.span) { + return; + } + + format!("destructors in {}s are an unstable feature", + self.mode) + } else { + format!("{}s are not allowed to have destructors", + self.mode) + }; + + 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"); } + err.emit(); } /// Check if an Lvalue with the current qualifications could |
