make fn_sig().subst()
ICE when used with a closure
It's inefficient, and the substitution there doesn't account for the extra regions used by NLL inference, so it's a bad thing to encourage. As it happens all callers already know if they have a closure or not, from what I can tell.
This commit is contained in:
parent
d5ef3e262f
commit
b4d71ea6f8
@ -10,7 +10,7 @@
|
||||
|
||||
use hir::def_id::DefId;
|
||||
use ty::{self, Ty, TypeFoldable, Substs, TyCtxt};
|
||||
use ty::subst::{Kind, Subst};
|
||||
use ty::subst::Kind;
|
||||
use traits;
|
||||
use syntax::abi::Abi;
|
||||
use util::ppaux;
|
||||
@ -311,7 +311,7 @@ fn fn_once_adapter_instance<'a, 'tcx>(
|
||||
let self_ty = tcx.mk_closure_from_closure_substs(
|
||||
closure_did, substs);
|
||||
|
||||
let sig = tcx.fn_sig(closure_did).subst(tcx, substs.substs);
|
||||
let sig = substs.closure_sig(closure_did, tcx);
|
||||
let sig = tcx.erase_late_bound_regions_and_normalize(&sig);
|
||||
assert_eq!(sig.inputs().len(), 1);
|
||||
let substs = tcx.mk_substs([
|
||||
|
@ -29,7 +29,7 @@ use value::Value;
|
||||
use rustc::traits;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::layout::{HasDataLayout, LayoutOf};
|
||||
use rustc::ty::subst::{Kind, Subst, Substs};
|
||||
use rustc::ty::subst::{Kind, Substs};
|
||||
use rustc::hir;
|
||||
|
||||
use libc::{c_uint, c_char};
|
||||
@ -393,7 +393,7 @@ pub fn ty_fn_sig<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
ty::TyFnPtr(_) => ty.fn_sig(ccx.tcx()),
|
||||
ty::TyClosure(def_id, substs) => {
|
||||
let tcx = ccx.tcx();
|
||||
let sig = tcx.fn_sig(def_id).subst(tcx, substs.substs);
|
||||
let sig = substs.closure_sig(def_id, tcx);
|
||||
|
||||
let env_ty = tcx.closure_env_ty(def_id, substs).unwrap();
|
||||
sig.map_bound(|sig| tcx.mk_fn_sig(
|
||||
|
@ -20,7 +20,7 @@ use rustc::mir::tcx::PlaceTy;
|
||||
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc::ty::layout::{self, LayoutOf, Size};
|
||||
use rustc::ty::cast::{CastTy, IntTy};
|
||||
use rustc::ty::subst::{Kind, Substs, Subst};
|
||||
use rustc::ty::subst::{Kind, Substs};
|
||||
use rustc_apfloat::{ieee, Float, Status};
|
||||
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||
use base;
|
||||
@ -658,8 +658,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
||||
.find(|it| it.kind == ty::AssociatedKind::Method)
|
||||
.unwrap().def_id;
|
||||
// Now create its substs [Closure, Tuple]
|
||||
let input = tcx.fn_sig(def_id)
|
||||
.subst(tcx, substs.substs).input(0);
|
||||
let input = substs.closure_sig(def_id, tcx).input(0);
|
||||
let input = tcx.erase_late_bound_regions_and_normalize(&input);
|
||||
let substs = tcx.mk_substs([operand.ty, input]
|
||||
.iter().cloned().map(Kind::from));
|
||||
|
@ -12,7 +12,7 @@ use rustc::hir::def_id::DefId;
|
||||
use rustc::middle::lang_items::DropInPlaceFnLangItem;
|
||||
use rustc::traits;
|
||||
use rustc::ty::adjustment::CustomCoerceUnsized;
|
||||
use rustc::ty::subst::{Kind, Subst};
|
||||
use rustc::ty::subst::Kind;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
|
||||
pub use rustc::ty::Instance;
|
||||
@ -34,7 +34,7 @@ fn fn_once_adapter_instance<'a, 'tcx>(
|
||||
let self_ty = tcx.mk_closure_from_closure_substs(
|
||||
closure_did, substs);
|
||||
|
||||
let sig = tcx.fn_sig(closure_did).subst(tcx, substs.substs);
|
||||
let sig = substs.closure_sig(closure_did, tcx);
|
||||
let sig = tcx.erase_late_bound_regions_and_normalize(&sig);
|
||||
assert_eq!(sig.inputs().len(), 1);
|
||||
let substs = tcx.mk_substs([
|
||||
|
@ -1268,15 +1268,23 @@ fn fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
))
|
||||
}
|
||||
|
||||
NodeExpr(&hir::Expr { node: hir::ExprClosure(..), hir_id, .. }) => {
|
||||
let tables = tcx.typeck_tables_of(def_id);
|
||||
match tables.node_id_to_type(hir_id).sty {
|
||||
ty::TyClosure(closure_def_id, closure_substs) => {
|
||||
assert_eq!(def_id, closure_def_id);
|
||||
return closure_substs.closure_sig(closure_def_id, tcx);
|
||||
}
|
||||
ref t => bug!("closure with non-closure type: {:?}", t),
|
||||
}
|
||||
NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
|
||||
// In order to property accommodate regions during NLL
|
||||
// inference, `fn_sig` query only works for top-level
|
||||
// functions. This is because closures often contain erased regions
|
||||
// in their signatures that are understood by NLL inference but not other
|
||||
// parts of the system -- these do not appear in the generics and hence
|
||||
// are not properly substituted away without some care.
|
||||
//
|
||||
// To get the signature of a closure, you should use the
|
||||
// `closure_sig` method on the `ClosureSubsts`:
|
||||
//
|
||||
// closure_substs.closure_sig(def_id, tcx)
|
||||
//
|
||||
// or, inside of an inference context, you can use
|
||||
//
|
||||
// infcx.closure_sig(def_id, closure_substs)
|
||||
bug!("to get the signature of a closure, use `closure_sig()` not `fn_sig()`");
|
||||
}
|
||||
|
||||
x => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user