Auto merge of #122500 - petrochenkov:deleg, r=fmease · rust-lang/rust@5557f8c (original) (raw)

`@@ -49,7 +49,7 @@ use rustc_errors::ErrorGuaranteed;

`

49

49

`use rustc_hir as hir;

`

50

50

`use rustc_hir::def_id::DefId;

`

51

51

`use rustc_middle::span_bug;

`

52

``

`-

use rustc_middle::ty::ResolverAstLowering;

`

``

52

`+

use rustc_middle::ty::{Asyncness, ResolverAstLowering};

`

53

53

`use rustc_span::{symbol::Ident, Span};

`

54

54

`use rustc_target::spec::abi;

`

55

55

`use std::iter;

`

`@@ -67,7 +67,7 @@ impl<'hir> LoweringContext<'_, 'hir> {

`

67

67

`return false;

`

68

68

`};

`

69

69

`if let Some(local_sig_id) = sig_id.as_local() {

`

70

``

`-

self.resolver.has_self.contains(&local_sig_id)

`

``

70

`+

self.resolver.delegation_fn_sigs[&local_sig_id].has_self

`

71

71

`} else {

`

72

72

`match self.tcx.def_kind(sig_id) {

`

73

73

`DefKind::Fn => false,

`

`@@ -82,13 +82,14 @@ impl<'hir> LoweringContext<'_, 'hir> {

`

82

82

`delegation: &Delegation,

`

83

83

`item_id: NodeId,

`

84

84

`) -> DelegationResults<'hir> {

`

85

``

`-

let span = delegation.path.segments.last().unwrap().ident.span;

`

``

85

`+

let span = self.lower_span(delegation.path.segments.last().unwrap().ident.span);

`

86

86

`let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span);

`

87

87

`match sig_id {

`

88

88

`Ok(sig_id) => {

`

89

``

`-

let decl = self.lower_delegation_decl(sig_id, span);

`

90

``

`-

let sig = self.lower_delegation_sig(span, decl);

`

91

``

`-

let body_id = self.lower_delegation_body(sig.decl, delegation);

`

``

89

`+

let (param_count, c_variadic) = self.param_count(sig_id);

`

``

90

`+

let decl = self.lower_delegation_decl(sig_id, param_count, c_variadic, span);

`

``

91

`+

let sig = self.lower_delegation_sig(sig_id, decl, span);

`

``

92

`+

let body_id = self.lower_delegation_body(delegation, param_count, span);

`

92

93

``

93

94

`let generics = self.lower_delegation_generics(span);

`

94

95

`DelegationResults { body_id, sig, generics }

`

`@@ -123,70 +124,93 @@ impl<'hir> LoweringContext<'_, 'hir> {

`

123

124

`})

`

124

125

`}

`

125

126

``

``

127

`` +

// Function parameter count, including C variadic ... if present.

``

``

128

`+

fn param_count(&self, sig_id: DefId) -> (usize, bool /c_variadic/) {

`

``

129

`+

if let Some(local_sig_id) = sig_id.as_local() {

`

``

130

`+

// Map may be filled incorrectly due to recursive delegation.

`

``

131

`+

// Error will be emmited later during HIR ty lowering.

`

``

132

`+

match self.resolver.delegation_fn_sigs.get(&local_sig_id) {

`

``

133

`+

Some(sig) => (sig.param_count, sig.c_variadic),

`

``

134

`+

None => (0, false),

`

``

135

`+

}

`

``

136

`+

} else {

`

``

137

`+

let sig = self.tcx.fn_sig(sig_id).skip_binder().skip_binder();

`

``

138

`+

(sig.inputs().len() + usize::from(sig.c_variadic), sig.c_variadic)

`

``

139

`+

}

`

``

140

`+

}

`

``

141

+

126

142

`fn lower_delegation_decl(

`

127

143

`&mut self,

`

128

144

`sig_id: DefId,

`

129

``

`-

param_span: Span,

`

``

145

`+

param_count: usize,

`

``

146

`+

c_variadic: bool,

`

``

147

`+

span: Span,

`

130

148

`) -> &'hir hir::FnDecl<'hir> {

`

131

``

`-

let args_count = if let Some(local_sig_id) = sig_id.as_local() {

`

132

``

`-

// Map may be filled incorrectly due to recursive delegation.

`

133

``

`-

// Error will be emitted later during HIR ty lowering.

`

134

``

`-

self.resolver.fn_parameter_counts.get(&local_sig_id).cloned().unwrap_or_default()

`

135

``

`-

} else {

`

136

``

`-

self.tcx.fn_arg_names(sig_id).len()

`

137

``

`-

};

`

138

``

`-

let inputs = self.arena.alloc_from_iter((0..args_count).map(|arg| hir::Ty {

`

``

149

`+

// The last parameter in C variadic functions is skipped in the signature,

`

``

150

`+

// like during regular lowering.

`

``

151

`+

let decl_param_count = param_count - c_variadic as usize;

`

``

152

`+

let inputs = self.arena.alloc_from_iter((0..decl_param_count).map(|arg| hir::Ty {

`

139

153

`hir_id: self.next_id(),

`

140

154

`kind: hir::TyKind::InferDelegation(sig_id, hir::InferDelegationKind::Input(arg)),

`

141

``

`-

span: self.lower_span(param_span),

`

``

155

`+

span,

`

142

156

`}));

`

143

157

``

144

158

`let output = self.arena.alloc(hir::Ty {

`

145

159

`hir_id: self.next_id(),

`

146

160

`kind: hir::TyKind::InferDelegation(sig_id, hir::InferDelegationKind::Output),

`

147

``

`-

span: self.lower_span(param_span),

`

``

161

`+

span,

`

148

162

`});

`

149

163

``

150

164

`self.arena.alloc(hir::FnDecl {

`

151

165

` inputs,

`

152

166

`output: hir::FnRetTy::Return(output),

`

153

``

`-

c_variadic: false,

`

``

167

`+

c_variadic,

`

154

168

`lifetime_elision_allowed: true,

`

155

169

`implicit_self: hir::ImplicitSelfKind::None,

`

156

170

`})

`

157

171

`}

`

158

172

``

159

173

`fn lower_delegation_sig(

`

160

174

`&mut self,

`

161

``

`-

span: Span,

`

``

175

`+

sig_id: DefId,

`

162

176

`decl: &'hir hir::FnDecl<'hir>,

`

``

177

`+

span: Span,

`

163

178

`) -> hir::FnSig<'hir> {

`

164

``

`-

hir::FnSig {

`

165

``

`-

decl,

`

166

``

`-

header: hir::FnHeader {

`

167

``

`-

unsafety: hir::Unsafety::Normal,

`

168

``

`-

constness: hir::Constness::NotConst,

`

169

``

`-

asyncness: hir::IsAsync::NotAsync,

`

170

``

`-

abi: abi::Abi::Rust,

`

171

``

`-

},

`

172

``

`-

span: self.lower_span(span),

`

173

``

`-

}

`

``

179

`+

let header = if let Some(local_sig_id) = sig_id.as_local() {

`

``

180

`+

match self.resolver.delegation_fn_sigs.get(&local_sig_id) {

`

``

181

`+

Some(sig) => self.lower_fn_header(sig.header),

`

``

182

`+

None => self.generate_header_error(),

`

``

183

`+

}

`

``

184

`+

} else {

`

``

185

`+

let sig = self.tcx.fn_sig(sig_id).skip_binder().skip_binder();

`

``

186

`+

let asyncness = match self.tcx.asyncness(sig_id) {

`

``

187

`+

Asyncness::Yes => hir::IsAsync::Async(span),

`

``

188

`+

Asyncness::No => hir::IsAsync::NotAsync,

`

``

189

`+

};

`

``

190

`+

hir::FnHeader {

`

``

191

`+

unsafety: sig.unsafety,

`

``

192

`+

constness: self.tcx.constness(sig_id),

`

``

193

`+

asyncness,

`

``

194

`+

abi: sig.abi,

`

``

195

`+

}

`

``

196

`+

};

`

``

197

`+

hir::FnSig { decl, header, span }

`

174

198

`}

`

175

199

``

176

``

`-

fn generate_param(&mut self, ty: &'hir hir::Ty<'hir>) -> (hir::Param<'hir>, NodeId) {

`

``

200

`+

fn generate_param(&mut self, span: Span) -> (hir::Param<'hir>, NodeId) {

`

177

201

`let pat_node_id = self.next_node_id();

`

178

202

`let pat_id = self.lower_node_id(pat_node_id);

`

179

203

`let pat = self.arena.alloc(hir::Pat {

`

180

204

`hir_id: pat_id,

`

181

205

`kind: hir::PatKind::Binding(hir::BindingMode::NONE, pat_id, Ident::empty(), None),

`

182

``

`-

span: ty.span,

`

``

206

`+

span,

`

183

207

`default_binding_modes: false,

`

184

208

`});

`

185

209

``

186

``

`-

(hir::Param { hir_id: self.next_id(), pat, ty_span: ty.span, span: ty.span }, pat_node_id)

`

``

210

`+

(hir::Param { hir_id: self.next_id(), pat, ty_span: span, span }, pat_node_id)

`

187

211

`}

`

188

212

``

189

``

`-

fn generate_arg(&mut self, ty: &'hir hir::Ty<'hir>, param_id: HirId) -> hir::Expr<'hir> {

`

``

213

`+

fn generate_arg(&mut self, param_id: HirId, span: Span) -> hir::Expr<'hir> {

`

190

214

`let segments = self.arena.alloc_from_iter(iter::once(hir::PathSegment {

`

191

215

`ident: Ident::empty(),

`

192

216

`hir_id: self.next_id(),

`

`@@ -195,20 +219,20 @@ impl<'hir> LoweringContext<'_, 'hir> {

`

195

219

`infer_args: false,

`

196

220

`}));

`

197

221

``

198

``

`-

let path =

`

199

``

`-

self.arena.alloc(hir::Path { span: ty.span, res: Res::Local(param_id), segments });

`

``

222

`+

let path = self.arena.alloc(hir::Path { span, res: Res::Local(param_id), segments });

`

200

223

``

201

224

` hir::Expr {

`

202

225

`hir_id: self.next_id(),

`

203

226

`kind: hir::ExprKind::Path(hir::QPath::Resolved(None, path)),

`

204

``

`-

span: ty.span,

`

``

227

`+

span,

`

205

228

`}

`

206

229

`}

`

207

230

``

208

231

`fn lower_delegation_body(

`

209

232

`&mut self,

`

210

``

`-

decl: &'hir hir::FnDecl<'hir>,

`

211

233

`delegation: &Delegation,

`

``

234

`+

param_count: usize,

`

``

235

`+

span: Span,

`

212

236

`) -> BodyId {

`

213

237

`let path = self.lower_qpath(

`

214

238

` delegation.id,

`

`@@ -224,8 +248,8 @@ impl<'hir> LoweringContext<'_, 'hir> {

`

224

248

`let mut parameters: Vec<hir::Param<'_>> = Vec::new();

`

225

249

`let mut args: Vec<hir::Expr<'hir>> = Vec::new();

`

226

250

``

227

``

`-

for (idx, param_ty) in decl.inputs.iter().enumerate() {

`

228

``

`-

let (param, pat_node_id) = this.generate_param(param_ty);

`

``

251

`+

for idx in 0..param_count {

`

``

252

`+

let (param, pat_node_id) = this.generate_param(span);

`

229

253

` parameters.push(param);

`

230

254

``

231

255

`let arg = if let Some(block) = block

`

`@@ -245,7 +269,7 @@ impl<'hir> LoweringContext<'_, 'hir> {

`

245

269

`}

`

246

270

`} else {

`

247

271

`let pat_hir_id = this.lower_node_id(pat_node_id);

`

248

``

`-

this.generate_arg(param_ty, pat_hir_id)

`

``

272

`+

this.generate_arg(pat_hir_id, span)

`

249

273

`};

`

250

274

` args.push(arg);

`

251

275

`}

`

`@@ -304,14 +328,25 @@ impl<'hir> LoweringContext<'_, 'hir> {

`

304

328

`implicit_self: hir::ImplicitSelfKind::None,

`

305

329

`});

`

306

330

``

307

``

`-

let sig = self.lower_delegation_sig(span, decl);

`

``

331

`+

let header = self.generate_header_error();

`

``

332

`+

let sig = hir::FnSig { decl, header, span };

`

``

333

+

308

334

`let body_id = self.lower_body(|this| {

`

309

335

`let expr =

`

310

336

` hir::Expr { hir_id: this.next_id(), kind: hir::ExprKind::Err(err), span: span };

`

311

337

`(&[], expr)

`

312

338

`});

`

313

339

`DelegationResults { generics, body_id, sig }

`

314

340

`}

`

``

341

+

``

342

`+

fn generate_header_error(&self) -> hir::FnHeader {

`

``

343

`+

hir::FnHeader {

`

``

344

`+

unsafety: hir::Unsafety::Normal,

`

``

345

`+

constness: hir::Constness::NotConst,

`

``

346

`+

asyncness: hir::IsAsync::NotAsync,

`

``

347

`+

abi: abi::Abi::Rust,

`

``

348

`+

}

`

``

349

`+

}

`

315

350

`}

`

316

351

``

317

352

`struct SelfResolver<'a> {

`