Also compute implicit params in THIR.
This commit is contained in:
parent
445841cda3
commit
af128b0144
3 changed files with 98 additions and 84 deletions
|
@ -73,6 +73,8 @@ macro_rules! thir_with_elements {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const UPVAR_ENV_PARAM: ParamId = ParamId::from_u32(0);
|
||||||
|
|
||||||
thir_with_elements! {
|
thir_with_elements! {
|
||||||
arms: ArmId => Arm<'tcx> => "a{}",
|
arms: ArmId => Arm<'tcx> => "a{}",
|
||||||
blocks: BlockId => Block => "b{}",
|
blocks: BlockId => Block => "b{}",
|
||||||
|
@ -84,8 +86,8 @@ thir_with_elements! {
|
||||||
/// Description of a type-checked function parameter.
|
/// Description of a type-checked function parameter.
|
||||||
#[derive(Clone, Debug, HashStable)]
|
#[derive(Clone, Debug, HashStable)]
|
||||||
pub struct Param<'tcx> {
|
pub struct Param<'tcx> {
|
||||||
/// The pattern that appears in the parameter list.
|
/// The pattern that appears in the parameter list, or None for implicit parameters.
|
||||||
pub pat: Box<Pat<'tcx>>,
|
pub pat: Option<Box<Pat<'tcx>>>,
|
||||||
/// The possibly inferred type.
|
/// The possibly inferred type.
|
||||||
pub ty: Ty<'tcx>,
|
pub ty: Ty<'tcx>,
|
||||||
/// Span of the explicitly provided type, or None if inferred for closures.
|
/// Span of the explicitly provided type, or None if inferred for closures.
|
||||||
|
@ -93,7 +95,7 @@ pub struct Param<'tcx> {
|
||||||
/// Whether this param is `self`, and how it is bound.
|
/// Whether this param is `self`, and how it is bound.
|
||||||
pub self_kind: Option<hir::ImplicitSelfKind>,
|
pub self_kind: Option<hir::ImplicitSelfKind>,
|
||||||
/// HirId for lints.
|
/// HirId for lints.
|
||||||
pub hir_id: hir::HirId,
|
pub hir_id: Option<hir::HirId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, HashStable)]
|
#[derive(Copy, Clone, Debug, HashStable)]
|
||||||
|
|
|
@ -7,8 +7,9 @@ use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::sorted_map::SortedIndexMultiMap;
|
use rustc_data_structures::sorted_map::SortedIndexMultiMap;
|
||||||
use rustc_errors::ErrorGuaranteed;
|
use rustc_errors::ErrorGuaranteed;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_hir::{GeneratorKind, ImplicitSelfKind, Node};
|
use rustc_hir::{GeneratorKind, Node};
|
||||||
use rustc_index::vec::{Idx, IndexVec};
|
use rustc_index::vec::{Idx, IndexVec};
|
||||||
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
||||||
use rustc_middle::hir::place::PlaceBase as HirPlaceBase;
|
use rustc_middle::hir::place::PlaceBase as HirPlaceBase;
|
||||||
|
@ -16,7 +17,9 @@ use rustc_middle::middle::region;
|
||||||
use rustc_middle::mir::interpret::ConstValue;
|
use rustc_middle::mir::interpret::ConstValue;
|
||||||
use rustc_middle::mir::interpret::Scalar;
|
use rustc_middle::mir::interpret::Scalar;
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
use rustc_middle::thir::{BindingMode, Expr, ExprId, LintLevel, LocalVarId, Param, PatKind, Thir};
|
use rustc_middle::thir::{
|
||||||
|
self, BindingMode, Expr, ExprId, LintLevel, LocalVarId, Param, ParamId, PatKind, Thir,
|
||||||
|
};
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable, TypeckResults};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable, TypeckResults};
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -97,26 +100,6 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// BuildMir -- walks a crate, looking for fn items and methods to build MIR from
|
// BuildMir -- walks a crate, looking for fn items and methods to build MIR from
|
||||||
|
|
||||||
fn liberated_closure_env_ty(
|
|
||||||
tcx: TyCtxt<'_>,
|
|
||||||
closure_expr_id: hir::HirId,
|
|
||||||
body_id: hir::BodyId,
|
|
||||||
) -> Ty<'_> {
|
|
||||||
let closure_ty = tcx.typeck_body(body_id).node_type(closure_expr_id);
|
|
||||||
|
|
||||||
let ty::Closure(closure_def_id, closure_substs) = *closure_ty.kind() else {
|
|
||||||
bug!("closure expr does not have closure type: {:?}", closure_ty);
|
|
||||||
};
|
|
||||||
|
|
||||||
let bound_vars =
|
|
||||||
tcx.mk_bound_variable_kinds(std::iter::once(ty::BoundVariableKind::Region(ty::BrEnv)));
|
|
||||||
let br =
|
|
||||||
ty::BoundRegion { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind: ty::BrEnv };
|
|
||||||
let env_region = ty::ReLateBound(ty::INNERMOST, br);
|
|
||||||
let closure_env_ty = tcx.closure_env_ty(closure_def_id, closure_substs, env_region).unwrap();
|
|
||||||
tcx.erase_late_bound_regions(ty::Binder::bind_with_vars(closure_env_ty, bound_vars))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
enum BlockFrame {
|
enum BlockFrame {
|
||||||
/// Evaluation is currently within a statement.
|
/// Evaluation is currently within a statement.
|
||||||
|
@ -446,13 +429,6 @@ macro_rules! unpack {
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
/// the main entry point for building MIR for a function
|
/// the main entry point for building MIR for a function
|
||||||
|
|
||||||
struct ArgInfo<'thir, 'tcx>(
|
|
||||||
Ty<'tcx>,
|
|
||||||
Option<Span>,
|
|
||||||
Option<&'thir Param<'tcx>>,
|
|
||||||
Option<ImplicitSelfKind>,
|
|
||||||
);
|
|
||||||
|
|
||||||
fn construct_fn<'tcx>(
|
fn construct_fn<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
fn_def: ty::WithOptConstParam<LocalDefId>,
|
fn_def: ty::WithOptConstParam<LocalDefId>,
|
||||||
|
@ -483,41 +459,21 @@ fn construct_fn<'tcx>(
|
||||||
hir::Unsafety::Unsafe => Safety::FnUnsafe,
|
hir::Unsafety::Unsafe => Safety::FnUnsafe,
|
||||||
};
|
};
|
||||||
|
|
||||||
let body = tcx.hir().body(body_id);
|
|
||||||
let ty = tcx.type_of(fn_def.did);
|
|
||||||
let mut abi = fn_sig.abi;
|
let mut abi = fn_sig.abi;
|
||||||
let implicit_argument = match ty.kind() {
|
if let DefKind::Closure = tcx.def_kind(fn_def.did) {
|
||||||
ty::Closure(..) => {
|
// HACK(eddyb) Avoid having RustCall on closures,
|
||||||
// HACK(eddyb) Avoid having RustCall on closures,
|
// as it adds unnecessary (and wrong) auto-tupling.
|
||||||
// as it adds unnecessary (and wrong) auto-tupling.
|
abi = Abi::Rust;
|
||||||
abi = Abi::Rust;
|
}
|
||||||
vec![ArgInfo(liberated_closure_env_ty(tcx, fn_id, body_id), None, None, None)]
|
|
||||||
}
|
|
||||||
ty::Generator(..) => {
|
|
||||||
let gen_ty = typeck_results.node_type(fn_id);
|
|
||||||
|
|
||||||
// The resume argument may be missing, in that case we need to provide it here.
|
let arguments = &thir.params;
|
||||||
// It will always be `()` in this case.
|
|
||||||
if body.params.is_empty() {
|
|
||||||
vec![ArgInfo(gen_ty, None, None, None), ArgInfo(tcx.mk_unit(), None, None, None)]
|
|
||||||
} else {
|
|
||||||
vec![ArgInfo(gen_ty, None, None, None)]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => vec![],
|
|
||||||
};
|
|
||||||
|
|
||||||
let explicit_arguments =
|
|
||||||
thir.params.iter().map(|arg| ArgInfo(arg.ty, arg.ty_span, Some(&arg), arg.self_kind));
|
|
||||||
|
|
||||||
let arguments = implicit_argument.into_iter().chain(explicit_arguments);
|
|
||||||
|
|
||||||
let (yield_ty, return_ty) = if generator_kind.is_some() {
|
let (yield_ty, return_ty) = if generator_kind.is_some() {
|
||||||
let gen_ty = typeck_results.node_type(fn_id);
|
let gen_ty = arguments[thir::UPVAR_ENV_PARAM].ty;
|
||||||
let gen_sig = match gen_ty.kind() {
|
let gen_sig = match gen_ty.kind() {
|
||||||
ty::Generator(_, gen_substs, ..) => gen_substs.as_generator().sig(),
|
ty::Generator(_, gen_substs, ..) => gen_substs.as_generator().sig(),
|
||||||
_ => {
|
_ => {
|
||||||
span_bug!(span, "generator w/o generator type: {:?}", ty)
|
span_bug!(span, "generator w/o generator type: {:?}", gen_ty)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
(Some(gen_sig.yield_ty), gen_sig.return_ty)
|
(Some(gen_sig.yield_ty), gen_sig.return_ty)
|
||||||
|
@ -525,8 +481,6 @@ fn construct_fn<'tcx>(
|
||||||
(None, fn_sig.output())
|
(None, fn_sig.output())
|
||||||
};
|
};
|
||||||
|
|
||||||
let arguments: Vec<_> = arguments.collect();
|
|
||||||
|
|
||||||
let mut body = tcx.infer_ctxt().enter(|infcx| {
|
let mut body = tcx.infer_ctxt().enter(|infcx| {
|
||||||
let mut builder = Builder::new(
|
let mut builder = Builder::new(
|
||||||
thir,
|
thir,
|
||||||
|
@ -542,9 +496,9 @@ fn construct_fn<'tcx>(
|
||||||
);
|
);
|
||||||
|
|
||||||
let call_site_scope =
|
let call_site_scope =
|
||||||
region::Scope { id: body.value.hir_id.local_id, data: region::ScopeData::CallSite };
|
region::Scope { id: body_id.hir_id.local_id, data: region::ScopeData::CallSite };
|
||||||
let arg_scope =
|
let arg_scope =
|
||||||
region::Scope { id: body.value.hir_id.local_id, data: region::ScopeData::Arguments };
|
region::Scope { id: body_id.hir_id.local_id, data: region::ScopeData::Arguments };
|
||||||
let source_info = builder.source_info(span);
|
let source_info = builder.source_info(span);
|
||||||
let call_site_s = (call_site_scope, source_info);
|
let call_site_s = (call_site_scope, source_info);
|
||||||
unpack!(builder.in_scope(call_site_s, LintLevel::Inherited, |builder| {
|
unpack!(builder.in_scope(call_site_s, LintLevel::Inherited, |builder| {
|
||||||
|
@ -560,7 +514,7 @@ fn construct_fn<'tcx>(
|
||||||
builder.args_and_body(
|
builder.args_and_body(
|
||||||
START_BLOCK,
|
START_BLOCK,
|
||||||
fn_def.did,
|
fn_def.did,
|
||||||
&arguments,
|
arguments,
|
||||||
arg_scope,
|
arg_scope,
|
||||||
&thir[expr],
|
&thir[expr],
|
||||||
)
|
)
|
||||||
|
@ -819,18 +773,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
mut block: BasicBlock,
|
mut block: BasicBlock,
|
||||||
fn_def_id: LocalDefId,
|
fn_def_id: LocalDefId,
|
||||||
arguments: &[ArgInfo<'_, 'tcx>],
|
arguments: &IndexVec<ParamId, Param<'tcx>>,
|
||||||
argument_scope: region::Scope,
|
argument_scope: region::Scope,
|
||||||
expr: &Expr<'tcx>,
|
expr: &Expr<'tcx>,
|
||||||
) -> BlockAnd<()> {
|
) -> BlockAnd<()> {
|
||||||
// Allocate locals for the function arguments
|
// Allocate locals for the function arguments
|
||||||
for &ArgInfo(ty, _, arg_opt, _) in arguments.iter() {
|
for param in arguments.iter() {
|
||||||
let source_info =
|
let source_info =
|
||||||
SourceInfo::outermost(arg_opt.map_or(self.fn_span, |arg| arg.pat.span));
|
SourceInfo::outermost(param.pat.as_ref().map_or(self.fn_span, |pat| pat.span));
|
||||||
let arg_local = self.local_decls.push(LocalDecl::with_source_info(ty, source_info));
|
let arg_local =
|
||||||
|
self.local_decls.push(LocalDecl::with_source_info(param.ty, source_info));
|
||||||
|
|
||||||
// If this is a simple binding pattern, give debuginfo a nice name.
|
// If this is a simple binding pattern, give debuginfo a nice name.
|
||||||
if let Some(arg) = arg_opt && let Some(name) = arg.pat.simple_ident() {
|
if let Some(ref pat) = param.pat && let Some(name) = pat.simple_ident() {
|
||||||
self.var_debug_info.push(VarDebugInfo {
|
self.var_debug_info.push(VarDebugInfo {
|
||||||
name,
|
name,
|
||||||
source_info,
|
source_info,
|
||||||
|
@ -905,27 +860,28 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
|
|
||||||
let mut scope = None;
|
let mut scope = None;
|
||||||
// Bind the argument patterns
|
// Bind the argument patterns
|
||||||
for (index, arg_info) in arguments.iter().enumerate() {
|
for (index, param) in arguments.iter().enumerate() {
|
||||||
// Function arguments always get the first Local indices after the return place
|
// Function arguments always get the first Local indices after the return place
|
||||||
let local = Local::new(index + 1);
|
let local = Local::new(index + 1);
|
||||||
let place = Place::from(local);
|
let place = Place::from(local);
|
||||||
let &ArgInfo(_, opt_ty_info, arg_opt, ref self_binding) = arg_info;
|
|
||||||
|
|
||||||
// Make sure we drop (parts of) the argument even when not matched on.
|
// Make sure we drop (parts of) the argument even when not matched on.
|
||||||
self.schedule_drop(
|
self.schedule_drop(
|
||||||
arg_opt.as_ref().map_or(expr.span, |arg| arg.pat.span),
|
param.pat.as_ref().map_or(expr.span, |pat| pat.span),
|
||||||
argument_scope,
|
argument_scope,
|
||||||
local,
|
local,
|
||||||
DropKind::Value,
|
DropKind::Value,
|
||||||
);
|
);
|
||||||
|
|
||||||
let Some(arg) = arg_opt else {
|
let Some(ref pat) = param.pat else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let original_source_scope = self.source_scope;
|
let original_source_scope = self.source_scope;
|
||||||
let span = arg.pat.span;
|
let span = pat.span;
|
||||||
self.set_correct_source_scope_for_arg(arg.hir_id, original_source_scope, span);
|
if let Some(arg_hir_id) = param.hir_id {
|
||||||
match arg.pat.kind {
|
self.set_correct_source_scope_for_arg(arg_hir_id, original_source_scope, span);
|
||||||
|
}
|
||||||
|
match pat.kind {
|
||||||
// Don't introduce extra copies for simple bindings
|
// Don't introduce extra copies for simple bindings
|
||||||
PatKind::Binding {
|
PatKind::Binding {
|
||||||
mutability,
|
mutability,
|
||||||
|
@ -936,16 +892,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
} => {
|
} => {
|
||||||
self.local_decls[local].mutability = mutability;
|
self.local_decls[local].mutability = mutability;
|
||||||
self.local_decls[local].source_info.scope = self.source_scope;
|
self.local_decls[local].source_info.scope = self.source_scope;
|
||||||
self.local_decls[local].local_info = if let Some(kind) = self_binding {
|
self.local_decls[local].local_info = if let Some(kind) = param.self_kind {
|
||||||
Some(Box::new(LocalInfo::User(ClearCrossCrate::Set(
|
Some(Box::new(LocalInfo::User(ClearCrossCrate::Set(
|
||||||
BindingForm::ImplicitSelf(*kind),
|
BindingForm::ImplicitSelf(kind),
|
||||||
))))
|
))))
|
||||||
} else {
|
} else {
|
||||||
let binding_mode = ty::BindingMode::BindByValue(mutability);
|
let binding_mode = ty::BindingMode::BindByValue(mutability);
|
||||||
Some(Box::new(LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
|
Some(Box::new(LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
|
||||||
VarBindingForm {
|
VarBindingForm {
|
||||||
binding_mode,
|
binding_mode,
|
||||||
opt_ty_info,
|
opt_ty_info: param.ty_span,
|
||||||
opt_match_place: Some((None, span)),
|
opt_match_place: Some((None, span)),
|
||||||
pat_span: span,
|
pat_span: span,
|
||||||
},
|
},
|
||||||
|
@ -957,12 +913,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
scope = self.declare_bindings(
|
scope = self.declare_bindings(
|
||||||
scope,
|
scope,
|
||||||
expr.span,
|
expr.span,
|
||||||
&arg.pat,
|
&pat,
|
||||||
matches::ArmHasGuard(false),
|
matches::ArmHasGuard(false),
|
||||||
Some((Some(&place), span)),
|
Some((Some(&place), span)),
|
||||||
);
|
);
|
||||||
let place_builder = PlaceBuilder::from(local);
|
let place_builder = PlaceBuilder::from(local);
|
||||||
unpack!(block = self.place_into_pattern(block, &arg.pat, place_builder, false));
|
unpack!(block = self.place_into_pattern(block, &pat, place_builder, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.source_scope = original_source_scope;
|
self.source_scope = original_source_scope;
|
||||||
|
|
|
@ -8,6 +8,7 @@ use crate::thir::util::UserAnnotatedTyHelpers;
|
||||||
use rustc_data_structures::steal::Steal;
|
use rustc_data_structures::steal::Steal;
|
||||||
use rustc_errors::ErrorGuaranteed;
|
use rustc_errors::ErrorGuaranteed;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_hir::HirId;
|
use rustc_hir::HirId;
|
||||||
|
@ -31,8 +32,21 @@ pub(crate) fn thir_body<'tcx>(
|
||||||
|
|
||||||
let owner_id = hir.local_def_id_to_hir_id(owner_def.did);
|
let owner_id = hir.local_def_id_to_hir_id(owner_def.did);
|
||||||
if let Some(ref fn_decl) = hir.fn_decl_by_hir_id(owner_id) {
|
if let Some(ref fn_decl) = hir.fn_decl_by_hir_id(owner_id) {
|
||||||
|
let closure_env_param = cx.closure_env_param(owner_def.did, owner_id);
|
||||||
let explicit_params = cx.explicit_params(owner_id, fn_decl, body);
|
let explicit_params = cx.explicit_params(owner_id, fn_decl, body);
|
||||||
cx.thir.params = explicit_params.collect();
|
cx.thir.params = closure_env_param.into_iter().chain(explicit_params).collect();
|
||||||
|
|
||||||
|
// The resume argument may be missing, in that case we need to provide it here.
|
||||||
|
// It will always be `()` in this case.
|
||||||
|
if tcx.def_kind(owner_def.did) == DefKind::Generator && body.params.is_empty() {
|
||||||
|
cx.thir.params.push(Param {
|
||||||
|
ty: tcx.mk_unit(),
|
||||||
|
pat: None,
|
||||||
|
ty_span: None,
|
||||||
|
self_kind: None,
|
||||||
|
hir_id: None,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok((tcx.alloc_steal_thir(cx.thir), expr))
|
Ok((tcx.alloc_steal_thir(cx.thir), expr))
|
||||||
|
@ -94,6 +108,48 @@ impl<'tcx> Cx<'tcx> {
|
||||||
pat_from_hir(self.tcx, self.param_env, self.typeck_results(), p)
|
pat_from_hir(self.tcx, self.param_env, self.typeck_results(), p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn closure_env_param(&self, owner_def: LocalDefId, owner_id: HirId) -> Option<Param<'tcx>> {
|
||||||
|
match self.tcx.def_kind(owner_def) {
|
||||||
|
DefKind::Closure => {
|
||||||
|
let closure_ty = self.typeck_results.node_type(owner_id);
|
||||||
|
|
||||||
|
let ty::Closure(closure_def_id, closure_substs) = *closure_ty.kind() else {
|
||||||
|
bug!("closure expr does not have closure type: {:?}", closure_ty);
|
||||||
|
};
|
||||||
|
|
||||||
|
let bound_vars = self.tcx.mk_bound_variable_kinds(std::iter::once(
|
||||||
|
ty::BoundVariableKind::Region(ty::BrEnv),
|
||||||
|
));
|
||||||
|
let br = ty::BoundRegion {
|
||||||
|
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
|
||||||
|
kind: ty::BrEnv,
|
||||||
|
};
|
||||||
|
let env_region = ty::ReLateBound(ty::INNERMOST, br);
|
||||||
|
let closure_env_ty =
|
||||||
|
self.tcx.closure_env_ty(closure_def_id, closure_substs, env_region).unwrap();
|
||||||
|
let liberated_closure_env_ty = self.tcx.erase_late_bound_regions(
|
||||||
|
ty::Binder::bind_with_vars(closure_env_ty, bound_vars),
|
||||||
|
);
|
||||||
|
let env_param = Param {
|
||||||
|
ty: liberated_closure_env_ty,
|
||||||
|
pat: None,
|
||||||
|
ty_span: None,
|
||||||
|
self_kind: None,
|
||||||
|
hir_id: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(env_param)
|
||||||
|
}
|
||||||
|
DefKind::Generator => {
|
||||||
|
let gen_ty = self.typeck_results.node_type(owner_id);
|
||||||
|
let gen_param =
|
||||||
|
Param { ty: gen_ty, pat: None, ty_span: None, self_kind: None, hir_id: None };
|
||||||
|
Some(gen_param)
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn explicit_params<'a>(
|
fn explicit_params<'a>(
|
||||||
&'a mut self,
|
&'a mut self,
|
||||||
owner_id: HirId,
|
owner_id: HirId,
|
||||||
|
@ -128,7 +184,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let pat = self.pattern_from_hir(param.pat);
|
let pat = self.pattern_from_hir(param.pat);
|
||||||
Param { pat, ty, ty_span, self_kind, hir_id: param.hir_id }
|
Param { pat: Some(pat), ty, ty_span, self_kind, hir_id: Some(param.hir_id) }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue