diff options
| author | bors <bors@rust-lang.org> | 2017-04-08 14:05:06 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-04-08 14:05:06 +0000 |
| commit | a61011761deeab9e308e6d103b1dc7aaf334f6e3 (patch) | |
| tree | ad81d56b54b321b5afb8f9aa29e593f2cd13b351 | |
| parent | fe39e94d6cd6eba00b3aadf323b3f4d029aad7eb (diff) | |
| parent | c9932b395ada3c367aea5e79645c10657262ea6f (diff) | |
| download | rust-a61011761deeab9e308e6d103b1dc7aaf334f6e3.tar.gz rust-a61011761deeab9e308e6d103b1dc7aaf334f6e3.zip | |
Auto merge of #41055 - Archytaus:compile-fail/const-match-pattern-arm, r=arielb1
Fixed ICEs with pattern matching in const expression
Fixed 2 ICEs with when pattern matching inside a constant expression.
Both of these ICEs now resolve to an appropriate compiler error.
1. ICE was caused by a compiler bug to implement discriminant const qualify.
I removed this intentionally thrown bug and changed it to a FIXME as the unimplemented expression type is handled as a compiler error elsewhere.
2. ICE was caused during a drop check when checking if a variable lifetime outlives the current scope if there was no parent scope .
I've changed it to stop checking if there is no parent scope for the current scope. It is valid syntax for a const variable to be assigned a match expression with no enclosing scope.
The ICE seemed to mainly be used as a defensive check for bugs elsewhere.
Fixes #38199.
Fixes #31577.
Fixes #29093.
Fixes #40012.
| -rw-r--r-- | src/librustc_mir/transform/qualify_consts.rs | 11 | ||||
| -rw-r--r-- | src/librustc_typeck/check/dropck.rs | 9 | ||||
| -rw-r--r-- | src/test/compile-fail/const-match-pattern-arm.rs | 25 |
3 files changed, 33 insertions, 12 deletions
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 9d236bd013c..8eabe92fb98 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -603,7 +603,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { Rvalue::Cast(CastKind::ReifyFnPointer, ..) | Rvalue::Cast(CastKind::UnsafeFnPointer, ..) | Rvalue::Cast(CastKind::ClosureFnPointer, ..) | - Rvalue::Cast(CastKind::Unsize, ..) => {} + Rvalue::Cast(CastKind::Unsize, ..) | + Rvalue::Discriminant(..) => {} Rvalue::Len(_) => { // Static lvalues in consts would have errored already, @@ -721,14 +722,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { } } - Rvalue::Discriminant(..) => { - // FIXME discriminant - self.add(Qualif::NOT_CONST); - if self.mode != Mode::Fn { - bug!("implement discriminant const qualify"); - } - } - Rvalue::Box(_) => { self.add(Qualif::NOT_CONST); if self.mode != Mode::Fn { diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 90d2a15cf08..9f41373dab1 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -278,9 +278,12 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'gcx, 'tcx>( debug!("check_safety_of_destructor_if_necessary typ: {:?} scope: {:?}", typ, scope); - let parent_scope = rcx.tcx.region_maps.opt_encl_scope(scope).unwrap_or_else(|| { - span_bug!(span, "no enclosing scope found for scope: {:?}", scope) - }); + + let parent_scope = match rcx.tcx.region_maps.opt_encl_scope(scope) { + Some(parent_scope) => parent_scope, + // If no enclosing scope, then it must be the root scope which cannot be outlived. + None => return + }; let result = iterate_over_potentially_unsafe_regions_in_type( &mut DropckContext { diff --git a/src/test/compile-fail/const-match-pattern-arm.rs b/src/test/compile-fail/const-match-pattern-arm.rs new file mode 100644 index 00000000000..452aa87d6ba --- /dev/null +++ b/src/test/compile-fail/const-match-pattern-arm.rs @@ -0,0 +1,25 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const x: bool = match Some(true) { + Some(value) => true, + //~^ ERROR: constant contains unimplemented expression type [E0019] + _ => false +}; + +const y: bool = { + match Some(true) { + Some(value) => true, + //~^ ERROR: constant contains unimplemented expression type [E0019] + _ => false + } +}; + +fn main() {} |
