Skip to content

Commit 8f92150

Browse files
Manishearthalexcrichton
authored andcommitted
Rollup merge of #22667 - dotdash:retslot_cast.rs, r=huonw
We already do this for the function arguments, but miss it for the retslot pointer, which can lead to LLVM assertions because the retslot has the wrong type. Fixes #22663
2 parents 5a41536 + b593c60 commit 8f92150

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

src/librustc_trans/trans/callee.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,8 +765,16 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
765765
if is_rust_fn {
766766
let mut llargs = Vec::new();
767767

768-
if let (ty::FnConverging(ret_ty), Some(llretslot)) = (ret_ty, opt_llretslot) {
768+
if let (ty::FnConverging(ret_ty), Some(mut llretslot)) = (ret_ty, opt_llretslot) {
769769
if type_of::return_uses_outptr(ccx, ret_ty) {
770+
let llformal_ret_ty = type_of::type_of(ccx, ret_ty).ptr_to();
771+
let llret_ty = common::val_ty(llretslot);
772+
if llformal_ret_ty != llret_ty {
773+
// this could happen due to e.g. subtyping
774+
debug!("casting actual return type ({}) to match formal ({})",
775+
bcx.llty_str(llret_ty), bcx.llty_str(llformal_ret_ty));
776+
llretslot = PointerCast(bcx, llretslot, llformal_ret_ty);
777+
}
770778
llargs.push(llretslot);
771779
}
772780
}

src/test/compile-fail/retslot-cast.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2015 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+
#![feature(rustc_attrs)]
12+
#![allow(warnings)]
13+
14+
pub fn fail(x: Option<& (Iterator+Send)>) -> Option<&Iterator> {
15+
// This call used to trigger an LLVM assertion because the return slot had type
16+
// "Option<&Iterator>"* instead of "Option<&(Iterator+Send)>"*
17+
inner(x)
18+
}
19+
20+
pub fn inner(x: Option<& (Iterator+Send)>) -> Option<&(Iterator+Send)> {
21+
x
22+
}
23+
24+
#[rustc_error]
25+
fn main() {} //~ ERROR compilation successful

0 commit comments

Comments
 (0)