Skip to content

Consistently normalize fn types after erasing lifetimes. #29836

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 1 commit into from
Nov 15, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/librustc_trans/trans/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
};

let fn_sig = ccx.tcx().erase_late_bound_regions(fn_sig);
let fn_sig = infer::normalize_associated_type(ccx.tcx(), &fn_sig);

let mut attrs = llvm::AttrBuilder::new();
let ret_ty = fn_sig.output;
Expand Down
34 changes: 13 additions & 21 deletions src/librustc_trans/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use metadata::{csearch, encoder, loader};
use middle::astencode;
use middle::cfg;
use middle::def_id::DefId;
use middle::infer;
use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
use middle::weak_lang_items;
use middle::pat_util::simple_name;
Expand Down Expand Up @@ -1905,7 +1906,11 @@ pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
debug!("trans_fn(param_substs={:?})", param_substs);
let _icx = push_ctxt("trans_fn");
let fn_ty = ccx.tcx().node_id_to_type(id);
let output_type = ccx.tcx().erase_late_bound_regions(&fn_ty.fn_ret());
let fn_ty = monomorphize::apply_param_substs(ccx.tcx(), param_substs, &fn_ty);
let sig = fn_ty.fn_sig();
let sig = ccx.tcx().erase_late_bound_regions(&sig);
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
let output_type = sig.output;
let abi = fn_ty.fn_abi();
trans_closure(ccx, decl, body, llfndecl, param_substs, id, attrs, output_type, abi,
closure::ClosureEnv::NotClosure);
Expand Down Expand Up @@ -1936,15 +1941,9 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,

let ccx = bcx.fcx.ccx;

let result_ty = match ctor_ty.sty {
ty::TyBareFn(_, ref bft) => {
bcx.tcx().erase_late_bound_regions(&bft.sig.output()).unwrap()
}
_ => ccx.sess().bug(
&format!("trans_enum_variant_constructor: \
unexpected ctor return type {}",
ctor_ty))
};
let sig = ccx.tcx().erase_late_bound_regions(&ctor_ty.fn_sig());
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
let result_ty = sig.output.unwrap();

// Get location to store the result. If the user does not care about
// the result, just make a stack slot
Expand Down Expand Up @@ -2026,15 +2025,10 @@ fn trans_enum_variant_or_tuple_like_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx
let ctor_ty = ccx.tcx().node_id_to_type(ctor_id);
let ctor_ty = monomorphize::apply_param_substs(ccx.tcx(), param_substs, &ctor_ty);

let result_ty = match ctor_ty.sty {
ty::TyBareFn(_, ref bft) => {
ccx.tcx().erase_late_bound_regions(&bft.sig.output())
}
_ => ccx.sess().bug(
&format!("trans_enum_variant_or_tuple_like_struct: \
unexpected ctor return type {}",
ctor_ty))
};
let sig = ccx.tcx().erase_late_bound_regions(&ctor_ty.fn_sig());
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
let arg_tys = sig.inputs;
let result_ty = sig.output;

let (arena, fcx): (TypedArena<_>, FunctionContext);
arena = TypedArena::new();
Expand All @@ -2044,8 +2038,6 @@ fn trans_enum_variant_or_tuple_like_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx

assert!(!fcx.needs_ret_allocas);

let arg_tys = ccx.tcx().erase_late_bound_regions(&ctor_ty.fn_args());

if !type_is_zero_size(fcx.ccx, result_ty.unwrap()) {
let dest = fcx.get_ret_slot(bcx, result_ty, "eret_slot");
let repr = adt::represent_type(ccx, result_ty.unwrap());
Expand Down
25 changes: 17 additions & 8 deletions src/librustc_trans/trans/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use llvm::{self, ValueRef, get_params};
use metadata::cstore::LOCAL_CRATE;
use middle::def;
use middle::def_id::DefId;
use middle::infer::normalize_associated_type;
use middle::infer;
use middle::subst;
use middle::subst::{Substs};
use rustc::front::map as hir_map;
Expand Down Expand Up @@ -304,6 +304,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
}
};
let sig = tcx.erase_late_bound_regions(sig);
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
let tuple_input_ty = tcx.mk_tup(sig.inputs.to_vec());
let tuple_fn_ty = tcx.mk_fn(opt_def_id,
tcx.mk_bare_fn(ty::BareFnTy {
Expand Down Expand Up @@ -466,7 +467,7 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(

// Type scheme of the function item (may have type params)
let fn_type_scheme = tcx.lookup_item_type(def_id);
let fn_type = normalize_associated_type(tcx, &fn_type_scheme.ty);
let fn_type = infer::normalize_associated_type(tcx, &fn_type_scheme.ty);

// Find the actual function pointer.
let mut val = {
Expand Down Expand Up @@ -605,8 +606,9 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,

let (abi, ret_ty) = match callee.ty.sty {
ty::TyBareFn(_, ref f) => {
let output = bcx.tcx().erase_late_bound_regions(&f.sig.output());
(f.abi, output)
let sig = bcx.tcx().erase_late_bound_regions(&f.sig);
let sig = infer::normalize_associated_type(bcx.tcx(), &sig);
(f.abi, sig.output)
}
_ => panic!("expected bare rust fn or closure in trans_call_inner")
};
Expand Down Expand Up @@ -826,7 +828,9 @@ fn trans_args_under_call_abi<'blk, 'tcx>(
ignore_self: bool)
-> Block<'blk, 'tcx>
{
let args = bcx.tcx().erase_late_bound_regions(&fn_ty.fn_args());
let sig = bcx.tcx().erase_late_bound_regions(&fn_ty.fn_sig());
let sig = infer::normalize_associated_type(bcx.tcx(), &sig);
let args = sig.inputs;

// Translate the `self` argument first.
if !ignore_self {
Expand Down Expand Up @@ -887,7 +891,10 @@ fn trans_overloaded_call_args<'blk, 'tcx>(
ignore_self: bool)
-> Block<'blk, 'tcx> {
// Translate the `self` argument first.
let arg_tys = bcx.tcx().erase_late_bound_regions( &fn_ty.fn_args());
let sig = bcx.tcx().erase_late_bound_regions(&fn_ty.fn_sig());
let sig = infer::normalize_associated_type(bcx.tcx(), &sig);
let arg_tys = sig.inputs;

if !ignore_self {
let arg_datum = unpack_datum!(bcx, expr::trans(bcx, arg_exprs[0]));
bcx = trans_arg_datum(bcx,
Expand Down Expand Up @@ -933,8 +940,10 @@ pub fn trans_args<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>,
debug!("trans_args(abi={})", abi);

let _icx = push_ctxt("trans_args");
let arg_tys = cx.tcx().erase_late_bound_regions(&fn_ty.fn_args());
let variadic = fn_ty.fn_sig().0.variadic;
let sig = cx.tcx().erase_late_bound_regions(&fn_ty.fn_sig());
let sig = infer::normalize_associated_type(cx.tcx(), &sig);
let arg_tys = sig.inputs;
let variadic = sig.variadic;

let mut bcx = cx;

Expand Down
3 changes: 3 additions & 0 deletions src/librustc_trans/trans/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
tcx.with_freevars(id, |fv| fv.iter().cloned().collect());

let sig = tcx.erase_late_bound_regions(&function_type.sig);
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);

trans_closure(ccx,
decl,
Expand Down Expand Up @@ -371,6 +372,8 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
let lloncefn = declare::define_internal_rust_fn(ccx, &function_name,
llonce_fn_ty);
let sig = tcx.erase_late_bound_regions(&llonce_bare_fn_ty.sig);
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);

let (block_arena, fcx): (TypedArena<_>, FunctionContext);
block_arena = TypedArena::new();
fcx = new_fn_ctxt(ccx,
Expand Down
2 changes: 2 additions & 0 deletions src/librustc_trans/trans/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use llvm::{self, ValueRef};
use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType};

use middle::def_id::DefId;
use middle::infer;
use middle::pat_util;
use middle::subst::{self, Substs};
use rustc::front::map as hir_map;
Expand Down Expand Up @@ -262,6 +263,7 @@ impl<'tcx> TypeMap<'tcx> {
unique_type_id.push_str(" fn(");

let sig = cx.tcx().erase_late_bound_regions(sig);
let sig = infer::normalize_associated_type(cx.tcx(), &sig);

for &parameter_type in &sig.inputs {
let parameter_type_id =
Expand Down
11 changes: 8 additions & 3 deletions src/librustc_trans/trans/debuginfo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use rustc_front::hir;
use trans::common::{NodeIdAndSpan, CrateContext, FunctionContext, Block};
use trans;
use trans::{monomorphize, type_of};
use middle::infer;
use middle::ty::{self, Ty};
use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
use util::nodemap::{NodeMap, FnvHashMap, FnvHashSet};
Expand Down Expand Up @@ -418,19 +419,23 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
// Return type -- llvm::DIBuilder wants this at index 0
assert_type_for_node_id(cx, fn_ast_id, error_reporting_span);
let fn_type = cx.tcx().node_id_to_type(fn_ast_id);
let fn_type = monomorphize::apply_param_substs(cx.tcx(), param_substs, &fn_type);

let (sig, abi) = match fn_type.sty {
ty::TyBareFn(_, ref barefnty) => {
(cx.tcx().erase_late_bound_regions(&barefnty.sig), barefnty.abi)
let sig = cx.tcx().erase_late_bound_regions(&barefnty.sig);
let sig = infer::normalize_associated_type(cx.tcx(), &sig);
(sig, barefnty.abi)
}
ty::TyClosure(def_id, ref substs) => {
let closure_type = cx.tcx().closure_type(def_id, substs);
(cx.tcx().erase_late_bound_regions(&closure_type.sig), closure_type.abi)
let sig = cx.tcx().erase_late_bound_regions(&closure_type.sig);
let sig = infer::normalize_associated_type(cx.tcx(), &sig);
(sig, closure_type.abi)
}

_ => cx.sess().bug("get_function_metdata: Expected a function type!")
};
let sig = monomorphize::apply_param_substs(cx.tcx(), param_substs, &sig);

let mut signature = Vec::with_capacity(sig.inputs.len() + 1);

Expand Down
2 changes: 2 additions & 0 deletions src/librustc_trans/trans/debuginfo/type_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use super::namespace::crate_root_namespace;

use trans::common::CrateContext;
use middle::def_id::DefId;
use middle::infer;
use middle::subst::{self, Substs};
use middle::ty::{self, Ty};

Expand Down Expand Up @@ -124,6 +125,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
output.push_str("fn(");

let sig = cx.tcx().erase_late_bound_regions(sig);
let sig = infer::normalize_associated_type(cx.tcx(), &sig);
if !sig.inputs.is_empty() {
for &parameter_type in &sig.inputs {
push_debuginfo_type_name(cx, parameter_type, true, output);
Expand Down
8 changes: 3 additions & 5 deletions src/librustc_trans/trans/declare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,6 @@ pub fn declare_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str,
fn_type: ty::Ty<'tcx>) -> ValueRef {
debug!("declare_rust_fn(name={:?}, fn_type={:?})", name,
fn_type);
let fn_type = infer::normalize_associated_type(ccx.tcx(), &fn_type);
debug!("declare_rust_fn (after normalised associated types) fn_type={:?}",
fn_type);

let function_type; // placeholder so that the memory ownership works out ok
let (sig, abi, env) = match fn_type.sty {
Expand All @@ -124,14 +121,15 @@ pub fn declare_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str,
_ => ccx.sess().bug("expected closure or fn")
};

let sig = ty::Binder(ccx.tcx().erase_late_bound_regions(sig));
let sig = ccx.tcx().erase_late_bound_regions(sig);
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
debug!("declare_rust_fn (after region erasure) sig={:?}", sig);
let llfty = type_of::type_of_rust_fn(ccx, env, &sig, abi);
debug!("declare_rust_fn llfty={}", ccx.tn().type_to_string(llfty));

// it is ok to directly access sig.0.output because we erased all
// late-bound-regions above
let llfn = declare_fn(ccx, name, llvm::CCallConv, llfty, sig.0.output);
let llfn = declare_fn(ccx, name, llvm::CCallConv, llfty, sig.output);
attributes::from_fn_type(ccx, fn_type).apply_llfn(llfn);
llfn
}
Expand Down
21 changes: 8 additions & 13 deletions src/librustc_trans/trans/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use intrinsics::{self, Intrinsic};
use libc;
use llvm;
use llvm::{SequentiallyConsistent, Acquire, Release, AtomicXchg, ValueRef, TypeKind};
use middle::infer;
use middle::subst;
use middle::subst::FnSpace;
use trans::adt;
Expand Down Expand Up @@ -170,13 +171,10 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,

let _icx = push_ctxt("trans_intrinsic_call");

let (arg_tys, ret_ty) = match callee_ty.sty {
ty::TyBareFn(_, ref f) => {
(bcx.tcx().erase_late_bound_regions(&f.sig.inputs()),
bcx.tcx().erase_late_bound_regions(&f.sig.output()))
}
_ => panic!("expected bare_fn in trans_intrinsic_call")
};
let sig = ccx.tcx().erase_late_bound_regions(callee_ty.fn_sig());
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
let arg_tys = sig.inputs;
let ret_ty = sig.output;
let foreign_item = tcx.map.expect_foreign_item(node);
let name = foreign_item.name.as_str();

Expand Down Expand Up @@ -1330,12 +1328,9 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a>


let tcx = bcx.tcx();
let arg_tys = match callee_ty.sty {
ty::TyBareFn(_, ref f) => {
bcx.tcx().erase_late_bound_regions(&f.sig.inputs())
}
_ => unreachable!()
};
let sig = tcx.erase_late_bound_regions(callee_ty.fn_sig());
let sig = infer::normalize_associated_type(tcx, &sig);
let arg_tys = sig.inputs;

// every intrinsic takes a SIMD vector as its first argument
require_simd!(arg_tys[0], "input");
Expand Down
2 changes: 2 additions & 0 deletions src/librustc_trans/trans/meth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use arena::TypedArena;
use back::link;
use llvm::{ValueRef, get_params};
use middle::def_id::DefId;
use middle::infer;
use middle::subst::{Subst, Substs};
use middle::subst::VecPerParamSpace;
use middle::subst;
Expand Down Expand Up @@ -522,6 +523,7 @@ fn trans_object_shim<'a, 'tcx>(
let llfn = declare::define_internal_rust_fn(ccx, &function_name, shim_fn_ty);

let sig = ccx.tcx().erase_late_bound_regions(&fty.sig);
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);

let empty_substs = tcx.mk_substs(Substs::trans_empty());
let (block_arena, fcx): (TypedArena<_>, FunctionContext);
Expand Down
16 changes: 10 additions & 6 deletions src/librustc_trans/trans/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#![allow(non_camel_case_types)]

use middle::def_id::DefId;
use middle::infer;
use middle::subst;
use trans::adt;
use trans::common::*;
Expand Down Expand Up @@ -89,24 +90,25 @@ pub fn untuple_arguments<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,

pub fn type_of_rust_fn<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
llenvironment_type: Option<Type>,
sig: &ty::Binder<ty::FnSig<'tcx>>,
sig: &ty::FnSig<'tcx>,
abi: abi::Abi)
-> Type
{
debug!("type_of_rust_fn(sig={:?},abi={:?})",
sig,
abi);

let sig = cx.tcx().erase_late_bound_regions(sig);
assert!(!sig.variadic); // rust fns are never variadic

let mut atys: Vec<Type> = Vec::new();

// First, munge the inputs, if this has the `rust-call` ABI.
let inputs = &if abi == abi::RustCall {
untuple_arguments(cx, &sig.inputs)
let inputs_temp;
let inputs = if abi == abi::RustCall {
inputs_temp = untuple_arguments(cx, &sig.inputs);
&inputs_temp
} else {
sig.inputs
&sig.inputs
};

// Arg 0: Output pointer.
Expand Down Expand Up @@ -155,7 +157,9 @@ pub fn type_of_fn_from_ty<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, fty: Ty<'tcx>)
// FIXME(#19925) once fn item types are
// zero-sized, we'll need to do something here
if f.abi == abi::Rust || f.abi == abi::RustCall {
type_of_rust_fn(cx, None, &f.sig, f.abi)
let sig = cx.tcx().erase_late_bound_regions(&f.sig);
let sig = infer::normalize_associated_type(cx.tcx(), &sig);
type_of_rust_fn(cx, None, &sig, f.abi)
} else {
foreign::lltype_for_foreign_fn(cx, fty)
}
Expand Down
23 changes: 23 additions & 0 deletions src/test/run-pass/issue-23406.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// 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.

trait Inner {
type T;
}

impl<'a> Inner for &'a i32 {
type T = i32;
}

fn f<'a>(x: &'a i32) -> <&'a i32 as Inner>::T {
*x
}

fn main() {}
Loading