From 96ba514294bc36586dafbf934a1497194ae44d8b Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Fri, 31 Oct 2014 16:20:25 +0200 Subject: [PATCH] trans: use types from argument patterns instead of the function signature. This fixes ICEs caused by late-bound lifetimes ending up in argument datum types and being used in cleanup - user Drop impl's would then fail to monomorphize if the type was used to look up the impl of a method call - which happens in trans now, I presume for multidispatch. --- src/librustc/middle/trans/base.rs | 21 ++++++++----- src/librustc/middle/trans/closure.rs | 2 -- src/librustc/middle/typeck/check/writeback.rs | 1 + .../regions-no-bound-in-argument-cleanup.rs | 30 +++++++++++++++++++ 4 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 src/test/run-pass/regions-no-bound-in-argument-cleanup.rs diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index ae8f944cab100..16f406644dc43 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -50,7 +50,7 @@ use middle::trans::cleanup; use middle::trans::common::{Block, C_bool, C_bytes_in_context, C_i32, C_integral, C_nil}; use middle::trans::common::{C_null, C_struct_in_context, C_u64, C_u8, C_uint, C_undef}; use middle::trans::common::{CrateContext, ExternMap, FunctionContext}; -use middle::trans::common::{NodeInfo, Result, SubstP, monomorphize_type}; +use middle::trans::common::{NodeInfo, Result, SubstP}; use middle::trans::common::{node_id_type, param_substs, return_type_is_void}; use middle::trans::common::{tydesc_info, type_is_immediate}; use middle::trans::common::{type_is_zero_size, val_ty}; @@ -1794,7 +1794,6 @@ pub fn trans_closure(ccx: &CrateContext, param_substs: ¶m_substs, fn_ast_id: ast::NodeId, _attributes: &[ast::Attribute], - arg_types: Vec, output_type: ty::FnOutput, abi: Abi, has_env: bool, @@ -1829,9 +1828,19 @@ pub fn trans_closure(ccx: &CrateContext, // Set up arguments to the function. let monomorphized_arg_types = - arg_types.iter() - .map(|at| monomorphize_type(bcx, *at)) - .collect::>(); + decl.inputs.iter() + .map(|arg| node_id_type(bcx, arg.id)) + .collect::>(); + let monomorphized_arg_types = match is_unboxed_closure { + NotUnboxedClosure => monomorphized_arg_types, + + // Tuple up closure argument types for the "rust-call" ABI. + IsUnboxedClosure => vec![if monomorphized_arg_types.is_empty() { + ty::mk_nil() + } else { + ty::mk_tup(ccx.tcx(), monomorphized_arg_types) + }] + }; for monomorphized_arg_type in monomorphized_arg_types.iter() { debug!("trans_closure: monomorphized_arg_type: {}", ty_to_string(ccx.tcx(), *monomorphized_arg_type)); @@ -1933,7 +1942,6 @@ pub fn trans_fn(ccx: &CrateContext, debug!("trans_fn(param_substs={})", param_substs.repr(ccx.tcx())); let _icx = push_ctxt("trans_fn"); let fn_ty = ty::node_id_to_type(ccx.tcx(), id); - let arg_types = ty::ty_fn_args(fn_ty); let output_type = ty::ty_fn_ret(fn_ty); let abi = ty::ty_fn_abi(fn_ty); trans_closure(ccx, @@ -1943,7 +1951,6 @@ pub fn trans_fn(ccx: &CrateContext, param_substs, id, attrs, - arg_types, output_type, abi, false, diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index b6f45b2ccda77..717f52d739ddf 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -408,7 +408,6 @@ pub fn trans_expr_fn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, bcx.fcx.param_substs, id, [], - ty::ty_fn_args(fty), ty::ty_fn_ret(fty), ty::ty_fn_abi(fty), true, @@ -501,7 +500,6 @@ pub fn trans_unboxed_closure<'blk, 'tcx>( bcx.fcx.param_substs, id, [], - ty::ty_fn_args(function_type), ty::ty_fn_ret(function_type), ty::ty_fn_abi(function_type), true, diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs index b53318861b891..d011e807ce7dc 100644 --- a/src/librustc/middle/typeck/check/writeback.rs +++ b/src/librustc/middle/typeck/check/writeback.rs @@ -53,6 +53,7 @@ pub fn resolve_type_vars_in_fn(fcx: &FnCtxt, let mut wbcx = WritebackCx::new(fcx); wbcx.visit_block(blk); for arg in decl.inputs.iter() { + wbcx.visit_node_id(ResolvingPattern(arg.pat.span), arg.id); wbcx.visit_pat(&*arg.pat); // Privacy needs the type for the whole pattern, not just each binding diff --git a/src/test/run-pass/regions-no-bound-in-argument-cleanup.rs b/src/test/run-pass/regions-no-bound-in-argument-cleanup.rs new file mode 100644 index 0000000000000..27d9895097863 --- /dev/null +++ b/src/test/run-pass/regions-no-bound-in-argument-cleanup.rs @@ -0,0 +1,30 @@ +// Copyright 2014 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. + +#![feature(unsafe_destructor)] + +pub struct Foo; + +impl Iterator for Foo { + fn next(&mut self) -> Option { + None + } +} + +#[unsafe_destructor] +impl Drop for Foo { + fn drop(&mut self) { + self.next(); + } +} + +pub fn foo<'a>(_: Foo<&'a ()>) {} + +pub fn main() {}