Skip to content

Commit

Permalink
rustc_infer: remove InferCtxt::closure_sig as the FnSig is always sha…
Browse files Browse the repository at this point in the history
…llowly known.
  • Loading branch information
eddyb committed Mar 18, 2020
1 parent 7ceebd9 commit 63811bc
Show file tree
Hide file tree
Showing 15 changed files with 51 additions and 76 deletions.
4 changes: 2 additions & 2 deletions src/librustc/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -681,9 +681,9 @@ pub trait PrettyPrinter<'tcx>:

if self.tcx().sess.verbose() {
p!(write(
" closure_kind_ty={:?} closure_sig_ty={:?}",
" closure_kind_ty={:?} closure_sig_as_fn_ptr_ty={:?}",
substs.as_closure().kind_ty(did, self.tcx()),
substs.as_closure().sig_ty(did, self.tcx())
substs.as_closure().sig_as_fn_ptr_ty(did, self.tcx())
));
}

Expand Down
30 changes: 12 additions & 18 deletions src/librustc/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ pub struct ClosureSubsts<'tcx> {
/// parent slice and not canonical substs themselves.
struct SplitClosureSubsts<'tcx> {
closure_kind_ty: Ty<'tcx>,
closure_sig_ty: Ty<'tcx>,
closure_sig_as_fn_ptr_ty: Ty<'tcx>,
upvar_kinds: &'tcx [GenericArg<'tcx>],
}

Expand All @@ -384,7 +384,7 @@ impl<'tcx> ClosureSubsts<'tcx> {
let parent_len = generics.parent_count;
SplitClosureSubsts {
closure_kind_ty: self.substs.type_at(parent_len),
closure_sig_ty: self.substs.type_at(parent_len + 1),
closure_sig_as_fn_ptr_ty: self.substs.type_at(parent_len + 1),
upvar_kinds: &self.substs[parent_len + 2..],
}
}
Expand Down Expand Up @@ -412,12 +412,10 @@ impl<'tcx> ClosureSubsts<'tcx> {
self.split(def_id, tcx).closure_kind_ty
}

/// Returns the type representing the closure signature for this
/// closure; may contain type variables during inference. To get
/// the closure signature during inference, use
/// `infcx.fn_sig(def_id)`.
pub fn sig_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
self.split(def_id, tcx).closure_sig_ty
/// Returns the `fn` pointer type representing the closure signature for this
/// closure.
pub fn sig_as_fn_ptr_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
self.split(def_id, tcx).closure_sig_as_fn_ptr_ty
}

/// Returns the closure kind for this closure; only usable outside
Expand All @@ -429,16 +427,12 @@ impl<'tcx> ClosureSubsts<'tcx> {
self.split(def_id, tcx).closure_kind_ty.to_opt_closure_kind().unwrap()
}

/// Extracts the signature from the closure; only usable outside
/// of an inference context, because in that context we know that
/// there are no type variables.
///
/// If you have an inference context, use `infcx.closure_sig()`.
/// Extracts the signature from the closure.
pub fn sig(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
let ty = self.sig_ty(def_id, tcx);
let ty = self.sig_as_fn_ptr_ty(def_id, tcx);
match ty.kind {
ty::FnPtr(sig) => sig,
_ => bug!("closure_sig_ty is not a fn-ptr: {:?}", ty.kind),
_ => bug!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {:?}", ty.kind),
}
}
}
Expand Down Expand Up @@ -2200,9 +2194,9 @@ impl<'tcx> TyS<'tcx> {
// ignore errors (#54954)
ty::Binder::dummy(FnSig::fake())
}
Closure(..) => {
bug!("to get the signature of a closure, use `closure_sig()` not `fn_sig()`",)
}
Closure(..) => bug!(
"to get the signature of a closure, use `substs.as_closure().sig()` not `fn_sig()`",
),
_ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self),
}
}
Expand Down
10 changes: 0 additions & 10 deletions src/librustc_infer/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1486,16 +1486,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
closure_kind_ty.to_opt_closure_kind()
}

/// Obtains the signature of a closure. For closures, unlike
/// `tcx.fn_sig(def_id)`, this method will work during the
/// type-checking of the enclosing function and return the closure
/// signature in its partially inferred state.
pub fn closure_sig(&self, def_id: DefId, substs: SubstsRef<'tcx>) -> ty::PolyFnSig<'tcx> {
let closure_sig_ty = substs.as_closure().sig_ty(def_id, self.tcx);
let closure_sig_ty = self.shallow_resolve(closure_sig_ty);
closure_sig_ty.fn_sig(self.tcx)
}

/// Clears the selection, evaluation, and projection caches. This is useful when
/// repeatedly attempting to select an `Obligation` while changing only
/// its `ParamEnv`, since `FulfillmentContext` doesn't use probing.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1684,7 +1684,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// case it ends up being assigned into the return place.
annotated_closure = self.annotate_fn_sig(
*def_id,
self.infcx.closure_sig(*def_id, *substs),
substs.as_closure().sig(*def_id, self.infcx.tcx),
);
debug!(
"annotate_argument_and_return_for_borrow: \
Expand Down
4 changes: 1 addition & 3 deletions src/librustc_mir/borrow_check/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2083,9 +2083,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {

CastKind::Pointer(PointerCast::ClosureFnPointer(unsafety)) => {
let sig = match op.ty(*body, tcx).kind {
ty::Closure(def_id, substs) => {
substs.as_closure().sig_ty(def_id, tcx).fn_sig(tcx)
}
ty::Closure(def_id, substs) => substs.as_closure().sig(def_id, tcx),
_ => bug!(),
};
let ty_fn_ptr_from = tcx.coerce_closure_fn_ty(sig, *unsafety);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/borrow_check/universal_regions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
match defining_ty {
DefiningTy::Closure(def_id, substs) => {
assert_eq!(self.mir_def_id, def_id);
let closure_sig = substs.as_closure().sig_ty(def_id, tcx).fn_sig(tcx);
let closure_sig = substs.as_closure().sig(def_id, tcx);
let inputs_and_output = closure_sig.inputs_and_output();
let closure_ty = tcx.closure_env_ty(def_id, substs).unwrap();
ty::Binder::fuse(closure_ty, inputs_and_output, |closure_ty, inputs_and_output| {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trait_selection/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,7 @@ where
upvar_ty.visit_with(self);
}

substs.as_closure().sig_ty(def_id, self.tcx).visit_with(self);
substs.as_closure().sig_as_fn_ptr_ty(def_id, self.tcx).visit_with(self);
}

ty::Generator(def_id, ref substs, _) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
let self_ty = trait_ref.self_ty();
let (def_id, output_ty, callable) = match self_ty.kind {
ty::Closure(def_id, substs) => {
(def_id, self.closure_sig(def_id, substs).output(), "closure")
(def_id, substs.as_closure().sig(def_id, self.tcx).output(), "closure")
}
ty::FnDef(def_id, _) => (def_id, self_ty.fn_sig(self.tcx).output(), "function"),
_ => return,
Expand Down
4 changes: 1 addition & 3 deletions src/librustc_trait_selection/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1311,9 +1311,7 @@ fn confirm_closure_candidate<'cx, 'tcx>(
vtable: VtableClosureData<'tcx, PredicateObligation<'tcx>>,
) -> Progress<'tcx> {
let tcx = selcx.tcx();
let infcx = selcx.infcx();
let closure_sig_ty = vtable.substs.as_closure().sig_ty(vtable.closure_def_id, tcx);
let closure_sig = infcx.shallow_resolve(closure_sig_ty).fn_sig(tcx);
let closure_sig = vtable.substs.as_closure().sig(vtable.closure_def_id, tcx);
let Normalized { value: closure_sig, obligations } = normalize_with_depth(
selcx,
obligation.param_env,
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_trait_selection/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3349,9 +3349,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
"closure_trait_ref_unnormalized(obligation={:?}, closure_def_id={:?}, substs={:?})",
obligation, closure_def_id, substs,
);
let closure_type = self.infcx.closure_sig(closure_def_id, substs);
let closure_sig = substs.as_closure().sig(closure_def_id, self.tcx());

debug!("closure_trait_ref_unnormalized: closure_type = {:?}", closure_type);
debug!("closure_trait_ref_unnormalized: closure_sig = {:?}", closure_sig);

// (1) Feels icky to skip the binder here, but OTOH we know
// that the self-type is an unboxed closure type and hence is
Expand All @@ -3362,7 +3362,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
self.tcx(),
obligation.predicate.def_id(),
obligation.predicate.skip_binder().self_ty(), // (1)
closure_type,
closure_sig,
util::TupleArgumentsFlag::No,
)
.map_bound(|(trait_ref, _)| trait_ref)
Expand Down
10 changes: 5 additions & 5 deletions src/librustc_typeck/check/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// haven't yet decided on whether the closure is fn vs
// fnmut vs fnonce. If so, we have to defer further processing.
if self.closure_kind(def_id, substs).is_none() {
let closure_ty = self.closure_sig(def_id, substs);
let fn_sig = self
let closure_sig = substs.as_closure().sig(def_id, self.tcx);
let closure_sig = self
.replace_bound_vars_with_fresh_vars(
call_expr.span,
infer::FnCall,
&closure_ty,
&closure_sig,
)
.0;
let adjustments = autoderef.adjust_steps(self, Needs::None);
Expand All @@ -121,12 +121,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
callee_expr,
adjusted_ty,
adjustments,
fn_sig,
fn_sig: closure_sig,
closure_def_id: def_id,
closure_substs: substs,
},
);
return Some(CallStep::DeferredClosure(fn_sig));
return Some(CallStep::DeferredClosure(closure_sig));
}
}

Expand Down
19 changes: 14 additions & 5 deletions src/librustc_typeck/check/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
interior,
generator_substs.witness(expr_def_id, self.tcx),
);
return self.tcx.mk_generator(expr_def_id, substs, movability);
}

let closure_type = self.tcx.mk_closure(expr_def_id, substs);
// HACK(eddyb) this forces the types equated above into `substs` but
// it should rely on `GeneratorSubsts` providing a constructor, instead.
let substs = self.resolve_vars_if_possible(&substs);

debug!("check_closure: expr.hir_id={:?} closure_type={:?}", expr.hir_id, closure_type);
return self.tcx.mk_generator(expr_def_id, substs, movability);
}

// Tuple up the arguments and insert the resulting function type into
// the `closures` table.
Expand All @@ -144,7 +145,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.demand_eqtype(
expr.span,
sig_fn_ptr_ty,
substs.as_closure().sig_ty(expr_def_id, self.tcx),
substs.as_closure().sig_as_fn_ptr_ty(expr_def_id, self.tcx),
);

if let Some(kind) = opt_kind {
Expand All @@ -155,6 +156,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
}

// HACK(eddyb) this forces the types equated above into `substs` but
// it should rely on `ClosureSubsts` providing a constructor, instead.
let substs = self.resolve_vars_if_possible(&substs);

let closure_type = self.tcx.mk_closure(expr_def_id, substs);

debug!("check_closure: expr.hir_id={:?} closure_type={:?}", expr.hir_id, closure_type);

closure_type
}

Expand Down
4 changes: 2 additions & 2 deletions src/librustc_typeck/check/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -749,9 +749,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
// `fn(arg0,arg1,...) -> _`
// or
// `unsafe fn(arg0,arg1,...) -> _`
let sig = self.closure_sig(def_id_a, substs_a);
let closure_sig = substs_a.as_closure().sig(def_id_a, self.tcx);
let unsafety = fn_ty.unsafety();
let pointer_ty = self.tcx.coerce_closure_fn_ty(sig, unsafety);
let pointer_ty = self.tcx.coerce_closure_fn_ty(closure_sig, unsafety);
debug!("coerce_closure_to_fn(a={:?}, b={:?}, pty={:?})", a, b, pointer_ty);
self.unify_and(
pointer_ty,
Expand Down
13 changes: 1 addition & 12 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4839,18 +4839,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let hir = self.tcx.hir();
let (def_id, sig) = match found.kind {
ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)),
ty::Closure(def_id, substs) => {
// We don't use `closure_sig` to account for malformed closures like
// `|_: [_; continue]| {}` and instead we don't suggest anything.
let closure_sig_ty = substs.as_closure().sig_ty(def_id, self.tcx);
(
def_id,
match closure_sig_ty.kind {
ty::FnPtr(sig) => sig,
_ => return false,
},
)
}
ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig(def_id, self.tcx)),
_ => return false,
};

Expand Down
15 changes: 6 additions & 9 deletions src/librustc_typeck/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1527,16 +1527,13 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
// argument. In any case they are embedded within the
// closure type as part of the `ClosureSubsts`.
//
// To get
// the signature of a closure, you should use the
// `closure_sig` method on the `ClosureSubsts`:
// To get the signature of a closure, you should use the
// `sig` method on the `ClosureSubsts`:
//
// closure_substs.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()`");
// substs.as_closure().sig(def_id, tcx)
bug!(
"to get the signature of a closure, use `substs.as_closure().sig()` not `fn_sig()`",
);
}

x => {
Expand Down

0 comments on commit 63811bc

Please sign in to comment.