Skip to content

Commit

Permalink
closures cannot be constants
Browse files Browse the repository at this point in the history
During type collection, error if a closures is found in constant
position, catching that before they go causing ICEs.

Fixes rust-lang#50600.
Fixes rust-lang#48838.
  • Loading branch information
leoyvens committed May 10, 2018
1 parent e5f80f2 commit 7bb6de0
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 2 deletions.
11 changes: 10 additions & 1 deletion src/librustc_mir/interpret/const_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -444,9 +444,18 @@ pub fn const_eval_provider<'a, 'tcx>(
}

if let Some(id) = tcx.hir.as_local_node_id(def_id) {
let tables = tcx.typeck_tables_of(def_id);
let span = tcx.def_span(def_id);

// Closures in constant position can hit this in type collection.
if !tcx.has_typeck_tables(def_id) {
return Err(ConstEvalErr {
kind: Lrc::new(TypeckError),
span,
});
}

let tables = tcx.typeck_tables_of(def_id);

// Do match-check before building MIR
if tcx.check_match(def_id).is_err() {
return Err(ConstEvalErr {
Expand Down
6 changes: 5 additions & 1 deletion src/librustc_typeck/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1085,12 +1085,16 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,

NodeField(field) => icx.to_ty(&field.ty),

NodeExpr(&hir::Expr { node: hir::ExprClosure(.., gen), .. }) => {
NodeExpr(&hir::Expr { node: hir::ExprClosure(.., gen), span, .. }) => {
if gen.is_some() {
let hir_id = tcx.hir.node_to_hir_id(node_id);
return tcx.typeck_tables_of(def_id).node_id_to_type(hir_id);
}

if !tcx.has_typeck_tables(def_id) {
span_err!(tcx.sess, span, E0912, "closures cannot be constants");
}

let substs = ty::ClosureSubsts {
substs: Substs::for_item(
tcx,
Expand Down
1 change: 1 addition & 0 deletions src/librustc_typeck/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4770,4 +4770,5 @@ register_diagnostics! {
E0641, // cannot cast to/from a pointer with an unknown kind
E0645, // trait aliases not finished
E0907, // type inside generator must be known in this context
E0912, // closures cannot be constants
}
20 changes: 20 additions & 0 deletions src/test/ui/const-eval/issue-50600.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// 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.

// Testing that these do not ICE.

struct Foo ([u8; |x: u8| { }]);
//~^ ERROR closures cannot be constants
enum Functions {
Square = |x:i32| { },
//~^ ERROR closures cannot be constants
}

fn main() {}
15 changes: 15 additions & 0 deletions src/test/ui/const-eval/issue-50600.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0912]: closures cannot be constants
--> $DIR/issue-50600.rs:13:18
|
LL | struct Foo ([u8; |x: u8| { }]);
| ^^^^^^^^^^^

error[E0912]: closures cannot be constants
--> $DIR/issue-50600.rs:16:14
|
LL | Square = |x:i32| { },
| ^^^^^^^^^^^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0912`.

0 comments on commit 7bb6de0

Please sign in to comment.