diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index 61b2c108fed..83a38a529d0 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -629,19 +629,13 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { def_id: DefId) -> bool { match tcx.item_type(def_id).sty { - ty::TyFnDef(def_id, _, f) => { + ty::TyFnDef(def_id, _, _) => { // Some constructors also have type TyFnDef but they are // always instantiated inline and don't result in a // translation item. Same for FFI functions. if let Some(hir_map::NodeForeignItem(_)) = tcx.hir.get_if_local(def_id) { return false; } - - if let Some(adt_def) = f.sig.output().skip_binder().ty_adt_def() { - if adt_def.variants.iter().any(|v| def_id == v.did) { - return false; - } - } } ty::TyClosure(..) => {} _ => return false @@ -703,6 +697,16 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { fn should_trans_locally<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool { + if let ty::TyFnDef(_, _, f) = tcx.item_type(def_id).sty { + if let Some(adt_def) = f.sig.output().skip_binder().ty_adt_def() { + if adt_def.variants.iter().any(|v| def_id == v.did) { + // HACK: ADT constructors are translated in-place and + // do not have a trans-item. + return false; + } + } + } + if def_id.is_local() { true } else { diff --git a/src/test/run-pass/auxiliary/issue_39823.rs b/src/test/run-pass/auxiliary/issue_39823.rs new file mode 100644 index 00000000000..5342601ac14 --- /dev/null +++ b/src/test/run-pass/auxiliary/issue_39823.rs @@ -0,0 +1,17 @@ +// Copyright 2017 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type="rlib"] + +#[derive(Debug, PartialEq)] +pub struct RemoteC(pub u32); + +#[derive(Debug, PartialEq)] +pub struct RemoteG(pub T); diff --git a/src/test/run-pass/issue-39823.rs b/src/test/run-pass/issue-39823.rs new file mode 100644 index 00000000000..061a55b03b2 --- /dev/null +++ b/src/test/run-pass/issue-39823.rs @@ -0,0 +1,34 @@ +// Copyright 2016 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:issue_39823.rs + +extern crate issue_39823; +use issue_39823::{RemoteC, RemoteG}; + +#[derive(Debug, PartialEq)] +struct LocalC(u32); + +#[derive(Debug, PartialEq)] +struct LocalG(T); + +fn main() { + let virtual_localc : &Fn(_) -> LocalC = &LocalC; + assert_eq!(virtual_localc(1), LocalC(1)); + + let virtual_localg : &Fn(_) -> LocalG = &LocalG; + assert_eq!(virtual_localg(1), LocalG(1)); + + let virtual_remotec : &Fn(_) -> RemoteC = &RemoteC; + assert_eq!(virtual_remotec(1), RemoteC(1)); + + let virtual_remoteg : &Fn(_) -> RemoteG = &RemoteG; + assert_eq!(virtual_remoteg(1), RemoteG(1)); +}