Navigation Menu

Skip to content

Commit

Permalink
Report let bindings and statements as unstable
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed May 22, 2018
1 parent d7bf358 commit 8a5eb68
Show file tree
Hide file tree
Showing 16 changed files with 150 additions and 65 deletions.
35 changes: 13 additions & 22 deletions src/librustc_mir/transform/qualify_consts.rs
Expand Up @@ -32,7 +32,7 @@ use rustc::middle::lang_items;
use rustc_target::spec::abi::Abi;
use syntax::attr;
use syntax::ast::LitKind;
use syntax::feature_gate::{UnstableFeatures, emit_feature_err, GateIssue};
use syntax::feature_gate::{UnstableFeatures, feature_err, emit_feature_err, GateIssue};
use syntax_pos::{Span, DUMMY_SP};

use std::fmt;
Expand Down Expand Up @@ -189,17 +189,12 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
fn statement_like(&mut self) {
self.add(Qualif::NOT_CONST);
if self.mode != Mode::Fn {
if self.span.allows_unstable() {
emit_feature_err(&self.tcx.sess.parse_sess, "const_let",
self.span, GateIssue::Language,
"statements in const fn are unstable");
}
let mut err = struct_span_err!(
self.tcx.sess,
let mut err = feature_err(
&self.tcx.sess.parse_sess,
"const_let",
self.span,
E0016,
"blocks in {}s are limited to items and tail expressions",
self.mode
GateIssue::Language,
&format!("statements in {}s are unstable", self.mode),
);
if self.tcx.sess.teach(&err.get_code().unwrap()) {
err.note("Blocks in constants may only contain items (such as constant, function \
Expand Down Expand Up @@ -365,7 +360,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
TerminatorKind::FalseUnwind { .. } => None,

TerminatorKind::Return => {
if self.tcx.sess.features_untracked().const_let {
if !self.tcx.sess.features_untracked().const_let {
// Check for unused values. This usually means
// there are extra statements in the AST.
for temp in mir.temps_iter() {
Expand Down Expand Up @@ -466,10 +461,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
self.not_const();
}
LocalKind::Var if !self.tcx.sess.features_untracked().const_let => {
if self.mode != Mode::Fn && self.span.allows_unstable() {
if self.mode != Mode::Fn {
emit_feature_err(&self.tcx.sess.parse_sess, "const_let",
self.span, GateIssue::Language,
"let bindings in const fn are unstable");
&format!("let bindings in {}s are unstable",self.mode));
}
self.add(Qualif::NOT_CONST);
}
Expand Down Expand Up @@ -1105,15 +1100,11 @@ This does not pose a problem by itself because they can't be accessed directly."
// Avoid a generic error for other uses of arguments.
if self.qualif.intersects(Qualif::FN_ARGUMENT) {
let decl = &self.mir.local_decls[index];
if decl.source_info.span.allows_unstable() {
emit_feature_err(&self.tcx.sess.parse_sess, "const_let",
decl.source_info.span, GateIssue::Language,
"locals and patterns in const fn are unstable");
}
let mut err = struct_span_err!(
self.tcx.sess,
let mut err = feature_err(
&self.tcx.sess.parse_sess,
"const_let",
decl.source_info.span,
E0022,
GateIssue::Language,
"arguments of constant functions can only be immutable by-value bindings"
);
if self.tcx.sess.teach(&err.get_code().unwrap()) {
Expand Down
12 changes: 7 additions & 5 deletions src/test/compile-fail/const-block-non-item-statement-2.rs
Expand Up @@ -9,18 +9,20 @@
// except according to those terms.

const A: usize = { 1; 2 };
//~^ ERROR: blocks in constants are limited to items and tail expressions
//~^ ERROR statements in constants are unstable

const B: usize = { { } 2 };
//~^ ERROR: blocks in constants are limited to items and tail expressions
//~^ ERROR statements in constants are unstable

macro_rules! foo {
() => (()) //~ ERROR: blocks in constants are limited to items and tail expressions
() => (()) //~ ERROR statements in constants are unstable
}
const C: usize = { foo!(); 2 };

const D: usize = { let x = 4; 2 };
//~^ ERROR: blocks in constants are limited to items and tail expressions
//~^^ ERROR: blocks in constants are limited to items and tail expressions
//~^ ERROR let bindings in constants are unstable
//~| ERROR statements in constants are unstable
//~| ERROR let bindings in constants are unstable
//~| ERROR statements in constants are unstable

pub fn main() {}
6 changes: 4 additions & 2 deletions src/test/compile-fail/const-block-non-item-statement-3.rs
Expand Up @@ -9,7 +9,9 @@
// except according to those terms.

type Array = [u32; { let x = 2; 5 }];
//~^ ERROR: blocks in constants are limited to items and tail expressions
//~^^ ERROR: blocks in constants are limited to items and tail expressions
//~^ ERROR let bindings in constants are unstable
//~| ERROR statements in constants are unstable
//~| ERROR let bindings in constants are unstable
//~| ERROR statements in constants are unstable

pub fn main() {}
6 changes: 4 additions & 2 deletions src/test/compile-fail/const-block-non-item-statement.rs
Expand Up @@ -10,8 +10,10 @@

enum Foo {
Bar = { let x = 1; 3 }
//~^ ERROR: blocks in constants are limited to items and tail expressions
//~^^ ERROR: blocks in constants are limited to items and tail expressions
//~^ ERROR let bindings in constants are unstable
//~| ERROR statements in constants are unstable
//~| ERROR let bindings in constants are unstable
//~| ERROR statements in constants are unstable
}

pub fn main() {}
10 changes: 7 additions & 3 deletions src/test/compile-fail/const-fn-destructuring-arg.rs
Expand Up @@ -8,16 +8,20 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// test that certain things are disallowed in const fn signatures
// test that certain things are disallowed in constant functionssignatures

#![feature(const_fn)]

// no destructuring
const fn i((
a, //~ ERROR: E0022
b //~ ERROR: E0022
a,
//~^ ERROR arguments of constant functions can only be immutable by-value bindings
b
//~^ ERROR arguments of constant functions can only be immutable by-value bindings
): (u32, u32)) -> u32 {
a + b
//~^ ERROR let bindings in constant functions are unstable
//~| ERROR let bindings in constant functions are unstable
}

fn main() {}
10 changes: 8 additions & 2 deletions src/test/compile-fail/const-fn-not-safe-for-const.rs
Expand Up @@ -38,9 +38,15 @@ const fn get_Y_addr() -> &'static u32 {
}

const fn get() -> u32 {
let x = 22; //~ ERROR E0016
let y = 44; //~ ERROR E0016
let x = 22;
//~^ ERROR let bindings in constant functions are unstable
//~| ERROR statements in constant functions are unstable
let y = 44;
//~^ ERROR let bindings in constant functions are unstable
//~| ERROR statements in constant functions are unstable
x + y
//~^ ERROR let bindings in constant functions are unstable
//~| ERROR let bindings in constant functions are unstable
}

fn main() {
Expand Down
7 changes: 5 additions & 2 deletions src/test/compile-fail/issue-18118.rs
Expand Up @@ -10,9 +10,12 @@

pub fn main() {
const z: &'static isize = {
//~^ ERROR blocks in constants are limited to items and tail expressions
//~^ ERROR let bindings in constants are unstable
//~| ERROR statements in constants are unstable
let p = 3;
//~^ ERROR blocks in constants are limited to items and tail expressions
//~^ ERROR let bindings in constants are unstable
//~| ERROR statements in constants are unstable
&p //~ ERROR `p` does not live long enough
//~^ ERROR let bindings in constants are unstable
};
}
8 changes: 6 additions & 2 deletions src/test/compile-fail/issue-37550.rs
Expand Up @@ -11,8 +11,12 @@
#![feature(const_fn)]

const fn x() {
let t = true; //~ ERROR blocks in constant functions are limited to items and tail expressions
let x = || t; //~ ERROR blocks in constant functions are limited to items and tail expressions
let t = true;
//~^ ERROR let bindings in constant functions are unstable
//~| ERROR statements in constant functions are unstable
let x = || t;
//~^ ERROR let bindings in constant functions are unstable
//~| ERROR statements in constant functions are unstable
}

fn main() {}
25 changes: 14 additions & 11 deletions src/test/compile-fail/issue32829.rs
Expand Up @@ -14,15 +14,16 @@

const bad : u32 = {
{
5; //~ ERROR: blocks in constants are limited to items and tail expressions
5;
//~^ ERROR statements in constants are unstable
0
}
};

const bad_two : u32 = {
{
invalid();
//~^ ERROR: blocks in constants are limited to items and tail expressions
//~^ ERROR statements in constants are unstable
//~^^ ERROR: calls in constants are limited to constant functions, tuple structs and tuple variants
0
}
Expand All @@ -31,55 +32,57 @@ const bad_two : u32 = {
const bad_three : u32 = {
{
valid();
//~^ ERROR: blocks in constants are limited to items and tail expressions
//~^ ERROR statements in constants are unstable
0
}
};

static bad_four : u32 = {
{
5; //~ ERROR: blocks in statics are limited to items and tail expressions
5;
//~^ ERROR statements in statics are unstable
0
}
};

static bad_five : u32 = {
{
invalid();
//~^ ERROR: blocks in statics are limited to items and tail expressions
//~^^ ERROR: calls in statics are limited to constant functions, tuple structs and tuple variants
//~^ ERROR: calls in statics are limited to constant functions, tuple structs and tuple variants
//~| ERROR statements in statics are unstable
0
}
};

static bad_six : u32 = {
{
valid();
//~^ ERROR: blocks in statics are limited to items and tail expressions
//~^ ERROR statements in statics are unstable
0
}
};

static mut bad_seven : u32 = {
{
5; //~ ERROR: blocks in statics are limited to items and tail expressions
5;
//~^ ERROR statements in statics are unstable
0
}
};

static mut bad_eight : u32 = {
{
invalid();
//~^ ERROR: blocks in statics are limited to items and tail expressions
//~^^ ERROR: calls in statics are limited to constant functions, tuple structs and tuple variants
//~^ ERROR statements in statics are unstable
//~| ERROR: calls in statics are limited to constant functions, tuple structs and tuple variants
0
}
};

static mut bad_nine : u32 = {
{
valid();
//~^ ERROR: blocks in statics are limited to items and tail expressions
//~^ ERROR statements in statics are unstable
0
}
};
Expand Down
2 changes: 1 addition & 1 deletion src/test/run-pass/ctfe/const-fn-destructuring-arg.rs
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// test that certain things are disallowed in const fn signatures
// test that certain things are disallowed in constant functionssignatures

#![feature(const_fn, const_let)]

Expand Down
30 changes: 30 additions & 0 deletions src/test/ui/const-eval/const_let.rs
@@ -0,0 +1,30 @@
// Copyright 2018 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.

#![feature(const_let)]

fn main() {}

struct FakeNeedsDrop;

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

// ok
const X: FakeNeedsDrop = { let x = FakeNeedsDrop; x };

// error
const Y: FakeNeedsDrop = { let mut x = FakeNeedsDrop; x = FakeNeedsDrop; x };
//~^ ERROR constant contains unimplemented expression type

// error
const Z: () = { let mut x = None; x = Some(FakeNeedsDrop); };
//~^ ERROR constant contains unimplemented expression type
15 changes: 15 additions & 0 deletions src/test/ui/const-eval/const_let.stderr
@@ -0,0 +1,15 @@
error[E0019]: constant contains unimplemented expression type
--> $DIR/const_let.rs:25:55
|
LL | const Y: FakeNeedsDrop = { let mut x = FakeNeedsDrop; x = FakeNeedsDrop; x };
| ^

error[E0019]: constant contains unimplemented expression type
--> $DIR/const_let.rs:29:35
|
LL | const Z: () = { let mut x = None; x = Some(FakeNeedsDrop); };
| ^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0019`.
3 changes: 2 additions & 1 deletion src/test/ui/const-fn-error.rs
Expand Up @@ -14,7 +14,8 @@ const X : usize = 2;

const fn f(x: usize) -> usize {
let mut sum = 0;
//~^ ERROR E0016
//~^ let bindings in constant functions are unstable
//~| statements in constant functions are unstable
for i in 0..x {
//~^ ERROR E0015
//~| ERROR E0019
Expand Down

0 comments on commit 8a5eb68

Please sign in to comment.