Skip to content

Beta next #29112

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Oct 16, 2015
Prev Previous commit
Next Next commit
use the infcx tables to check if a closure is Copy
Fixes #28550
  • Loading branch information
Ariel Ben-Yehuda authored and brson committed Oct 16, 2015
commit 98aabbc899972cb239db5058da66b405c10c05f2
9 changes: 8 additions & 1 deletion src/librustc/middle/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1394,9 +1394,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
self.resolve_type_vars_or_error(&ty)
}

pub fn tables_are_tcx_tables(&self) -> bool {
let tables: &RefCell<ty::Tables> = &self.tables;
let tcx_tables: &RefCell<ty::Tables> = &self.tcx.tables;
tables as *const _ == tcx_tables as *const _
}

pub fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool {
let ty = self.resolve_type_vars_if_possible(&ty);
if ty.needs_infer() {
if ty.needs_infer() ||
(ty.has_closure_types() && !self.tables_are_tcx_tables()) {
// this can get called from typeck (by euv), and moves_by_default
// rightly refuses to work with inference variables, but
// moves_by_default has a cache, which we want to use in other
Expand Down
25 changes: 25 additions & 0 deletions src/test/run-pass/issue-28550.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2015 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.

struct A<F: FnOnce()->T,T>(F::Output);
struct B<F: FnOnce()->T,T>(A<F,T>);

// Removing Option causes it to compile.
fn foo<T,F: FnOnce()->T>(f: F) -> Option<B<F,T>> {
Some(B(A(f())))
}

fn main() {
let v = (|| foo(||4))();
match v {
Some(B(A(4))) => {},
_ => unreachable!()
}
}