Skip to content

Commit 19abaf8

Browse files
committed
Auto merge of #29836 - eefriedman:normalize-fn, r=arielb1
Fixes #23406. Fixes #23958. Fixes #29832. CC @arielb1
2 parents e4309c2 + 82ab707 commit 19abaf8

File tree

13 files changed

+114
-56
lines changed

13 files changed

+114
-56
lines changed

src/librustc_trans/trans/attributes.rs

+1
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
142142
};
143143

144144
let fn_sig = ccx.tcx().erase_late_bound_regions(fn_sig);
145+
let fn_sig = infer::normalize_associated_type(ccx.tcx(), &fn_sig);
145146

146147
let mut attrs = llvm::AttrBuilder::new();
147148
let ret_ty = fn_sig.output;

src/librustc_trans/trans/base.rs

+13-21
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ use metadata::{csearch, encoder, loader};
3838
use middle::astencode;
3939
use middle::cfg;
4040
use middle::def_id::DefId;
41+
use middle::infer;
4142
use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
4243
use middle::weak_lang_items;
4344
use middle::pat_util::simple_name;
@@ -1905,7 +1906,11 @@ pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
19051906
debug!("trans_fn(param_substs={:?})", param_substs);
19061907
let _icx = push_ctxt("trans_fn");
19071908
let fn_ty = ccx.tcx().node_id_to_type(id);
1908-
let output_type = ccx.tcx().erase_late_bound_regions(&fn_ty.fn_ret());
1909+
let fn_ty = monomorphize::apply_param_substs(ccx.tcx(), param_substs, &fn_ty);
1910+
let sig = fn_ty.fn_sig();
1911+
let sig = ccx.tcx().erase_late_bound_regions(&sig);
1912+
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
1913+
let output_type = sig.output;
19091914
let abi = fn_ty.fn_abi();
19101915
trans_closure(ccx, decl, body, llfndecl, param_substs, id, attrs, output_type, abi,
19111916
closure::ClosureEnv::NotClosure);
@@ -1936,15 +1941,9 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
19361941

19371942
let ccx = bcx.fcx.ccx;
19381943

1939-
let result_ty = match ctor_ty.sty {
1940-
ty::TyBareFn(_, ref bft) => {
1941-
bcx.tcx().erase_late_bound_regions(&bft.sig.output()).unwrap()
1942-
}
1943-
_ => ccx.sess().bug(
1944-
&format!("trans_enum_variant_constructor: \
1945-
unexpected ctor return type {}",
1946-
ctor_ty))
1947-
};
1944+
let sig = ccx.tcx().erase_late_bound_regions(&ctor_ty.fn_sig());
1945+
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
1946+
let result_ty = sig.output.unwrap();
19481947

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

2029-
let result_ty = match ctor_ty.sty {
2030-
ty::TyBareFn(_, ref bft) => {
2031-
ccx.tcx().erase_late_bound_regions(&bft.sig.output())
2032-
}
2033-
_ => ccx.sess().bug(
2034-
&format!("trans_enum_variant_or_tuple_like_struct: \
2035-
unexpected ctor return type {}",
2036-
ctor_ty))
2037-
};
2028+
let sig = ccx.tcx().erase_late_bound_regions(&ctor_ty.fn_sig());
2029+
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
2030+
let arg_tys = sig.inputs;
2031+
let result_ty = sig.output;
20382032

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

20452039
assert!(!fcx.needs_ret_allocas);
20462040

2047-
let arg_tys = ccx.tcx().erase_late_bound_regions(&ctor_ty.fn_args());
2048-
20492041
if !type_is_zero_size(fcx.ccx, result_ty.unwrap()) {
20502042
let dest = fcx.get_ret_slot(bcx, result_ty, "eret_slot");
20512043
let repr = adt::represent_type(ccx, result_ty.unwrap());

src/librustc_trans/trans/callee.rs

+17-8
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use llvm::{self, ValueRef, get_params};
2525
use metadata::cstore::LOCAL_CRATE;
2626
use middle::def;
2727
use middle::def_id::DefId;
28-
use middle::infer::normalize_associated_type;
28+
use middle::infer;
2929
use middle::subst;
3030
use middle::subst::{Substs};
3131
use rustc::front::map as hir_map;
@@ -304,6 +304,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
304304
}
305305
};
306306
let sig = tcx.erase_late_bound_regions(sig);
307+
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
307308
let tuple_input_ty = tcx.mk_tup(sig.inputs.to_vec());
308309
let tuple_fn_ty = tcx.mk_fn(opt_def_id,
309310
tcx.mk_bare_fn(ty::BareFnTy {
@@ -466,7 +467,7 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
466467

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

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

606607
let (abi, ret_ty) = match callee.ty.sty {
607608
ty::TyBareFn(_, ref f) => {
608-
let output = bcx.tcx().erase_late_bound_regions(&f.sig.output());
609-
(f.abi, output)
609+
let sig = bcx.tcx().erase_late_bound_regions(&f.sig);
610+
let sig = infer::normalize_associated_type(bcx.tcx(), &sig);
611+
(f.abi, sig.output)
610612
}
611613
_ => panic!("expected bare rust fn or closure in trans_call_inner")
612614
};
@@ -826,7 +828,9 @@ fn trans_args_under_call_abi<'blk, 'tcx>(
826828
ignore_self: bool)
827829
-> Block<'blk, 'tcx>
828830
{
829-
let args = bcx.tcx().erase_late_bound_regions(&fn_ty.fn_args());
831+
let sig = bcx.tcx().erase_late_bound_regions(&fn_ty.fn_sig());
832+
let sig = infer::normalize_associated_type(bcx.tcx(), &sig);
833+
let args = sig.inputs;
830834

831835
// Translate the `self` argument first.
832836
if !ignore_self {
@@ -887,7 +891,10 @@ fn trans_overloaded_call_args<'blk, 'tcx>(
887891
ignore_self: bool)
888892
-> Block<'blk, 'tcx> {
889893
// Translate the `self` argument first.
890-
let arg_tys = bcx.tcx().erase_late_bound_regions( &fn_ty.fn_args());
894+
let sig = bcx.tcx().erase_late_bound_regions(&fn_ty.fn_sig());
895+
let sig = infer::normalize_associated_type(bcx.tcx(), &sig);
896+
let arg_tys = sig.inputs;
897+
891898
if !ignore_self {
892899
let arg_datum = unpack_datum!(bcx, expr::trans(bcx, arg_exprs[0]));
893900
bcx = trans_arg_datum(bcx,
@@ -933,8 +940,10 @@ pub fn trans_args<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>,
933940
debug!("trans_args(abi={})", abi);
934941

935942
let _icx = push_ctxt("trans_args");
936-
let arg_tys = cx.tcx().erase_late_bound_regions(&fn_ty.fn_args());
937-
let variadic = fn_ty.fn_sig().0.variadic;
943+
let sig = cx.tcx().erase_late_bound_regions(&fn_ty.fn_sig());
944+
let sig = infer::normalize_associated_type(cx.tcx(), &sig);
945+
let arg_tys = sig.inputs;
946+
let variadic = sig.variadic;
938947

939948
let mut bcx = cx;
940949

src/librustc_trans/trans/closure.rs

+3
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
210210
tcx.with_freevars(id, |fv| fv.iter().cloned().collect());
211211

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

214215
trans_closure(ccx,
215216
decl,
@@ -371,6 +372,8 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
371372
let lloncefn = declare::define_internal_rust_fn(ccx, &function_name,
372373
llonce_fn_ty);
373374
let sig = tcx.erase_late_bound_regions(&llonce_bare_fn_ty.sig);
375+
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
376+
374377
let (block_arena, fcx): (TypedArena<_>, FunctionContext);
375378
block_arena = TypedArena::new();
376379
fcx = new_fn_ctxt(ccx,

src/librustc_trans/trans/debuginfo/metadata.rs

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use llvm::{self, ValueRef};
2424
use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType};
2525

2626
use middle::def_id::DefId;
27+
use middle::infer;
2728
use middle::pat_util;
2829
use middle::subst::{self, Substs};
2930
use rustc::front::map as hir_map;
@@ -262,6 +263,7 @@ impl<'tcx> TypeMap<'tcx> {
262263
unique_type_id.push_str(" fn(");
263264

264265
let sig = cx.tcx().erase_late_bound_regions(sig);
266+
let sig = infer::normalize_associated_type(cx.tcx(), &sig);
265267

266268
for &parameter_type in &sig.inputs {
267269
let parameter_type_id =

src/librustc_trans/trans/debuginfo/mod.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use rustc_front::hir;
3535
use trans::common::{NodeIdAndSpan, CrateContext, FunctionContext, Block};
3636
use trans;
3737
use trans::{monomorphize, type_of};
38+
use middle::infer;
3839
use middle::ty::{self, Ty};
3940
use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
4041
use util::nodemap::{NodeMap, FnvHashMap, FnvHashSet};
@@ -418,19 +419,23 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
418419
// Return type -- llvm::DIBuilder wants this at index 0
419420
assert_type_for_node_id(cx, fn_ast_id, error_reporting_span);
420421
let fn_type = cx.tcx().node_id_to_type(fn_ast_id);
422+
let fn_type = monomorphize::apply_param_substs(cx.tcx(), param_substs, &fn_type);
421423

422424
let (sig, abi) = match fn_type.sty {
423425
ty::TyBareFn(_, ref barefnty) => {
424-
(cx.tcx().erase_late_bound_regions(&barefnty.sig), barefnty.abi)
426+
let sig = cx.tcx().erase_late_bound_regions(&barefnty.sig);
427+
let sig = infer::normalize_associated_type(cx.tcx(), &sig);
428+
(sig, barefnty.abi)
425429
}
426430
ty::TyClosure(def_id, ref substs) => {
427431
let closure_type = cx.tcx().closure_type(def_id, substs);
428-
(cx.tcx().erase_late_bound_regions(&closure_type.sig), closure_type.abi)
432+
let sig = cx.tcx().erase_late_bound_regions(&closure_type.sig);
433+
let sig = infer::normalize_associated_type(cx.tcx(), &sig);
434+
(sig, closure_type.abi)
429435
}
430436

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

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

src/librustc_trans/trans/debuginfo/type_names.rs

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use super::namespace::crate_root_namespace;
1414

1515
use trans::common::CrateContext;
1616
use middle::def_id::DefId;
17+
use middle::infer;
1718
use middle::subst::{self, Substs};
1819
use middle::ty::{self, Ty};
1920

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

126127
let sig = cx.tcx().erase_late_bound_regions(sig);
128+
let sig = infer::normalize_associated_type(cx.tcx(), &sig);
127129
if !sig.inputs.is_empty() {
128130
for &parameter_type in &sig.inputs {
129131
push_debuginfo_type_name(cx, parameter_type, true, output);

src/librustc_trans/trans/declare.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,6 @@ pub fn declare_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str,
103103
fn_type: ty::Ty<'tcx>) -> ValueRef {
104104
debug!("declare_rust_fn(name={:?}, fn_type={:?})", name,
105105
fn_type);
106-
let fn_type = infer::normalize_associated_type(ccx.tcx(), &fn_type);
107-
debug!("declare_rust_fn (after normalised associated types) fn_type={:?}",
108-
fn_type);
109106

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

127-
let sig = ty::Binder(ccx.tcx().erase_late_bound_regions(sig));
124+
let sig = ccx.tcx().erase_late_bound_regions(sig);
125+
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
128126
debug!("declare_rust_fn (after region erasure) sig={:?}", sig);
129127
let llfty = type_of::type_of_rust_fn(ccx, env, &sig, abi);
130128
debug!("declare_rust_fn llfty={}", ccx.tn().type_to_string(llfty));
131129

132130
// it is ok to directly access sig.0.output because we erased all
133131
// late-bound-regions above
134-
let llfn = declare_fn(ccx, name, llvm::CCallConv, llfty, sig.0.output);
132+
let llfn = declare_fn(ccx, name, llvm::CCallConv, llfty, sig.output);
135133
attributes::from_fn_type(ccx, fn_type).apply_llfn(llfn);
136134
llfn
137135
}

src/librustc_trans/trans/intrinsic.rs

+8-13
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use intrinsics::{self, Intrinsic};
1515
use libc;
1616
use llvm;
1717
use llvm::{SequentiallyConsistent, Acquire, Release, AtomicXchg, ValueRef, TypeKind};
18+
use middle::infer;
1819
use middle::subst;
1920
use middle::subst::FnSpace;
2021
use trans::adt;
@@ -170,13 +171,10 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
170171

171172
let _icx = push_ctxt("trans_intrinsic_call");
172173

173-
let (arg_tys, ret_ty) = match callee_ty.sty {
174-
ty::TyBareFn(_, ref f) => {
175-
(bcx.tcx().erase_late_bound_regions(&f.sig.inputs()),
176-
bcx.tcx().erase_late_bound_regions(&f.sig.output()))
177-
}
178-
_ => panic!("expected bare_fn in trans_intrinsic_call")
179-
};
174+
let sig = ccx.tcx().erase_late_bound_regions(callee_ty.fn_sig());
175+
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
176+
let arg_tys = sig.inputs;
177+
let ret_ty = sig.output;
180178
let foreign_item = tcx.map.expect_foreign_item(node);
181179
let name = foreign_item.name.as_str();
182180

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

13311329

13321330
let tcx = bcx.tcx();
1333-
let arg_tys = match callee_ty.sty {
1334-
ty::TyBareFn(_, ref f) => {
1335-
bcx.tcx().erase_late_bound_regions(&f.sig.inputs())
1336-
}
1337-
_ => unreachable!()
1338-
};
1331+
let sig = tcx.erase_late_bound_regions(callee_ty.fn_sig());
1332+
let sig = infer::normalize_associated_type(tcx, &sig);
1333+
let arg_tys = sig.inputs;
13391334

13401335
// every intrinsic takes a SIMD vector as its first argument
13411336
require_simd!(arg_tys[0], "input");

src/librustc_trans/trans/meth.rs

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use arena::TypedArena;
1212
use back::link;
1313
use llvm::{ValueRef, get_params};
1414
use middle::def_id::DefId;
15+
use middle::infer;
1516
use middle::subst::{Subst, Substs};
1617
use middle::subst::VecPerParamSpace;
1718
use middle::subst;
@@ -522,6 +523,7 @@ fn trans_object_shim<'a, 'tcx>(
522523
let llfn = declare::define_internal_rust_fn(ccx, &function_name, shim_fn_ty);
523524

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

526528
let empty_substs = tcx.mk_substs(Substs::trans_empty());
527529
let (block_arena, fcx): (TypedArena<_>, FunctionContext);

src/librustc_trans/trans/type_of.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#![allow(non_camel_case_types)]
1212

1313
use middle::def_id::DefId;
14+
use middle::infer;
1415
use middle::subst;
1516
use trans::adt;
1617
use trans::common::*;
@@ -89,24 +90,25 @@ pub fn untuple_arguments<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
8990

9091
pub fn type_of_rust_fn<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
9192
llenvironment_type: Option<Type>,
92-
sig: &ty::Binder<ty::FnSig<'tcx>>,
93+
sig: &ty::FnSig<'tcx>,
9394
abi: abi::Abi)
9495
-> Type
9596
{
9697
debug!("type_of_rust_fn(sig={:?},abi={:?})",
9798
sig,
9899
abi);
99100

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

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

105105
// First, munge the inputs, if this has the `rust-call` ABI.
106-
let inputs = &if abi == abi::RustCall {
107-
untuple_arguments(cx, &sig.inputs)
106+
let inputs_temp;
107+
let inputs = if abi == abi::RustCall {
108+
inputs_temp = untuple_arguments(cx, &sig.inputs);
109+
&inputs_temp
108110
} else {
109-
sig.inputs
111+
&sig.inputs
110112
};
111113

112114
// Arg 0: Output pointer.
@@ -155,7 +157,9 @@ pub fn type_of_fn_from_ty<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, fty: Ty<'tcx>)
155157
// FIXME(#19925) once fn item types are
156158
// zero-sized, we'll need to do something here
157159
if f.abi == abi::Rust || f.abi == abi::RustCall {
158-
type_of_rust_fn(cx, None, &f.sig, f.abi)
160+
let sig = cx.tcx().erase_late_bound_regions(&f.sig);
161+
let sig = infer::normalize_associated_type(cx.tcx(), &sig);
162+
type_of_rust_fn(cx, None, &sig, f.abi)
159163
} else {
160164
foreign::lltype_for_foreign_fn(cx, fty)
161165
}

src/test/run-pass/issue-23406.rs

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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+
trait Inner {
12+
type T;
13+
}
14+
15+
impl<'a> Inner for &'a i32 {
16+
type T = i32;
17+
}
18+
19+
fn f<'a>(x: &'a i32) -> <&'a i32 as Inner>::T {
20+
*x
21+
}
22+
23+
fn main() {}

0 commit comments

Comments
 (0)