Delegation: ast lowering refactor
This commit is contained in:
parent
894f7a4ba6
commit
d30d85fd9e
2 changed files with 53 additions and 62 deletions
|
@ -66,14 +66,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
let Ok(sig_id) = sig_id else {
|
let Ok(sig_id) = sig_id else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
if let Some(local_sig_id) = sig_id.as_local() {
|
self.has_self(sig_id, span)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_self(&self, def_id: DefId, span: Span) -> bool {
|
||||||
|
if let Some(local_sig_id) = def_id.as_local() {
|
||||||
// The value may be missing due to recursive delegation.
|
// The value may be missing due to recursive delegation.
|
||||||
// Error will be emmited later during HIR ty lowering.
|
// Error will be emmited later during HIR ty lowering.
|
||||||
self.resolver.delegation_fn_sigs.get(&local_sig_id).map_or(false, |sig| sig.has_self)
|
self.resolver.delegation_fn_sigs.get(&local_sig_id).map_or(false, |sig| sig.has_self)
|
||||||
} else {
|
} else {
|
||||||
match self.tcx.def_kind(sig_id) {
|
match self.tcx.def_kind(def_id) {
|
||||||
DefKind::Fn => false,
|
DefKind::Fn => false,
|
||||||
DefKind::AssocFn => self.tcx.associated_item(sig_id).fn_has_self_parameter,
|
DefKind::AssocFn => self.tcx.associated_item(def_id).fn_has_self_parameter,
|
||||||
_ => span_bug!(span, "unexpected DefKind for delegation item"),
|
_ => span_bug!(span, "unexpected DefKind for delegation item"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,12 +111,17 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<DefId, ErrorGuaranteed> {
|
) -> Result<DefId, ErrorGuaranteed> {
|
||||||
let sig_id = if self.is_in_trait_impl { item_id } else { path_id };
|
let sig_id = if self.is_in_trait_impl { item_id } else { path_id };
|
||||||
let sig_id =
|
self.get_resolution_id(sig_id, span)
|
||||||
self.resolver.get_partial_res(sig_id).and_then(|r| r.expect_full_res().opt_def_id());
|
}
|
||||||
sig_id.ok_or_else(|| {
|
|
||||||
self.tcx
|
fn get_resolution_id(&self, node_id: NodeId, span: Span) -> Result<DefId, ErrorGuaranteed> {
|
||||||
.dcx()
|
let def_id =
|
||||||
.span_delayed_bug(span, "LoweringContext: couldn't resolve delegation item")
|
self.resolver.get_partial_res(node_id).and_then(|r| r.expect_full_res().opt_def_id());
|
||||||
|
def_id.ok_or_else(|| {
|
||||||
|
self.tcx.dcx().span_delayed_bug(
|
||||||
|
span,
|
||||||
|
format!("LoweringContext: couldn't resolve node {:?} in delegation item", node_id),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +131,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
predicates: &[],
|
predicates: &[],
|
||||||
has_where_clause_predicates: false,
|
has_where_clause_predicates: false,
|
||||||
where_clause_span: span,
|
where_clause_span: span,
|
||||||
span: span,
|
span,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,12 +231,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let path = self.arena.alloc(hir::Path { span, res: Res::Local(param_id), segments });
|
let path = self.arena.alloc(hir::Path { span, res: Res::Local(param_id), segments });
|
||||||
|
self.mk_expr(hir::ExprKind::Path(hir::QPath::Resolved(None, path)), span)
|
||||||
hir::Expr {
|
|
||||||
hir_id: self.next_id(),
|
|
||||||
kind: hir::ExprKind::Path(hir::QPath::Resolved(None, path)),
|
|
||||||
span,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_delegation_body(
|
fn lower_delegation_body(
|
||||||
|
@ -236,19 +240,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
param_count: usize,
|
param_count: usize,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> BodyId {
|
) -> BodyId {
|
||||||
let path = self.lower_qpath(
|
|
||||||
delegation.id,
|
|
||||||
&delegation.qself,
|
|
||||||
&delegation.path,
|
|
||||||
ParamMode::Optional,
|
|
||||||
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
let block = delegation.body.as_deref();
|
let block = delegation.body.as_deref();
|
||||||
|
|
||||||
self.lower_body(|this| {
|
self.lower_body(|this| {
|
||||||
let mut parameters: Vec<hir::Param<'_>> = Vec::new();
|
let mut parameters: Vec<hir::Param<'_>> = Vec::with_capacity(param_count);
|
||||||
let mut args: Vec<hir::Expr<'hir>> = Vec::new();
|
let mut args: Vec<hir::Expr<'_>> = Vec::with_capacity(param_count);
|
||||||
|
|
||||||
for idx in 0..param_count {
|
for idx in 0..param_count {
|
||||||
let (param, pat_node_id) = this.generate_param(span);
|
let (param, pat_node_id) = this.generate_param(span);
|
||||||
|
@ -264,11 +260,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
};
|
};
|
||||||
self_resolver.visit_block(block);
|
self_resolver.visit_block(block);
|
||||||
let block = this.lower_block(block, false);
|
let block = this.lower_block(block, false);
|
||||||
hir::Expr {
|
this.mk_expr(hir::ExprKind::Block(block, None), block.span)
|
||||||
hir_id: this.next_id(),
|
|
||||||
kind: hir::ExprKind::Block(block, None),
|
|
||||||
span: block.span,
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
let pat_hir_id = this.lower_node_id(pat_node_id);
|
let pat_hir_id = this.lower_node_id(pat_node_id);
|
||||||
this.generate_arg(pat_hir_id, span)
|
this.generate_arg(pat_hir_id, span)
|
||||||
|
@ -276,43 +268,41 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
args.push(arg);
|
args.push(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
let args = self.arena.alloc_from_iter(args);
|
let final_expr = this.finalize_body_lowering(delegation, args, span);
|
||||||
let final_expr = this.generate_call(path, args);
|
|
||||||
(this.arena.alloc_from_iter(parameters), final_expr)
|
(this.arena.alloc_from_iter(parameters), final_expr)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_call(
|
// Generates fully qualified call for the resulting body.
|
||||||
|
fn finalize_body_lowering(
|
||||||
&mut self,
|
&mut self,
|
||||||
path: hir::QPath<'hir>,
|
delegation: &Delegation,
|
||||||
args: &'hir [hir::Expr<'hir>],
|
args: Vec<hir::Expr<'hir>>,
|
||||||
|
span: Span,
|
||||||
) -> hir::Expr<'hir> {
|
) -> hir::Expr<'hir> {
|
||||||
let callee = self.arena.alloc(hir::Expr {
|
let path = self.lower_qpath(
|
||||||
hir_id: self.next_id(),
|
delegation.id,
|
||||||
kind: hir::ExprKind::Path(path),
|
&delegation.qself,
|
||||||
span: path.span(),
|
&delegation.path,
|
||||||
});
|
ParamMode::Optional,
|
||||||
|
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
let expr = self.arena.alloc(hir::Expr {
|
let args = self.arena.alloc_from_iter(args);
|
||||||
hir_id: self.next_id(),
|
let path_expr = self.arena.alloc(self.mk_expr(hir::ExprKind::Path(path), span));
|
||||||
kind: hir::ExprKind::Call(callee, args),
|
let call = self.arena.alloc(self.mk_expr(hir::ExprKind::Call(path_expr, args), span));
|
||||||
span: path.span(),
|
|
||||||
});
|
|
||||||
|
|
||||||
let block = self.arena.alloc(hir::Block {
|
let block = self.arena.alloc(hir::Block {
|
||||||
stmts: &[],
|
stmts: &[],
|
||||||
expr: Some(expr),
|
expr: Some(call),
|
||||||
hir_id: self.next_id(),
|
hir_id: self.next_id(),
|
||||||
rules: hir::BlockCheckMode::DefaultBlock,
|
rules: hir::BlockCheckMode::DefaultBlock,
|
||||||
span: path.span(),
|
span,
|
||||||
targeted_by_break: false,
|
targeted_by_break: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
hir::Expr {
|
self.mk_expr(hir::ExprKind::Block(block, None), span)
|
||||||
hir_id: self.next_id(),
|
|
||||||
kind: hir::ExprKind::Block(block, None),
|
|
||||||
span: path.span(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_delegation_error(
|
fn generate_delegation_error(
|
||||||
|
@ -333,11 +323,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
let header = self.generate_header_error();
|
let header = self.generate_header_error();
|
||||||
let sig = hir::FnSig { decl, header, span };
|
let sig = hir::FnSig { decl, header, span };
|
||||||
|
|
||||||
let body_id = self.lower_body(|this| {
|
let body_id = self.lower_body(|this| (&[], this.mk_expr(hir::ExprKind::Err(err), span)));
|
||||||
let expr =
|
|
||||||
hir::Expr { hir_id: this.next_id(), kind: hir::ExprKind::Err(err), span: span };
|
|
||||||
(&[], expr)
|
|
||||||
});
|
|
||||||
DelegationResults { generics, body_id, sig }
|
DelegationResults { generics, body_id, sig }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,6 +335,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
abi: abi::Abi::Rust,
|
abi: abi::Abi::Rust,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mk_expr(&mut self, kind: hir::ExprKind<'hir>, span: Span) -> hir::Expr<'hir> {
|
||||||
|
hir::Expr { hir_id: self.next_id(), kind, span }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SelfResolver<'a> {
|
struct SelfResolver<'a> {
|
||||||
|
|
|
@ -110,10 +110,10 @@ error[E0308]: mismatched types
|
||||||
--> $DIR/explicit-paths.rs:78:30
|
--> $DIR/explicit-paths.rs:78:30
|
||||||
|
|
|
|
||||||
LL | reuse <S2 as Trait>::foo1;
|
LL | reuse <S2 as Trait>::foo1;
|
||||||
| ---------------^^^^
|
| ^^^^
|
||||||
| | |
|
| |
|
||||||
| | expected `&S2`, found `&S`
|
| expected `&S2`, found `&S`
|
||||||
| arguments to this function are incorrect
|
| arguments to this function are incorrect
|
||||||
|
|
|
|
||||||
= note: expected reference `&S2`
|
= note: expected reference `&S2`
|
||||||
found reference `&S`
|
found reference `&S`
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue