Skip to content

Commit 7d56131

Browse files
spastorinonikomatsakis
authored andcommitted
Mir typeck Cast for ReifyFnPtr value
1 parent 8635548 commit 7d56131

File tree

2 files changed

+70
-1
lines changed

2 files changed

+70
-1
lines changed

src/librustc_mir/transform/type_check.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1186,11 +1186,28 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
11861186
self.prove_trait_ref(trait_ref, location);
11871187
}
11881188

1189+
Rvalue::Cast(cast_kind, op, ty) => {
1190+
match cast_kind {
1191+
CastKind::ReifyFnPointer => {
1192+
let ty_fn_ptr_from = tcx.mk_fn_ptr(op.ty(mir, tcx).fn_sig(tcx));
1193+
1194+
if let Err(terr) = self.eq_types(ty_fn_ptr_from, ty, location.at_self()) {
1195+
span_mirbug!(self, "", "casting {:?}", terr);
1196+
}
1197+
}
1198+
1199+
CastKind::ClosureFnPointer |
1200+
CastKind::UnsafeFnPointer |
1201+
CastKind::Misc |
1202+
CastKind::Unsize => {}
1203+
1204+
}
1205+
}
1206+
11891207
// FIXME: These other cases have to be implemented in future PRs
11901208
Rvalue::Use(..) |
11911209
Rvalue::Ref(..) |
11921210
Rvalue::Len(..) |
1193-
Rvalue::Cast(..) |
11941211
Rvalue::BinaryOp(..) |
11951212
Rvalue::CheckedBinaryOp(..) |
11961213
Rvalue::UnaryOp(..) |
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-flags: -Z borrowck=mir -Z nll
12+
13+
#![allow(dead_code)]
14+
15+
// Test that we relate the type of the fn type to the type of the fn
16+
// ptr when doing a `ReifyFnPointer` cast.
17+
//
18+
// This test is a bit tortured, let me explain:
19+
//
20+
21+
// The `where 'a: 'a` clause here ensures that `'a` is early bound,
22+
// which is needed below to ensure that this test hits the path we are
23+
// concerned with.
24+
fn foo<'a>(x: &'a u32) -> &'a u32
25+
where
26+
'a: 'a,
27+
{
28+
panic!()
29+
}
30+
31+
fn bar<'a>(x: &'a u32) -> &'static u32 {
32+
// Here, the type of `foo` is `typeof(foo::<'x>)` for some fresh variable `'x`.
33+
// During NLL region analysis, this will get renumbered to `typeof(foo::<'?0>)`
34+
// where `'?0` is a new region variable.
35+
//
36+
// (Note that if `'a` on `foo` were early-bound, the type would be
37+
// `typeof(foo)`, which would interact differently with because
38+
// the renumbering later.)
39+
//
40+
// This type is then coerced to a fn type `fn(&'?1 u32) -> &'?2
41+
// u32`. Here, the `'?1` and `'?2` will have been created during
42+
// the NLL region renumbering.
43+
//
44+
// The MIR type checker must therefore relate `'?0` to `'?1` and `'?2`
45+
// as part of checking the `ReifyFnPointer`.
46+
let f: fn(_) -> _ = foo;
47+
//~^ WARNING not reporting region error due to -Znll
48+
f(x)
49+
//~^ ERROR free region `'_#1r` does not outlive free region `'static`
50+
}
51+
52+
fn main() {}

0 commit comments

Comments
 (0)