mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 15:23:46 +00:00
Auto merge of #98131 - JohnTitor:rollup-c17vjdy, r=JohnTitor
Rollup of 3 pull requests Successful merges: - #95118 (Implement stabilization of `#[feature(io_safety)]`.) - #98110 (Make `ExprKind::Closure` a struct variant.) - #98115 (Remove `rustc_deprecated` diagnostics) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
a4cec9742b
@ -577,7 +577,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
};
|
||||
|
||||
// The closure/generator `FnDecl` takes a single (resume) argument of type `input_ty`.
|
||||
let decl = self.arena.alloc(hir::FnDecl {
|
||||
let fn_decl = self.arena.alloc(hir::FnDecl {
|
||||
inputs: arena_vec![self; input_ty],
|
||||
output,
|
||||
c_variadic: false,
|
||||
@ -598,7 +598,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
};
|
||||
let params = arena_vec![self; param];
|
||||
|
||||
let body_id = self.lower_body(move |this| {
|
||||
let body = self.lower_body(move |this| {
|
||||
this.generator_kind = Some(hir::GeneratorKind::Async(async_gen_kind));
|
||||
|
||||
let old_ctx = this.task_context;
|
||||
@ -609,13 +609,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
});
|
||||
|
||||
// `static |_task_context| -> <ret_ty> { body }`:
|
||||
let generator_kind = hir::ExprKind::Closure(
|
||||
let generator_kind = hir::ExprKind::Closure {
|
||||
capture_clause,
|
||||
decl,
|
||||
body_id,
|
||||
self.lower_span(span),
|
||||
Some(hir::Movability::Static),
|
||||
);
|
||||
fn_decl,
|
||||
body,
|
||||
fn_decl_span: self.lower_span(span),
|
||||
movability: Some(hir::Movability::Static),
|
||||
};
|
||||
let generator = hir::Expr {
|
||||
hir_id: self.lower_node_id(closure_node_id),
|
||||
kind: generator_kind,
|
||||
@ -840,7 +840,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
body: &Expr,
|
||||
fn_decl_span: Span,
|
||||
) -> hir::ExprKind<'hir> {
|
||||
let (body_id, generator_option) = self.with_new_scopes(move |this| {
|
||||
let (body, generator_option) = self.with_new_scopes(move |this| {
|
||||
let prev = this.current_item;
|
||||
this.current_item = Some(fn_decl_span);
|
||||
let mut generator_kind = None;
|
||||
@ -858,13 +858,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
// Lower outside new scope to preserve `is_in_loop_condition`.
|
||||
let fn_decl = self.lower_fn_decl(decl, None, FnDeclKind::Closure, None);
|
||||
|
||||
hir::ExprKind::Closure(
|
||||
hir::ExprKind::Closure {
|
||||
capture_clause,
|
||||
fn_decl,
|
||||
body_id,
|
||||
self.lower_span(fn_decl_span),
|
||||
generator_option,
|
||||
)
|
||||
body,
|
||||
fn_decl_span: self.lower_span(fn_decl_span),
|
||||
movability: generator_option,
|
||||
}
|
||||
}
|
||||
|
||||
fn generator_movability_for_fn(
|
||||
@ -911,7 +911,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let outer_decl =
|
||||
FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) };
|
||||
|
||||
let body_id = self.with_new_scopes(|this| {
|
||||
let body = self.with_new_scopes(|this| {
|
||||
// FIXME(cramertj): allow `async` non-`move` closures with arguments.
|
||||
if capture_clause == CaptureBy::Ref && !decl.inputs.is_empty() {
|
||||
struct_span_err!(
|
||||
@ -950,13 +950,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
// closure argument types.
|
||||
let fn_decl = self.lower_fn_decl(&outer_decl, None, FnDeclKind::Closure, None);
|
||||
|
||||
hir::ExprKind::Closure(
|
||||
hir::ExprKind::Closure {
|
||||
capture_clause,
|
||||
fn_decl,
|
||||
body_id,
|
||||
self.lower_span(fn_decl_span),
|
||||
None,
|
||||
)
|
||||
body,
|
||||
fn_decl_span: self.lower_span(fn_decl_span),
|
||||
movability: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Destructure the LHS of complex assignments.
|
||||
|
@ -406,8 +406,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
|
||||
// Emit errors for non-staged-api crates.
|
||||
if !self.features.staged_api {
|
||||
if attr.has_name(sym::rustc_deprecated)
|
||||
|| attr.has_name(sym::unstable)
|
||||
if attr.has_name(sym::unstable)
|
||||
|| attr.has_name(sym::stable)
|
||||
|| attr.has_name(sym::rustc_const_unstable)
|
||||
|| attr.has_name(sym::rustc_const_stable)
|
||||
|
@ -720,18 +720,10 @@ where
|
||||
let is_rustc = sess.features_untracked().staged_api;
|
||||
|
||||
'outer: for attr in attrs_iter {
|
||||
if !(attr.has_name(sym::deprecated) || attr.has_name(sym::rustc_deprecated)) {
|
||||
if !attr.has_name(sym::deprecated) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// FIXME(jhpratt) remove this eventually
|
||||
if attr.has_name(sym::rustc_deprecated) {
|
||||
diagnostic
|
||||
.struct_span_err(attr.span, "`#[rustc_deprecated]` has been removed")
|
||||
.help("use `#[deprecated]` instead")
|
||||
.emit();
|
||||
}
|
||||
|
||||
let Some(meta) = attr.meta() else {
|
||||
continue;
|
||||
};
|
||||
@ -787,25 +779,6 @@ where
|
||||
continue 'outer;
|
||||
}
|
||||
}
|
||||
// FIXME(jhpratt) remove this eventually
|
||||
sym::reason if attr.has_name(sym::rustc_deprecated) => {
|
||||
if !get(mi, &mut note) {
|
||||
continue 'outer;
|
||||
}
|
||||
|
||||
let mut diag = diagnostic
|
||||
.struct_span_err(mi.span, "`reason` has been renamed");
|
||||
match note {
|
||||
Some(note) => diag.span_suggestion(
|
||||
mi.span,
|
||||
"use `note` instead",
|
||||
format!("note = \"{note}\""),
|
||||
Applicability::MachineApplicable,
|
||||
),
|
||||
None => diag.span_help(mi.span, "use `note` instead"),
|
||||
};
|
||||
diag.emit();
|
||||
}
|
||||
sym::suggestion => {
|
||||
if !sess.features_untracked().deprecated_suggestion {
|
||||
let mut diag = sess.struct_span_err(
|
||||
|
@ -896,7 +896,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
let hir_id = self.infcx.tcx.hir().local_def_id_to_hir_id(local_did);
|
||||
let expr = &self.infcx.tcx.hir().expect_expr(hir_id).kind;
|
||||
debug!("closure_span: hir_id={:?} expr={:?}", hir_id, expr);
|
||||
if let hir::ExprKind::Closure(.., body_id, args_span, _) = expr {
|
||||
if let hir::ExprKind::Closure { body, fn_decl_span, .. } = expr {
|
||||
for (captured_place, place) in self
|
||||
.infcx
|
||||
.tcx
|
||||
@ -909,11 +909,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
if target_place == place.as_ref() =>
|
||||
{
|
||||
debug!("closure_span: found captured local {:?}", place);
|
||||
let body = self.infcx.tcx.hir().body(*body_id);
|
||||
let body = self.infcx.tcx.hir().body(*body);
|
||||
let generator_kind = body.generator_kind();
|
||||
|
||||
return Some((
|
||||
*args_span,
|
||||
*fn_decl_span,
|
||||
generator_kind,
|
||||
captured_place.get_capture_kind_span(self.infcx.tcx),
|
||||
captured_place.get_path_span(self.infcx.tcx),
|
||||
|
@ -311,8 +311,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||
// Can't have BrEnv in functions, constants or generators.
|
||||
bug!("BrEnv outside of closure.");
|
||||
};
|
||||
let hir::ExprKind::Closure(_, _, _, args_span, _) =
|
||||
tcx.hir().expect_expr(self.mir_hir_id()).kind else {
|
||||
let hir::ExprKind::Closure { fn_decl_span, .. }
|
||||
= tcx.hir().expect_expr(self.mir_hir_id()).kind
|
||||
else {
|
||||
bug!("Closure is not defined by a closure expr");
|
||||
};
|
||||
let region_name = self.synthesize_region_name();
|
||||
@ -336,7 +337,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||
Some(RegionName {
|
||||
name: region_name,
|
||||
source: RegionNameSource::SynthesizedFreeEnvRegion(
|
||||
args_span,
|
||||
fn_decl_span,
|
||||
note.to_string(),
|
||||
),
|
||||
})
|
||||
@ -683,16 +684,16 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||
|
||||
let (return_span, mir_description, hir_ty) = match hir.get(mir_hir_id) {
|
||||
hir::Node::Expr(hir::Expr {
|
||||
kind: hir::ExprKind::Closure(_, return_ty, body_id, span, _),
|
||||
kind: hir::ExprKind::Closure { fn_decl, body, fn_decl_span, .. },
|
||||
..
|
||||
}) => {
|
||||
let (mut span, mut hir_ty) = match return_ty.output {
|
||||
let (mut span, mut hir_ty) = match fn_decl.output {
|
||||
hir::FnRetTy::DefaultReturn(_) => {
|
||||
(tcx.sess.source_map().end_point(*span), None)
|
||||
(tcx.sess.source_map().end_point(*fn_decl_span), None)
|
||||
}
|
||||
hir::FnRetTy::Return(hir_ty) => (return_ty.output.span(), Some(hir_ty)),
|
||||
hir::FnRetTy::Return(hir_ty) => (fn_decl.output.span(), Some(hir_ty)),
|
||||
};
|
||||
let mir_description = match hir.body(*body_id).generator_kind {
|
||||
let mir_description = match hir.body(*body).generator_kind {
|
||||
Some(hir::GeneratorKind::Async(gen)) => match gen {
|
||||
hir::AsyncGeneratorKind::Block => " of async block",
|
||||
hir::AsyncGeneratorKind::Closure => " of async closure",
|
||||
@ -822,8 +823,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||
|
||||
let yield_span = match tcx.hir().get(self.mir_hir_id()) {
|
||||
hir::Node::Expr(hir::Expr {
|
||||
kind: hir::ExprKind::Closure(_, _, _, span, _), ..
|
||||
}) => (tcx.sess.source_map().end_point(*span)),
|
||||
kind: hir::ExprKind::Closure { fn_decl_span, .. },
|
||||
..
|
||||
}) => (tcx.sess.source_map().end_point(*fn_decl_span)),
|
||||
_ => self.body.span,
|
||||
};
|
||||
|
||||
|
@ -489,11 +489,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
||||
// ==========================================================================
|
||||
|
||||
ungated!(feature, CrateLevel, template!(List: "name1, name2, ..."), DuplicatesOk),
|
||||
// FIXME(jhpratt) remove this eventually
|
||||
ungated!(
|
||||
rustc_deprecated, Normal,
|
||||
template!(List: r#"since = "version", note = "...""#), ErrorFollowing
|
||||
),
|
||||
// DuplicatesOk since it has its own validation
|
||||
ungated!(
|
||||
stable, Normal, template!(List: r#"feature = "name", since = "version""#), DuplicatesOk,
|
||||
|
@ -1652,7 +1652,7 @@ impl Expr<'_> {
|
||||
ExprKind::Let(..) => ExprPrecedence::Let,
|
||||
ExprKind::Loop(..) => ExprPrecedence::Loop,
|
||||
ExprKind::Match(..) => ExprPrecedence::Match,
|
||||
ExprKind::Closure(..) => ExprPrecedence::Closure,
|
||||
ExprKind::Closure { .. } => ExprPrecedence::Closure,
|
||||
ExprKind::Block(..) => ExprPrecedence::Block,
|
||||
ExprKind::Assign(..) => ExprPrecedence::Assign,
|
||||
ExprKind::AssignOp(..) => ExprPrecedence::AssignOp,
|
||||
@ -1712,7 +1712,7 @@ impl Expr<'_> {
|
||||
| ExprKind::Tup(..)
|
||||
| ExprKind::If(..)
|
||||
| ExprKind::Match(..)
|
||||
| ExprKind::Closure(..)
|
||||
| ExprKind::Closure { .. }
|
||||
| ExprKind::Block(..)
|
||||
| ExprKind::Repeat(..)
|
||||
| ExprKind::Array(..)
|
||||
@ -1795,7 +1795,7 @@ impl Expr<'_> {
|
||||
| ExprKind::Match(..)
|
||||
| ExprKind::MethodCall(..)
|
||||
| ExprKind::Call(..)
|
||||
| ExprKind::Closure(..)
|
||||
| ExprKind::Closure { .. }
|
||||
| ExprKind::Block(..)
|
||||
| ExprKind::Repeat(..)
|
||||
| ExprKind::Break(..)
|
||||
@ -1930,7 +1930,13 @@ pub enum ExprKind<'hir> {
|
||||
///
|
||||
/// This may also be a generator literal or an `async block` as indicated by the
|
||||
/// `Option<Movability>`.
|
||||
Closure(CaptureBy, &'hir FnDecl<'hir>, BodyId, Span, Option<Movability>),
|
||||
Closure {
|
||||
capture_clause: CaptureBy,
|
||||
fn_decl: &'hir FnDecl<'hir>,
|
||||
body: BodyId,
|
||||
fn_decl_span: Span,
|
||||
movability: Option<Movability>,
|
||||
},
|
||||
/// A block (e.g., `'label: { ... }`).
|
||||
Block(&'hir Block<'hir>, Option<Label>),
|
||||
|
||||
@ -3456,7 +3462,7 @@ impl<'hir> Node<'hir> {
|
||||
_ => None,
|
||||
},
|
||||
Node::Expr(e) => match e.kind {
|
||||
ExprKind::Closure(..) => Some(FnKind::Closure),
|
||||
ExprKind::Closure { .. } => Some(FnKind::Closure),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
|
@ -1168,14 +1168,13 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
|
||||
visitor.visit_expr(subexpression);
|
||||
walk_list!(visitor, visit_arm, arms);
|
||||
}
|
||||
ExprKind::Closure(_, ref function_declaration, body, _fn_decl_span, _gen) => visitor
|
||||
.visit_fn(
|
||||
FnKind::Closure,
|
||||
function_declaration,
|
||||
body,
|
||||
expression.span,
|
||||
expression.hir_id,
|
||||
),
|
||||
ExprKind::Closure {
|
||||
ref fn_decl,
|
||||
body,
|
||||
capture_clause: _,
|
||||
fn_decl_span: _,
|
||||
movability: _,
|
||||
} => visitor.visit_fn(FnKind::Closure, fn_decl, body, expression.span, expression.hir_id),
|
||||
ExprKind::Block(ref block, ref opt_label) => {
|
||||
walk_list!(visitor, visit_label, opt_label);
|
||||
visitor.visit_block(block);
|
||||
|
@ -1078,7 +1078,9 @@ impl<'a> State<'a> {
|
||||
// parses as the erroneous construct `if (return {})`, not `if (return) {}`.
|
||||
fn cond_needs_par(expr: &hir::Expr<'_>) -> bool {
|
||||
match expr.kind {
|
||||
hir::ExprKind::Break(..) | hir::ExprKind::Closure(..) | hir::ExprKind::Ret(..) => true,
|
||||
hir::ExprKind::Break(..) | hir::ExprKind::Closure { .. } | hir::ExprKind::Ret(..) => {
|
||||
true
|
||||
}
|
||||
_ => contains_exterior_struct_lit(expr),
|
||||
}
|
||||
}
|
||||
@ -1455,10 +1457,16 @@ impl<'a> State<'a> {
|
||||
}
|
||||
self.bclose(expr.span);
|
||||
}
|
||||
hir::ExprKind::Closure(capture_clause, ref decl, body, _fn_decl_span, _gen) => {
|
||||
hir::ExprKind::Closure {
|
||||
capture_clause,
|
||||
ref fn_decl,
|
||||
body,
|
||||
fn_decl_span: _,
|
||||
movability: _,
|
||||
} => {
|
||||
self.print_capture_clause(capture_clause);
|
||||
|
||||
self.print_closure_params(&decl, body);
|
||||
self.print_closure_params(&fn_decl, body);
|
||||
self.space();
|
||||
|
||||
// This is a bare expression.
|
||||
|
@ -988,22 +988,24 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
|
||||
}
|
||||
|
||||
if let Some(node_ty) = self.opt_node_type(expr.hir_id) {
|
||||
if let (&ExprKind::Closure(_, decl, body_id, span, _), ty::Closure(_, substs)) =
|
||||
(&expr.kind, node_ty.kind())
|
||||
if let (
|
||||
&ExprKind::Closure { fn_decl, body, fn_decl_span, .. },
|
||||
ty::Closure(_, substs),
|
||||
) = (&expr.kind, node_ty.kind())
|
||||
{
|
||||
let output = substs.as_closure().sig().output().skip_binder();
|
||||
if self.generic_arg_contains_target(output.into()) {
|
||||
let body = self.infcx.tcx.hir().body(body_id);
|
||||
let body = self.infcx.tcx.hir().body(body);
|
||||
let should_wrap_expr = if matches!(body.value.kind, ExprKind::Block(..)) {
|
||||
None
|
||||
} else {
|
||||
Some(body.value.span.shrink_to_hi())
|
||||
};
|
||||
self.update_infer_source(InferSource {
|
||||
span,
|
||||
span: fn_decl_span,
|
||||
kind: InferSourceKind::ClosureReturn {
|
||||
ty: output,
|
||||
data: &decl.output,
|
||||
data: &fn_decl.output,
|
||||
should_wrap_expr,
|
||||
},
|
||||
})
|
||||
|
@ -55,7 +55,7 @@ pub fn find_param_with_region<'tcx>(
|
||||
|
||||
// Don't perform this on closures
|
||||
match hir.get(hir_id) {
|
||||
hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => {
|
||||
hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
|
||||
return None;
|
||||
}
|
||||
_ => {}
|
||||
|
@ -2027,7 +2027,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn encode_info_for_expr(&mut self, expr: &hir::Expr<'_>) {
|
||||
if let hir::ExprKind::Closure(..) = expr.kind {
|
||||
if let hir::ExprKind::Closure { .. } = expr.kind {
|
||||
self.encode_info_for_closure(expr.hir_id);
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ fn fn_decl<'hir>(node: Node<'hir>) -> Option<&'hir FnDecl<'hir>> {
|
||||
Node::Item(Item { kind: ItemKind::Fn(sig, _, _), .. })
|
||||
| Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(sig, _), .. })
|
||||
| Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(sig, _), .. }) => Some(&sig.decl),
|
||||
Node::Expr(Expr { kind: ExprKind::Closure(_, fn_decl, ..), .. })
|
||||
Node::Expr(Expr { kind: ExprKind::Closure { fn_decl, .. }, .. })
|
||||
| Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_decl, ..), .. }) => {
|
||||
Some(fn_decl)
|
||||
}
|
||||
@ -54,7 +54,7 @@ pub fn associated_body<'hir>(node: Node<'hir>) -> Option<BodyId> {
|
||||
kind: ImplItemKind::Const(_, body) | ImplItemKind::Fn(_, body),
|
||||
..
|
||||
})
|
||||
| Node::Expr(Expr { kind: ExprKind::Closure(.., body, _, _), .. }) => Some(*body),
|
||||
| Node::Expr(Expr { kind: ExprKind::Closure { body, .. }, .. }) => Some(*body),
|
||||
|
||||
Node::AnonConst(constant) => Some(constant.body),
|
||||
|
||||
@ -285,8 +285,8 @@ impl<'hir> Map<'hir> {
|
||||
}
|
||||
Node::Field(_) => DefKind::Field,
|
||||
Node::Expr(expr) => match expr.kind {
|
||||
ExprKind::Closure(.., None) => DefKind::Closure,
|
||||
ExprKind::Closure(.., Some(_)) => DefKind::Generator,
|
||||
ExprKind::Closure { movability: None, .. } => DefKind::Closure,
|
||||
ExprKind::Closure { movability: Some(_), .. } => DefKind::Generator,
|
||||
_ => bug!("def_kind: unsupported node: {}", self.node_to_string(hir_id)),
|
||||
},
|
||||
Node::GenericParam(param) => match param.kind {
|
||||
@ -758,7 +758,7 @@ impl<'hir> Map<'hir> {
|
||||
Node::Item(_)
|
||||
| Node::ForeignItem(_)
|
||||
| Node::TraitItem(_)
|
||||
| Node::Expr(Expr { kind: ExprKind::Closure(..), .. })
|
||||
| Node::Expr(Expr { kind: ExprKind::Closure { .. }, .. })
|
||||
| Node::ImplItem(_) => return Some(hir_id),
|
||||
// Ignore `return`s on the first iteration
|
||||
Node::Expr(Expr { kind: ExprKind::Loop(..) | ExprKind::Ret(..), .. })
|
||||
|
@ -1550,7 +1550,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
Node::Item(&hir::Item { kind: ItemKind::Fn(..), .. }) => {}
|
||||
Node::TraitItem(&hir::TraitItem { kind: TraitItemKind::Fn(..), .. }) => {}
|
||||
Node::ImplItem(&hir::ImplItem { kind: ImplItemKind::Fn(..), .. }) => {}
|
||||
Node::Expr(&hir::Expr { kind: ExprKind::Closure(..), .. }) => {}
|
||||
Node::Expr(&hir::Expr { kind: ExprKind::Closure { .. }, .. }) => {}
|
||||
_ => return None,
|
||||
}
|
||||
|
||||
|
@ -68,8 +68,8 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
|
||||
|
||||
// Figure out what primary body this item has.
|
||||
let (body_id, return_ty_span, span_with_body) = match tcx.hir().get(id) {
|
||||
Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(_, decl, body_id, _, _), .. }) => {
|
||||
(*body_id, decl.output.span(), None)
|
||||
Node::Expr(hir::Expr { kind: hir::ExprKind::Closure { fn_decl, body, .. }, .. }) => {
|
||||
(*body, fn_decl.output.span(), None)
|
||||
}
|
||||
Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Fn(hir::FnSig { decl, .. }, _, body_id),
|
||||
|
@ -418,7 +418,7 @@ impl<'tcx> Cx<'tcx> {
|
||||
}
|
||||
},
|
||||
|
||||
hir::ExprKind::Closure(..) => {
|
||||
hir::ExprKind::Closure { .. } => {
|
||||
let closure_ty = self.typeck_results().expr_ty(expr);
|
||||
let (def_id, substs, movability) = match *closure_ty.kind() {
|
||||
ty::Closure(def_id, substs) => (def_id, UpvarSubsts::Closure(substs), None),
|
||||
|
@ -152,9 +152,7 @@ impl CheckAttrVisitor<'_> {
|
||||
sym::link_name => self.check_link_name(hir_id, attr, span, target),
|
||||
sym::link_section => self.check_link_section(hir_id, attr, span, target),
|
||||
sym::no_mangle => self.check_no_mangle(hir_id, attr, span, target),
|
||||
sym::deprecated | sym::rustc_deprecated => {
|
||||
self.check_deprecated(hir_id, attr, span, target)
|
||||
}
|
||||
sym::deprecated => self.check_deprecated(hir_id, attr, span, target),
|
||||
sym::macro_use | sym::macro_escape => self.check_macro_use(hir_id, attr, target),
|
||||
sym::path => self.check_generic_attr(hir_id, attr, target, &[Target::Mod]),
|
||||
sym::plugin_registrar => self.check_plugin_registrar(hir_id, attr, target),
|
||||
@ -2357,7 +2355,7 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
|
||||
|
||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
|
||||
let target = match expr.kind {
|
||||
hir::ExprKind::Closure(..) => Target::Closure,
|
||||
hir::ExprKind::Closure { .. } => Target::Closure,
|
||||
_ => Target::Expression,
|
||||
};
|
||||
|
||||
|
@ -405,7 +405,7 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
|
||||
}
|
||||
intravisit::walk_expr(self, expr);
|
||||
}
|
||||
hir::ExprKind::Closure(..) => {
|
||||
hir::ExprKind::Closure { .. } => {
|
||||
// Interesting control flow (for loops can contain labeled
|
||||
// breaks or continues)
|
||||
self.add_live_node_for_node(expr.hir_id, ExprNode(expr.span, expr.hir_id));
|
||||
@ -833,7 +833,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
|
||||
hir::ExprKind::Field(ref e, _) => self.propagate_through_expr(&e, succ),
|
||||
|
||||
hir::ExprKind::Closure(..) => {
|
||||
hir::ExprKind::Closure { .. } => {
|
||||
debug!("{:?} is an ExprKind::Closure", expr);
|
||||
|
||||
// the construction of a closure itself is not important,
|
||||
@ -1387,7 +1387,7 @@ fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr<'tcx>) {
|
||||
| hir::ExprKind::AddrOf(..)
|
||||
| hir::ExprKind::Struct(..)
|
||||
| hir::ExprKind::Repeat(..)
|
||||
| hir::ExprKind::Closure(..)
|
||||
| hir::ExprKind::Closure { .. }
|
||||
| hir::ExprKind::Path(_)
|
||||
| hir::ExprKind::Yield(..)
|
||||
| hir::ExprKind::Box(..)
|
||||
|
@ -57,14 +57,14 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
|
||||
hir::ExprKind::Loop(ref b, _, source, _) => {
|
||||
self.with_context(Loop(source), |v| v.visit_block(&b));
|
||||
}
|
||||
hir::ExprKind::Closure(_, ref function_decl, b, span, movability) => {
|
||||
hir::ExprKind::Closure { ref fn_decl, body, fn_decl_span, movability, .. } => {
|
||||
let cx = if let Some(Movability::Static) = movability {
|
||||
AsyncClosure(span)
|
||||
AsyncClosure(fn_decl_span)
|
||||
} else {
|
||||
Closure(span)
|
||||
Closure(fn_decl_span)
|
||||
};
|
||||
self.visit_fn_decl(&function_decl);
|
||||
self.with_context(cx, |v| v.visit_nested_body(b));
|
||||
self.visit_fn_decl(&fn_decl);
|
||||
self.with_context(cx, |v| v.visit_nested_body(body));
|
||||
}
|
||||
hir::ExprKind::Block(ref b, Some(_label)) => {
|
||||
self.with_context(LabeledBlock, |v| v.visit_block(&b));
|
||||
|
@ -212,7 +212,7 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
|
||||
| ExprKind::Loop(..)
|
||||
| ExprKind::Match(..)
|
||||
| ExprKind::If(..)
|
||||
| ExprKind::Closure(..)
|
||||
| ExprKind::Closure { .. }
|
||||
| ExprKind::Assign(..)
|
||||
| ExprKind::AssignOp(..)
|
||||
| ExprKind::Field(..)
|
||||
|
@ -273,7 +273,7 @@ impl<'tcx> ReachableContext<'tcx> {
|
||||
}
|
||||
hir::ImplItemKind::TyAlias(_) => {}
|
||||
},
|
||||
Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(.., body, _, _), .. }) => {
|
||||
Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { body, .. }, .. }) => {
|
||||
self.visit_nested_body(body);
|
||||
}
|
||||
// Nothing to recurse on for these
|
||||
|
@ -75,7 +75,7 @@ impl<'tcx> Visitor<'tcx> for CaptureCollector<'_, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
|
||||
if let hir::ExprKind::Closure(..) = expr.kind {
|
||||
if let hir::ExprKind::Closure { .. } = expr.kind {
|
||||
let closure_def_id = self.tcx.hir().local_def_id(expr.hir_id);
|
||||
if let Some(upvars) = self.tcx.upvars_mentioned(closure_def_id) {
|
||||
// Every capture of a closure expression is a local in scope,
|
||||
|
@ -1981,7 +1981,7 @@ fn visibility(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Visibility {
|
||||
match tcx.hir().get(hir_id) {
|
||||
// Unique types created for closures participate in type privacy checking.
|
||||
// They have visibilities inherited from the module they are defined in.
|
||||
Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(..), .. })
|
||||
Node::Expr(hir::Expr { kind: hir::ExprKind::Closure{..}, .. })
|
||||
// - AST lowering creates dummy `use` items which don't
|
||||
// get their entries in the resolver's visibility table.
|
||||
// - AST lowering also creates opaque type items with inherited visibilities.
|
||||
|
@ -1360,15 +1360,15 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
hir::ExprKind::Closure(_, ref decl, body, _fn_decl_span, _) => {
|
||||
hir::ExprKind::Closure { ref fn_decl, body, .. } => {
|
||||
let id = format!("${}", ex.hir_id);
|
||||
|
||||
// walk arg and return types
|
||||
for ty in decl.inputs {
|
||||
for ty in fn_decl.inputs {
|
||||
self.visit_ty(ty);
|
||||
}
|
||||
|
||||
if let hir::FnRetTy::Return(ref ret_ty) = decl.output {
|
||||
if let hir::FnRetTy::Return(ref ret_ty) = fn_decl.output {
|
||||
self.visit_ty(ret_ty);
|
||||
}
|
||||
|
||||
|
@ -1188,7 +1188,6 @@ symbols! {
|
||||
rustc_const_unstable,
|
||||
rustc_conversion_suggestion,
|
||||
rustc_def_path,
|
||||
rustc_deprecated,
|
||||
rustc_diagnostic_item,
|
||||
rustc_diagnostic_macros,
|
||||
rustc_dirty,
|
||||
|
@ -1084,11 +1084,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
let hir = self.tcx.hir();
|
||||
Some(match node {
|
||||
Node::Expr(&hir::Expr {
|
||||
kind: hir::ExprKind::Closure(_, ref _decl, id, span, _),
|
||||
kind: hir::ExprKind::Closure { body, fn_decl_span, .. },
|
||||
..
|
||||
}) => (
|
||||
sm.guess_head_span(span),
|
||||
hir.body(id)
|
||||
sm.guess_head_span(fn_decl_span),
|
||||
hir.body(body)
|
||||
.params
|
||||
.iter()
|
||||
.map(|arg| {
|
||||
|
@ -103,10 +103,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
})
|
||||
}),
|
||||
hir::Node::Expr(hir::Expr {
|
||||
kind: hir::ExprKind::Closure(_is_move, _, body_id, _, gen_movability),
|
||||
kind: hir::ExprKind::Closure { body, movability, .. },
|
||||
..
|
||||
}) => self.describe_generator(*body_id).or_else(|| {
|
||||
Some(if gen_movability.is_some() { "an async closure" } else { "a closure" })
|
||||
}) => self.describe_generator(*body).or_else(|| {
|
||||
Some(if movability.is_some() { "an async closure" } else { "a closure" })
|
||||
}),
|
||||
hir::Node::Expr(hir::Expr { .. }) => {
|
||||
let parent_hid = hir.get_parent_node(hir_id);
|
||||
|
@ -785,14 +785,14 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
// Get the name of the callable and the arguments to be used in the suggestion.
|
||||
let (snippet, sugg) = match hir.get_if_local(def_id) {
|
||||
Some(hir::Node::Expr(hir::Expr {
|
||||
kind: hir::ExprKind::Closure(_, decl, _, span, ..),
|
||||
kind: hir::ExprKind::Closure { fn_decl, fn_decl_span, .. },
|
||||
..
|
||||
})) => {
|
||||
err.span_label(*span, "consider calling this closure");
|
||||
err.span_label(*fn_decl_span, "consider calling this closure");
|
||||
let Some(name) = self.get_closure_name(def_id, err, &msg) else {
|
||||
return false;
|
||||
};
|
||||
let args = decl.inputs.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
|
||||
let args = fn_decl.inputs.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
|
||||
let sugg = format!("({})", args);
|
||||
(format!("{}{}", name, sugg), sugg)
|
||||
}
|
||||
|
@ -283,11 +283,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let hir_id = self.tcx.hir().get_parent_node(hir_id);
|
||||
let parent_node = self.tcx.hir().get(hir_id);
|
||||
if let (
|
||||
hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(_, _, _, sp, ..), .. }),
|
||||
hir::Node::Expr(hir::Expr {
|
||||
kind: hir::ExprKind::Closure { fn_decl_span, .. }, ..
|
||||
}),
|
||||
hir::ExprKind::Block(..),
|
||||
) = (parent_node, callee_node)
|
||||
{
|
||||
let start = sp.shrink_to_lo();
|
||||
let start = fn_decl_span.shrink_to_lo();
|
||||
let end = callee_span.shrink_to_hi();
|
||||
err.multipart_suggestion(
|
||||
"if you meant to create this closure and immediately call it, surround the \
|
||||
|
@ -124,7 +124,7 @@ pub(super) fn check_fn<'a, 'tcx>(
|
||||
..
|
||||
}) => Some(header),
|
||||
// Closures are RustCall, but they tuple their arguments, so shouldn't be checked
|
||||
Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => None,
|
||||
Node::Expr(hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => None,
|
||||
node => bug!("Item being checked wasn't a function/closure: {:?}", node),
|
||||
};
|
||||
|
||||
|
@ -1577,8 +1577,8 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
||||
let parent_id = fcx.tcx.hir().get_parent_node(id);
|
||||
let parent = fcx.tcx.hir().get(parent_id);
|
||||
if let Some(expr) = expression
|
||||
&& let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(_, _, body_id, ..), .. }) = parent
|
||||
&& !matches!(fcx.tcx.hir().get(body_id.hir_id), hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Block(..), .. }))
|
||||
&& let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure { body, .. }, .. }) = parent
|
||||
&& !matches!(fcx.tcx.hir().body(*body).value.kind, hir::ExprKind::Block(..))
|
||||
{
|
||||
fcx.suggest_missing_semicolon(&mut err, expr, expected, true);
|
||||
}
|
||||
|
@ -483,7 +483,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let param_parent = self.tcx.hir().get_parent_node(*param_hir_id);
|
||||
let Some(Node::Expr(hir::Expr {
|
||||
hir_id: expr_hir_id,
|
||||
kind: hir::ExprKind::Closure(_, closure_fn_decl, ..),
|
||||
kind: hir::ExprKind::Closure { fn_decl: closure_fn_decl, .. },
|
||||
..
|
||||
})) = self.tcx.hir().find(param_parent) else {
|
||||
return None;
|
||||
|
@ -318,8 +318,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
ExprKind::Match(discrim, arms, match_src) => {
|
||||
self.check_match(expr, &discrim, arms, expected, match_src)
|
||||
}
|
||||
ExprKind::Closure(capture, decl, body_id, _, gen) => {
|
||||
self.check_expr_closure(expr, capture, &decl, body_id, gen, expected)
|
||||
ExprKind::Closure { capture_clause, fn_decl, body, movability, .. } => {
|
||||
self.check_expr_closure(expr, capture_clause, &fn_decl, body, movability, expected)
|
||||
}
|
||||
ExprKind::Block(body, _) => self.check_block_with_expected(&body, expected),
|
||||
ExprKind::Call(callee, args) => self.check_call(expr, &callee, args, expected),
|
||||
|
@ -387,7 +387,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
continue;
|
||||
}
|
||||
|
||||
let is_closure = matches!(arg.kind, ExprKind::Closure(..));
|
||||
let is_closure = matches!(arg.kind, ExprKind::Closure { .. });
|
||||
if is_closure != check_closures {
|
||||
continue;
|
||||
}
|
||||
@ -1774,10 +1774,10 @@ fn label_fn_like<'tcx>(
|
||||
} else {
|
||||
match tcx.hir().get_if_local(def_id) {
|
||||
Some(hir::Node::Expr(hir::Expr {
|
||||
kind: hir::ExprKind::Closure(_, _, _, span, ..),
|
||||
kind: hir::ExprKind::Closure { fn_decl_span, .. },
|
||||
..
|
||||
})) => {
|
||||
let spans: MultiSpan = (*span).into();
|
||||
let spans: MultiSpan = (*fn_decl_span).into();
|
||||
|
||||
// Note: We don't point to param spans here because they overlap
|
||||
// with the closure span itself
|
||||
|
@ -121,7 +121,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
.join(", ");
|
||||
}
|
||||
Some(Node::Expr(hir::Expr {
|
||||
kind: ExprKind::Closure(_, _, body_id, _, _),
|
||||
kind: ExprKind::Closure { body: body_id, .. },
|
||||
span: full_closure_span,
|
||||
..
|
||||
})) => {
|
||||
|
@ -188,7 +188,7 @@ impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> {
|
||||
| ExprKind::If(..)
|
||||
| ExprKind::Loop(..)
|
||||
| ExprKind::Match(..)
|
||||
| ExprKind::Closure(..)
|
||||
| ExprKind::Closure { .. }
|
||||
| ExprKind::Block(..)
|
||||
| ExprKind::Assign(..)
|
||||
| ExprKind::AssignOp(..)
|
||||
@ -444,7 +444,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
|
||||
| ExprKind::Block(..)
|
||||
| ExprKind::Box(..)
|
||||
| ExprKind::Cast(..)
|
||||
| ExprKind::Closure(..)
|
||||
| ExprKind::Closure { .. }
|
||||
| ExprKind::ConstBlock(..)
|
||||
| ExprKind::DropTemps(..)
|
||||
| ExprKind::Err
|
||||
|
@ -335,7 +335,7 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
|
||||
match expr.kind {
|
||||
// Manually recurse over closures and inline consts, because they are the only
|
||||
// case of nested bodies that share the parent environment.
|
||||
hir::ExprKind::Closure(.., body, _, _)
|
||||
hir::ExprKind::Closure { body, .. }
|
||||
| hir::ExprKind::ConstBlock(hir::AnonConst { body, .. }) => {
|
||||
let body = visitor.tcx.hir().body(body);
|
||||
visitor.visit_body(body);
|
||||
|
@ -142,10 +142,10 @@ struct InferBorrowKindVisitor<'a, 'tcx> {
|
||||
impl<'a, 'tcx> Visitor<'tcx> for InferBorrowKindVisitor<'a, 'tcx> {
|
||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
|
||||
match expr.kind {
|
||||
hir::ExprKind::Closure(cc, _, body_id, _, _) => {
|
||||
hir::ExprKind::Closure { capture_clause, body: body_id, .. } => {
|
||||
let body = self.fcx.tcx.hir().body(body_id);
|
||||
self.visit_body(body);
|
||||
self.fcx.analyze_closure(expr.hir_id, expr.span, body_id, body, cc);
|
||||
self.fcx.analyze_closure(expr.hir_id, expr.span, body_id, body, capture_clause);
|
||||
}
|
||||
hir::ExprKind::ConstBlock(anon_const) => {
|
||||
let body = self.fcx.tcx.hir().body(anon_const.body);
|
||||
|
@ -262,7 +262,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
|
||||
self.fix_index_builtin_expr(e);
|
||||
|
||||
match e.kind {
|
||||
hir::ExprKind::Closure(_, _, body, _, _) => {
|
||||
hir::ExprKind::Closure { body, .. } => {
|
||||
let body = self.fcx.tcx.hir().body(body);
|
||||
for param in body.params {
|
||||
self.visit_node_id(e.span, param.hir_id);
|
||||
|
@ -295,7 +295,7 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
|
||||
if let hir::ExprKind::Closure(..) = expr.kind {
|
||||
if let hir::ExprKind::Closure { .. } = expr.kind {
|
||||
let def_id = self.tcx.hir().local_def_id(expr.hir_id);
|
||||
self.tcx.ensure().generics_of(def_id);
|
||||
// We do not call `type_of` for closures here as that
|
||||
@ -1566,7 +1566,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
|
||||
}
|
||||
}
|
||||
}
|
||||
Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => {
|
||||
Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
|
||||
Some(tcx.typeck_root_def_id(def_id))
|
||||
}
|
||||
Node::Item(item) => match item.kind {
|
||||
@ -1717,7 +1717,9 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
|
||||
// provide junk type parameter defs - the only place that
|
||||
// cares about anything but the length is instantiation,
|
||||
// and we don't do that for closures.
|
||||
if let Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(.., gen), .. }) = node {
|
||||
if let Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { movability: gen, .. }, .. }) =
|
||||
node
|
||||
{
|
||||
let dummy_args = if gen.is_some() {
|
||||
&["<resume_ty>", "<yield_ty>", "<return_ty>", "<witness>", "<upvars>"][..]
|
||||
} else {
|
||||
@ -1880,7 +1882,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
|
||||
))
|
||||
}
|
||||
|
||||
Expr(&hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => {
|
||||
Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
|
||||
// Closure signatures are not like other function
|
||||
// signatures and cannot be accessed through `fn_sig`. For
|
||||
// example, a closure signature excludes the `self`
|
||||
@ -2566,9 +2568,9 @@ fn is_foreign_item(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
||||
fn generator_kind(tcx: TyCtxt<'_>, def_id: DefId) -> Option<hir::GeneratorKind> {
|
||||
match tcx.hir().get_if_local(def_id) {
|
||||
Some(Node::Expr(&rustc_hir::Expr {
|
||||
kind: rustc_hir::ExprKind::Closure(_, _, body_id, _, _),
|
||||
kind: rustc_hir::ExprKind::Closure { body, .. },
|
||||
..
|
||||
})) => tcx.hir().body(body_id).generator_kind(),
|
||||
})) => tcx.hir().body(body).generator_kind(),
|
||||
Some(_) => None,
|
||||
_ => bug!("generator_kind applied to non-local def-id {:?}", def_id),
|
||||
}
|
||||
|
@ -405,7 +405,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
|
||||
Node::Field(field) => icx.to_ty(field.ty),
|
||||
|
||||
Node::Expr(&Expr { kind: ExprKind::Closure(..), .. }) => tcx.typeck(def_id).node_type(hir_id),
|
||||
Node::Expr(&Expr { kind: ExprKind::Closure{..}, .. }) => tcx.typeck(def_id).node_type(hir_id),
|
||||
|
||||
Node::AnonConst(_) if let Some(param) = tcx.opt_const_param_of(def_id) => {
|
||||
// We defer to `type_of` of the corresponding parameter
|
||||
@ -593,7 +593,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
|
||||
self.tcx.hir()
|
||||
}
|
||||
fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
|
||||
if let hir::ExprKind::Closure(..) = ex.kind {
|
||||
if let hir::ExprKind::Closure { .. } = ex.kind {
|
||||
let def_id = self.tcx.hir().local_def_id(ex.hir_id);
|
||||
self.check(def_id);
|
||||
}
|
||||
|
@ -437,7 +437,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
||||
self.consume_expr(base);
|
||||
}
|
||||
|
||||
hir::ExprKind::Closure(..) => {
|
||||
hir::ExprKind::Closure { .. } => {
|
||||
self.walk_captures(expr);
|
||||
}
|
||||
|
||||
|
@ -359,7 +359,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||
| hir::ExprKind::Call(..)
|
||||
| hir::ExprKind::Assign(..)
|
||||
| hir::ExprKind::AssignOp(..)
|
||||
| hir::ExprKind::Closure(..)
|
||||
| hir::ExprKind::Closure { .. }
|
||||
| hir::ExprKind::Ret(..)
|
||||
| hir::ExprKind::Unary(..)
|
||||
| hir::ExprKind::Yield(..)
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Owned and borrowed Unix-like file descriptors.
|
||||
|
||||
#![unstable(feature = "io_safety", issue = "87074")]
|
||||
#![stable(feature = "io_safety", since = "1.63.0")]
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
// `RawFd`, `AsRawFd`, etc.
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Owned and borrowed Unix-like file descriptors.
|
||||
|
||||
#![unstable(feature = "io_safety", issue = "87074")]
|
||||
#![stable(feature = "io_safety", since = "1.63.0")]
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
use super::raw::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
|
||||
@ -33,7 +33,7 @@ use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||
// because c_int is 32 bits.
|
||||
#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)]
|
||||
#[rustc_nonnull_optimization_guaranteed]
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
pub struct BorrowedFd<'fd> {
|
||||
fd: RawFd,
|
||||
_phantom: PhantomData<&'fd OwnedFd>,
|
||||
@ -54,7 +54,7 @@ pub struct BorrowedFd<'fd> {
|
||||
// because c_int is 32 bits.
|
||||
#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)]
|
||||
#[rustc_nonnull_optimization_guaranteed]
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
pub struct OwnedFd {
|
||||
fd: RawFd,
|
||||
}
|
||||
@ -67,7 +67,8 @@ impl BorrowedFd<'_> {
|
||||
/// The resource pointed to by `fd` must remain open for the duration of
|
||||
/// the returned `BorrowedFd`, and it must not have the value `-1`.
|
||||
#[inline]
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[rustc_const_stable(feature = "io_safety", since = "1.63.0")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
pub const unsafe fn borrow_raw(fd: RawFd) -> Self {
|
||||
assert!(fd != u32::MAX as RawFd);
|
||||
// SAFETY: we just asserted that the value is in the valid range and isn't `-1` (the only value bigger than `0xFF_FF_FF_FE` unsigned)
|
||||
@ -79,6 +80,7 @@ impl OwnedFd {
|
||||
/// Creates a new `OwnedFd` instance that shares the same underlying file handle
|
||||
/// as the existing `OwnedFd` instance.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
pub fn try_clone(&self) -> crate::io::Result<Self> {
|
||||
// We want to atomically duplicate this file descriptor and set the
|
||||
// CLOEXEC flag, and currently that's done via F_DUPFD_CLOEXEC. This
|
||||
@ -98,6 +100,7 @@ impl OwnedFd {
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
pub fn try_clone(&self) -> crate::io::Result<Self> {
|
||||
Err(crate::io::const_io_error!(
|
||||
crate::io::ErrorKind::Unsupported,
|
||||
@ -106,7 +109,7 @@ impl OwnedFd {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsRawFd for BorrowedFd<'_> {
|
||||
#[inline]
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
@ -114,7 +117,7 @@ impl AsRawFd for BorrowedFd<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsRawFd for OwnedFd {
|
||||
#[inline]
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
@ -122,7 +125,7 @@ impl AsRawFd for OwnedFd {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl IntoRawFd for OwnedFd {
|
||||
#[inline]
|
||||
fn into_raw_fd(self) -> RawFd {
|
||||
@ -132,7 +135,7 @@ impl IntoRawFd for OwnedFd {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl FromRawFd for OwnedFd {
|
||||
/// Constructs a new instance of `Self` from the given raw file descriptor.
|
||||
///
|
||||
@ -148,7 +151,7 @@ impl FromRawFd for OwnedFd {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl Drop for OwnedFd {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
@ -163,14 +166,14 @@ impl Drop for OwnedFd {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl fmt::Debug for BorrowedFd<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("BorrowedFd").field("fd", &self.fd).finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl fmt::Debug for OwnedFd {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("OwnedFd").field("fd", &self.fd).finish()
|
||||
@ -182,14 +185,13 @@ impl fmt::Debug for OwnedFd {
|
||||
/// This is only available on unix platforms and must be imported in order to
|
||||
/// call the method. Windows platforms have a corresponding `AsHandle` and
|
||||
/// `AsSocket` set of traits.
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
pub trait AsFd {
|
||||
/// Borrows the file descriptor.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// # #![feature(io_safety)]
|
||||
/// use std::fs::File;
|
||||
/// # use std::io;
|
||||
/// # #[cfg(target_os = "wasi")]
|
||||
@ -202,11 +204,11 @@ pub trait AsFd {
|
||||
/// let borrowed_fd: BorrowedFd<'_> = f.as_fd();
|
||||
/// # Ok::<(), io::Error>(())
|
||||
/// ```
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
fn as_fd(&self) -> BorrowedFd<'_>;
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl<T: AsFd> AsFd for &T {
|
||||
#[inline]
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
@ -214,7 +216,7 @@ impl<T: AsFd> AsFd for &T {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl<T: AsFd> AsFd for &mut T {
|
||||
#[inline]
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
@ -222,7 +224,7 @@ impl<T: AsFd> AsFd for &mut T {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsFd for BorrowedFd<'_> {
|
||||
#[inline]
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
@ -230,7 +232,7 @@ impl AsFd for BorrowedFd<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsFd for OwnedFd {
|
||||
#[inline]
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
@ -241,7 +243,7 @@ impl AsFd for OwnedFd {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsFd for fs::File {
|
||||
#[inline]
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
@ -249,7 +251,7 @@ impl AsFd for fs::File {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<fs::File> for OwnedFd {
|
||||
#[inline]
|
||||
fn from(file: fs::File) -> OwnedFd {
|
||||
@ -257,7 +259,7 @@ impl From<fs::File> for OwnedFd {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<OwnedFd> for fs::File {
|
||||
#[inline]
|
||||
fn from(owned_fd: OwnedFd) -> Self {
|
||||
@ -265,7 +267,7 @@ impl From<OwnedFd> for fs::File {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsFd for crate::net::TcpStream {
|
||||
#[inline]
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
@ -273,7 +275,7 @@ impl AsFd for crate::net::TcpStream {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<crate::net::TcpStream> for OwnedFd {
|
||||
#[inline]
|
||||
fn from(tcp_stream: crate::net::TcpStream) -> OwnedFd {
|
||||
@ -281,7 +283,7 @@ impl From<crate::net::TcpStream> for OwnedFd {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<OwnedFd> for crate::net::TcpStream {
|
||||
#[inline]
|
||||
fn from(owned_fd: OwnedFd) -> Self {
|
||||
@ -291,7 +293,7 @@ impl From<OwnedFd> for crate::net::TcpStream {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsFd for crate::net::TcpListener {
|
||||
#[inline]
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
@ -299,7 +301,7 @@ impl AsFd for crate::net::TcpListener {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<crate::net::TcpListener> for OwnedFd {
|
||||
#[inline]
|
||||
fn from(tcp_listener: crate::net::TcpListener) -> OwnedFd {
|
||||
@ -307,7 +309,7 @@ impl From<crate::net::TcpListener> for OwnedFd {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<OwnedFd> for crate::net::TcpListener {
|
||||
#[inline]
|
||||
fn from(owned_fd: OwnedFd) -> Self {
|
||||
@ -317,7 +319,7 @@ impl From<OwnedFd> for crate::net::TcpListener {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsFd for crate::net::UdpSocket {
|
||||
#[inline]
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
@ -325,7 +327,7 @@ impl AsFd for crate::net::UdpSocket {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<crate::net::UdpSocket> for OwnedFd {
|
||||
#[inline]
|
||||
fn from(udp_socket: crate::net::UdpSocket) -> OwnedFd {
|
||||
@ -333,7 +335,7 @@ impl From<crate::net::UdpSocket> for OwnedFd {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<OwnedFd> for crate::net::UdpSocket {
|
||||
#[inline]
|
||||
fn from(owned_fd: OwnedFd) -> Self {
|
||||
|
@ -1,9 +1,8 @@
|
||||
//! Owned and borrowed file descriptors.
|
||||
|
||||
#![unstable(feature = "io_safety", issue = "87074")]
|
||||
|
||||
// Tests for this module
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
pub use crate::os::fd::owned::*;
|
||||
|
@ -51,7 +51,7 @@
|
||||
mod fd;
|
||||
mod raw;
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
pub use fd::*;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use raw::*;
|
||||
|
@ -962,7 +962,7 @@ impl IntoRawFd for UnixDatagram {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsFd for UnixDatagram {
|
||||
#[inline]
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
@ -970,7 +970,7 @@ impl AsFd for UnixDatagram {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<UnixDatagram> for OwnedFd {
|
||||
#[inline]
|
||||
fn from(unix_datagram: UnixDatagram) -> OwnedFd {
|
||||
@ -978,7 +978,7 @@ impl From<UnixDatagram> for OwnedFd {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<OwnedFd> for UnixDatagram {
|
||||
#[inline]
|
||||
fn from(owned: OwnedFd) -> Self {
|
||||
|
@ -300,7 +300,7 @@ impl IntoRawFd for UnixListener {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsFd for UnixListener {
|
||||
#[inline]
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
@ -308,7 +308,7 @@ impl AsFd for UnixListener {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<OwnedFd> for UnixListener {
|
||||
#[inline]
|
||||
fn from(fd: OwnedFd) -> UnixListener {
|
||||
@ -316,7 +316,7 @@ impl From<OwnedFd> for UnixListener {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<UnixListener> for OwnedFd {
|
||||
#[inline]
|
||||
fn from(listener: UnixListener) -> OwnedFd {
|
||||
|
@ -683,7 +683,7 @@ impl IntoRawFd for UnixStream {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsFd for UnixStream {
|
||||
#[inline]
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
@ -691,7 +691,7 @@ impl AsFd for UnixStream {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<UnixStream> for OwnedFd {
|
||||
#[inline]
|
||||
fn from(unix_stream: UnixStream) -> OwnedFd {
|
||||
@ -699,7 +699,7 @@ impl From<UnixStream> for OwnedFd {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<OwnedFd> for UnixStream {
|
||||
#[inline]
|
||||
fn from(owned: OwnedFd) -> Self {
|
||||
|
@ -339,7 +339,7 @@ impl FromRawFd for process::Stdio {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<OwnedFd> for process::Stdio {
|
||||
#[inline]
|
||||
fn from(fd: OwnedFd) -> process::Stdio {
|
||||
@ -397,7 +397,7 @@ impl IntoRawFd for process::ChildStderr {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsFd for crate::process::ChildStdin {
|
||||
#[inline]
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
@ -405,7 +405,7 @@ impl AsFd for crate::process::ChildStdin {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<crate::process::ChildStdin> for OwnedFd {
|
||||
#[inline]
|
||||
fn from(child_stdin: crate::process::ChildStdin) -> OwnedFd {
|
||||
@ -413,7 +413,7 @@ impl From<crate::process::ChildStdin> for OwnedFd {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsFd for crate::process::ChildStdout {
|
||||
#[inline]
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
@ -421,7 +421,7 @@ impl AsFd for crate::process::ChildStdout {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<crate::process::ChildStdout> for OwnedFd {
|
||||
#[inline]
|
||||
fn from(child_stdout: crate::process::ChildStdout) -> OwnedFd {
|
||||
@ -429,7 +429,7 @@ impl From<crate::process::ChildStdout> for OwnedFd {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsFd for crate::process::ChildStderr {
|
||||
#[inline]
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
@ -437,7 +437,7 @@ impl AsFd for crate::process::ChildStderr {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<crate::process::ChildStderr> for OwnedFd {
|
||||
#[inline]
|
||||
fn from(child_stderr: crate::process::ChildStderr) -> OwnedFd {
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Owned and borrowed OS handles.
|
||||
|
||||
#![unstable(feature = "io_safety", issue = "87074")]
|
||||
#![stable(feature = "io_safety", since = "1.63.0")]
|
||||
|
||||
use super::raw::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
|
||||
use crate::fmt;
|
||||
@ -38,7 +38,7 @@ use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||
/// [the current process handle]: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocess#remarks
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(transparent)]
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
pub struct BorrowedHandle<'handle> {
|
||||
handle: RawHandle,
|
||||
_phantom: PhantomData<&'handle OwnedHandle>,
|
||||
@ -66,7 +66,7 @@ pub struct BorrowedHandle<'handle> {
|
||||
/// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
|
||||
/// [the current process handle]: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocess#remarks
|
||||
#[repr(transparent)]
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
pub struct OwnedHandle {
|
||||
handle: RawHandle,
|
||||
}
|
||||
@ -89,7 +89,7 @@ pub struct OwnedHandle {
|
||||
///
|
||||
/// [the current process handle]: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocess#remarks
|
||||
#[repr(transparent)]
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
#[derive(Debug)]
|
||||
pub struct HandleOrNull(OwnedHandle);
|
||||
|
||||
@ -108,7 +108,7 @@ pub struct HandleOrNull(OwnedHandle);
|
||||
///
|
||||
/// If holds a handle other than `INVALID_HANDLE_VALUE`, it will close the handle on drop.
|
||||
#[repr(transparent)]
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
#[derive(Debug)]
|
||||
pub struct HandleOrInvalid(OwnedHandle);
|
||||
|
||||
@ -117,13 +117,21 @@ pub struct HandleOrInvalid(OwnedHandle);
|
||||
// `Send` or `Sync`).
|
||||
//
|
||||
// [`HANDLE`]: std::os::windows::raw::HANDLE
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
unsafe impl Send for OwnedHandle {}
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
unsafe impl Send for HandleOrNull {}
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
unsafe impl Send for HandleOrInvalid {}
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
unsafe impl Send for BorrowedHandle<'_> {}
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
unsafe impl Sync for OwnedHandle {}
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
unsafe impl Sync for HandleOrNull {}
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
unsafe impl Sync for HandleOrInvalid {}
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
unsafe impl Sync for BorrowedHandle<'_> {}
|
||||
|
||||
impl BorrowedHandle<'_> {
|
||||
@ -142,12 +150,14 @@ impl BorrowedHandle<'_> {
|
||||
///
|
||||
/// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
|
||||
#[inline]
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[rustc_const_stable(feature = "io_safety", since = "1.63.0")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
pub const unsafe fn borrow_raw(handle: RawHandle) -> Self {
|
||||
Self { handle, _phantom: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl TryFrom<HandleOrNull> for OwnedHandle {
|
||||
type Error = NullHandleError;
|
||||
|
||||
@ -169,6 +179,7 @@ impl TryFrom<HandleOrNull> for OwnedHandle {
|
||||
impl OwnedHandle {
|
||||
/// Creates a new `OwnedHandle` instance that shares the same underlying file handle
|
||||
/// as the existing `OwnedHandle` instance.
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
pub fn try_clone(&self) -> crate::io::Result<Self> {
|
||||
self.duplicate(0, false, c::DUPLICATE_SAME_ACCESS)
|
||||
}
|
||||
@ -206,6 +217,7 @@ impl OwnedHandle {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl TryFrom<HandleOrInvalid> for OwnedHandle {
|
||||
type Error = InvalidHandleError;
|
||||
|
||||
@ -227,29 +239,29 @@ impl TryFrom<HandleOrInvalid> for OwnedHandle {
|
||||
/// This is the error type used by [`HandleOrNull`] when attempting to convert
|
||||
/// into a handle, to indicate that the value is null.
|
||||
// The empty field prevents constructing this, and allows extending it in the future.
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct NullHandleError(());
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl fmt::Display for NullHandleError {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
"A HandleOrNull could not be converted to a handle because it was null".fmt(fmt)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl crate::error::Error for NullHandleError {}
|
||||
|
||||
/// This is the error type used by [`HandleOrInvalid`] when attempting to
|
||||
/// convert into a handle, to indicate that the value is
|
||||
/// `INVALID_HANDLE_VALUE`.
|
||||
// The empty field prevents constructing this, and allows extending it in the future.
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct InvalidHandleError(());
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl fmt::Display for InvalidHandleError {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
"A HandleOrInvalid could not be converted to a handle because it was INVALID_HANDLE_VALUE"
|
||||
@ -257,9 +269,10 @@ impl fmt::Display for InvalidHandleError {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl crate::error::Error for InvalidHandleError {}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsRawHandle for BorrowedHandle<'_> {
|
||||
#[inline]
|
||||
fn as_raw_handle(&self) -> RawHandle {
|
||||
@ -267,6 +280,7 @@ impl AsRawHandle for BorrowedHandle<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsRawHandle for OwnedHandle {
|
||||
#[inline]
|
||||
fn as_raw_handle(&self) -> RawHandle {
|
||||
@ -274,6 +288,7 @@ impl AsRawHandle for OwnedHandle {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl IntoRawHandle for OwnedHandle {
|
||||
#[inline]
|
||||
fn into_raw_handle(self) -> RawHandle {
|
||||
@ -283,6 +298,7 @@ impl IntoRawHandle for OwnedHandle {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl FromRawHandle for OwnedHandle {
|
||||
#[inline]
|
||||
unsafe fn from_raw_handle(handle: RawHandle) -> Self {
|
||||
@ -305,6 +321,7 @@ impl HandleOrNull {
|
||||
/// Windows APIs use null for errors; see [here] for the full story.
|
||||
///
|
||||
/// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
#[inline]
|
||||
pub unsafe fn from_raw_handle(handle: RawHandle) -> Self {
|
||||
Self(OwnedHandle::from_raw_handle(handle))
|
||||
@ -327,12 +344,14 @@ impl HandleOrInvalid {
|
||||
/// `INVALID_HANDLE_VALUE` for errors; see [here] for the full story.
|
||||
///
|
||||
/// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
#[inline]
|
||||
pub unsafe fn from_raw_handle(handle: RawHandle) -> Self {
|
||||
Self(OwnedHandle::from_raw_handle(handle))
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl Drop for OwnedHandle {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
@ -342,12 +361,14 @@ impl Drop for OwnedHandle {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl fmt::Debug for BorrowedHandle<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("BorrowedHandle").field("handle", &self.handle).finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl fmt::Debug for OwnedHandle {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("OwnedHandle").field("handle", &self.handle).finish()
|
||||
@ -355,14 +376,13 @@ impl fmt::Debug for OwnedHandle {
|
||||
}
|
||||
|
||||
/// A trait to borrow the handle from an underlying object.
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
pub trait AsHandle {
|
||||
/// Borrows the handle.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// # #![feature(io_safety)]
|
||||
/// use std::fs::File;
|
||||
/// # use std::io;
|
||||
/// use std::os::windows::io::{AsHandle, BorrowedHandle};
|
||||
@ -371,10 +391,11 @@ pub trait AsHandle {
|
||||
/// let borrowed_handle: BorrowedHandle<'_> = f.as_handle();
|
||||
/// # Ok::<(), io::Error>(())
|
||||
/// ```
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
fn as_handle(&self) -> BorrowedHandle<'_>;
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl<T: AsHandle> AsHandle for &T {
|
||||
#[inline]
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
@ -382,7 +403,7 @@ impl<T: AsHandle> AsHandle for &T {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl<T: AsHandle> AsHandle for &mut T {
|
||||
#[inline]
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
@ -390,6 +411,7 @@ impl<T: AsHandle> AsHandle for &mut T {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsHandle for BorrowedHandle<'_> {
|
||||
#[inline]
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
@ -397,6 +419,7 @@ impl AsHandle for BorrowedHandle<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsHandle for OwnedHandle {
|
||||
#[inline]
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
@ -407,6 +430,7 @@ impl AsHandle for OwnedHandle {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsHandle for fs::File {
|
||||
#[inline]
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
@ -414,6 +438,7 @@ impl AsHandle for fs::File {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<fs::File> for OwnedHandle {
|
||||
#[inline]
|
||||
fn from(file: fs::File) -> OwnedHandle {
|
||||
@ -421,6 +446,7 @@ impl From<fs::File> for OwnedHandle {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<OwnedHandle> for fs::File {
|
||||
#[inline]
|
||||
fn from(owned: OwnedHandle) -> Self {
|
||||
@ -428,6 +454,7 @@ impl From<OwnedHandle> for fs::File {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsHandle for crate::io::Stdin {
|
||||
#[inline]
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
@ -435,6 +462,7 @@ impl AsHandle for crate::io::Stdin {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl<'a> AsHandle for crate::io::StdinLock<'a> {
|
||||
#[inline]
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
@ -442,6 +470,7 @@ impl<'a> AsHandle for crate::io::StdinLock<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsHandle for crate::io::Stdout {
|
||||
#[inline]
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
@ -449,6 +478,7 @@ impl AsHandle for crate::io::Stdout {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl<'a> AsHandle for crate::io::StdoutLock<'a> {
|
||||
#[inline]
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
@ -456,6 +486,7 @@ impl<'a> AsHandle for crate::io::StdoutLock<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsHandle for crate::io::Stderr {
|
||||
#[inline]
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
@ -463,6 +494,7 @@ impl AsHandle for crate::io::Stderr {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl<'a> AsHandle for crate::io::StderrLock<'a> {
|
||||
#[inline]
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
@ -470,6 +502,7 @@ impl<'a> AsHandle for crate::io::StderrLock<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsHandle for crate::process::ChildStdin {
|
||||
#[inline]
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
@ -477,6 +510,7 @@ impl AsHandle for crate::process::ChildStdin {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<crate::process::ChildStdin> for OwnedHandle {
|
||||
#[inline]
|
||||
fn from(child_stdin: crate::process::ChildStdin) -> OwnedHandle {
|
||||
@ -484,6 +518,7 @@ impl From<crate::process::ChildStdin> for OwnedHandle {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsHandle for crate::process::ChildStdout {
|
||||
#[inline]
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
@ -491,6 +526,7 @@ impl AsHandle for crate::process::ChildStdout {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<crate::process::ChildStdout> for OwnedHandle {
|
||||
#[inline]
|
||||
fn from(child_stdout: crate::process::ChildStdout) -> OwnedHandle {
|
||||
@ -498,6 +534,7 @@ impl From<crate::process::ChildStdout> for OwnedHandle {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsHandle for crate::process::ChildStderr {
|
||||
#[inline]
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
@ -505,6 +542,7 @@ impl AsHandle for crate::process::ChildStderr {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<crate::process::ChildStderr> for OwnedHandle {
|
||||
#[inline]
|
||||
fn from(child_stderr: crate::process::ChildStderr) -> OwnedHandle {
|
||||
@ -512,6 +550,7 @@ impl From<crate::process::ChildStderr> for OwnedHandle {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl<T> AsHandle for crate::thread::JoinHandle<T> {
|
||||
#[inline]
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
@ -519,6 +558,7 @@ impl<T> AsHandle for crate::thread::JoinHandle<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl<T> From<crate::thread::JoinHandle<T>> for OwnedHandle {
|
||||
#[inline]
|
||||
fn from(join_handle: crate::thread::JoinHandle<T>) -> OwnedHandle {
|
||||
|
@ -48,11 +48,11 @@ mod handle;
|
||||
mod raw;
|
||||
mod socket;
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
pub use handle::*;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use raw::*;
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
pub use socket::*;
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Owned and borrowed OS sockets.
|
||||
|
||||
#![unstable(feature = "io_safety", issue = "87074")]
|
||||
#![stable(feature = "io_safety", since = "1.63.0")]
|
||||
|
||||
use super::raw::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};
|
||||
use crate::fmt;
|
||||
@ -36,7 +36,7 @@ use crate::sys::cvt;
|
||||
rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE)
|
||||
)]
|
||||
#[rustc_nonnull_optimization_guaranteed]
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
pub struct BorrowedSocket<'socket> {
|
||||
socket: RawSocket,
|
||||
_phantom: PhantomData<&'socket OwnedSocket>,
|
||||
@ -59,7 +59,7 @@ pub struct BorrowedSocket<'socket> {
|
||||
rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE)
|
||||
)]
|
||||
#[rustc_nonnull_optimization_guaranteed]
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
pub struct OwnedSocket {
|
||||
socket: RawSocket,
|
||||
}
|
||||
@ -73,7 +73,8 @@ impl BorrowedSocket<'_> {
|
||||
/// the returned `BorrowedSocket`, and it must not have the value
|
||||
/// `INVALID_SOCKET`.
|
||||
#[inline]
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[rustc_const_stable(feature = "io_safety", since = "1.63.0")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
pub const unsafe fn borrow_raw(socket: RawSocket) -> Self {
|
||||
assert!(socket != c::INVALID_SOCKET as RawSocket);
|
||||
Self { socket, _phantom: PhantomData }
|
||||
@ -83,6 +84,7 @@ impl BorrowedSocket<'_> {
|
||||
impl OwnedSocket {
|
||||
/// Creates a new `OwnedSocket` instance that shares the same underlying socket
|
||||
/// as the existing `OwnedSocket` instance.
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
pub fn try_clone(&self) -> io::Result<Self> {
|
||||
let mut info = unsafe { mem::zeroed::<c::WSAPROTOCOL_INFO>() };
|
||||
let result = unsafe {
|
||||
@ -152,6 +154,7 @@ fn last_error() -> io::Error {
|
||||
io::Error::from_raw_os_error(unsafe { c::WSAGetLastError() })
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsRawSocket for BorrowedSocket<'_> {
|
||||
#[inline]
|
||||
fn as_raw_socket(&self) -> RawSocket {
|
||||
@ -159,6 +162,7 @@ impl AsRawSocket for BorrowedSocket<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsRawSocket for OwnedSocket {
|
||||
#[inline]
|
||||
fn as_raw_socket(&self) -> RawSocket {
|
||||
@ -166,6 +170,7 @@ impl AsRawSocket for OwnedSocket {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl IntoRawSocket for OwnedSocket {
|
||||
#[inline]
|
||||
fn into_raw_socket(self) -> RawSocket {
|
||||
@ -175,6 +180,7 @@ impl IntoRawSocket for OwnedSocket {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl FromRawSocket for OwnedSocket {
|
||||
#[inline]
|
||||
unsafe fn from_raw_socket(socket: RawSocket) -> Self {
|
||||
@ -183,6 +189,7 @@ impl FromRawSocket for OwnedSocket {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl Drop for OwnedSocket {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
@ -192,12 +199,14 @@ impl Drop for OwnedSocket {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl fmt::Debug for BorrowedSocket<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("BorrowedSocket").field("socket", &self.socket).finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl fmt::Debug for OwnedSocket {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("OwnedSocket").field("socket", &self.socket).finish()
|
||||
@ -205,13 +214,14 @@ impl fmt::Debug for OwnedSocket {
|
||||
}
|
||||
|
||||
/// A trait to borrow the socket from an underlying object.
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
pub trait AsSocket {
|
||||
/// Borrows the socket.
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
fn as_socket(&self) -> BorrowedSocket<'_>;
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl<T: AsSocket> AsSocket for &T {
|
||||
#[inline]
|
||||
fn as_socket(&self) -> BorrowedSocket<'_> {
|
||||
@ -219,7 +229,7 @@ impl<T: AsSocket> AsSocket for &T {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl<T: AsSocket> AsSocket for &mut T {
|
||||
#[inline]
|
||||
fn as_socket(&self) -> BorrowedSocket<'_> {
|
||||
@ -227,6 +237,7 @@ impl<T: AsSocket> AsSocket for &mut T {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsSocket for BorrowedSocket<'_> {
|
||||
#[inline]
|
||||
fn as_socket(&self) -> BorrowedSocket<'_> {
|
||||
@ -234,6 +245,7 @@ impl AsSocket for BorrowedSocket<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsSocket for OwnedSocket {
|
||||
#[inline]
|
||||
fn as_socket(&self) -> BorrowedSocket<'_> {
|
||||
@ -244,6 +256,7 @@ impl AsSocket for OwnedSocket {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsSocket for crate::net::TcpStream {
|
||||
#[inline]
|
||||
fn as_socket(&self) -> BorrowedSocket<'_> {
|
||||
@ -251,6 +264,7 @@ impl AsSocket for crate::net::TcpStream {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<crate::net::TcpStream> for OwnedSocket {
|
||||
#[inline]
|
||||
fn from(tcp_stream: crate::net::TcpStream) -> OwnedSocket {
|
||||
@ -258,6 +272,7 @@ impl From<crate::net::TcpStream> for OwnedSocket {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<OwnedSocket> for crate::net::TcpStream {
|
||||
#[inline]
|
||||
fn from(owned: OwnedSocket) -> Self {
|
||||
@ -265,6 +280,7 @@ impl From<OwnedSocket> for crate::net::TcpStream {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsSocket for crate::net::TcpListener {
|
||||
#[inline]
|
||||
fn as_socket(&self) -> BorrowedSocket<'_> {
|
||||
@ -272,6 +288,7 @@ impl AsSocket for crate::net::TcpListener {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<crate::net::TcpListener> for OwnedSocket {
|
||||
#[inline]
|
||||
fn from(tcp_listener: crate::net::TcpListener) -> OwnedSocket {
|
||||
@ -279,6 +296,7 @@ impl From<crate::net::TcpListener> for OwnedSocket {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<OwnedSocket> for crate::net::TcpListener {
|
||||
#[inline]
|
||||
fn from(owned: OwnedSocket) -> Self {
|
||||
@ -286,6 +304,7 @@ impl From<OwnedSocket> for crate::net::TcpListener {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsSocket for crate::net::UdpSocket {
|
||||
#[inline]
|
||||
fn as_socket(&self) -> BorrowedSocket<'_> {
|
||||
@ -293,6 +312,7 @@ impl AsSocket for crate::net::UdpSocket {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<crate::net::UdpSocket> for OwnedSocket {
|
||||
#[inline]
|
||||
fn from(udp_socket: crate::net::UdpSocket) -> OwnedSocket {
|
||||
@ -300,6 +320,7 @@ impl From<crate::net::UdpSocket> for OwnedSocket {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<OwnedSocket> for crate::net::UdpSocket {
|
||||
#[inline]
|
||||
fn from(owned: OwnedSocket) -> Self {
|
||||
|
@ -22,7 +22,7 @@ impl FromRawHandle for process::Stdio {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<OwnedHandle> for process::Stdio {
|
||||
fn from(handle: OwnedHandle) -> process::Stdio {
|
||||
let handle = sys::handle::Handle::from_inner(handle);
|
||||
@ -39,7 +39,7 @@ impl AsRawHandle for process::Child {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsHandle for process::Child {
|
||||
#[inline]
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
@ -54,7 +54,7 @@ impl IntoRawHandle for process::Child {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<process::Child> for OwnedHandle {
|
||||
fn from(child: process::Child) -> OwnedHandle {
|
||||
child.into_inner().into_handle().into_inner()
|
||||
|
@ -92,7 +92,7 @@ pub fn panic_output() -> Option<impl io::Write> {
|
||||
Some(Stderr::new())
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsFd for io::Stdin {
|
||||
#[inline]
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
@ -100,7 +100,7 @@ impl AsFd for io::Stdin {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl<'a> AsFd for io::StdinLock<'a> {
|
||||
#[inline]
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
@ -108,7 +108,7 @@ impl<'a> AsFd for io::StdinLock<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsFd for io::Stdout {
|
||||
#[inline]
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
@ -116,7 +116,7 @@ impl AsFd for io::Stdout {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl<'a> AsFd for io::StdoutLock<'a> {
|
||||
#[inline]
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
@ -124,7 +124,7 @@ impl<'a> AsFd for io::StdoutLock<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsFd for io::Stderr {
|
||||
#[inline]
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
@ -132,7 +132,7 @@ impl AsFd for io::Stderr {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "io_safety", issue = "87074")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl<'a> AsFd for io::StderrLock<'a> {
|
||||
#[inline]
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
|
@ -1,13 +0,0 @@
|
||||
// compile-flags: --crate-type=lib
|
||||
|
||||
#![feature(staged_api)]
|
||||
#![stable(since = "1.0.0", feature = "rust1")]
|
||||
|
||||
#[rustc_deprecated( //~ ERROR `#[rustc_deprecated]` has been removed
|
||||
//~^ HELP use `#[deprecated]` instead
|
||||
since = "1.100.0",
|
||||
reason = "text" //~ ERROR `reason` has been renamed
|
||||
//~^ HELP use `note` instead
|
||||
)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn foo() {}
|
@ -1,21 +0,0 @@
|
||||
error: `#[rustc_deprecated]` has been removed
|
||||
--> $DIR/rustc_deprecated.rs:6:1
|
||||
|
|
||||
LL | / #[rustc_deprecated(
|
||||
LL | |
|
||||
LL | | since = "1.100.0",
|
||||
LL | | reason = "text"
|
||||
LL | |
|
||||
LL | | )]
|
||||
| |__^
|
||||
|
|
||||
= help: use `#[deprecated]` instead
|
||||
|
||||
error: `reason` has been renamed
|
||||
--> $DIR/rustc_deprecated.rs:9:5
|
||||
|
|
||||
LL | reason = "text"
|
||||
| ^^^^^^^^^^^^^^^ help: use `note` instead: `note = "text"`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -69,7 +69,6 @@
|
||||
#![link_section = "1800"]
|
||||
//~^ WARN attribute should be applied to a function or static
|
||||
//~^^ WARN this was previously accepted by the compiler
|
||||
// see issue-43106-gating-of-rustc_deprecated.rs
|
||||
#![must_use]
|
||||
//~^ WARN `#[must_use]` has no effect
|
||||
// see issue-43106-gating-of-stable.rs
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -51,7 +51,7 @@ struct ExVisitor<'a, 'tcx> {
|
||||
|
||||
impl<'a, 'tcx> Visitor<'tcx> for ExVisitor<'a, 'tcx> {
|
||||
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
|
||||
if let ExprKind::Closure(_, _, eid, _, _) = expr.kind {
|
||||
if let ExprKind::Closure { body, .. } = expr.kind {
|
||||
// do not lint if the closure is called using an iterator (see #1141)
|
||||
if_chain! {
|
||||
if let Some(parent) = get_parent_expr(self.cx, expr);
|
||||
@ -64,7 +64,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ExVisitor<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
let body = self.cx.tcx.hir().body(eid);
|
||||
let body = self.cx.tcx.hir().body(body);
|
||||
let ex = &body.value;
|
||||
if let ExprKind::Block(block, _) = ex.kind {
|
||||
if !body.value.span.from_expansion() && !block.stmts.is_empty() {
|
||||
|
@ -51,8 +51,8 @@ impl<'tcx> LateLintPass<'tcx> for ByteCount {
|
||||
if count.ident.name == sym::count;
|
||||
if let ExprKind::MethodCall(filter, [filter_recv, filter_arg], _) = count_recv.kind;
|
||||
if filter.ident.name == sym!(filter);
|
||||
if let ExprKind::Closure(_, _, body_id, _, _) = filter_arg.kind;
|
||||
let body = cx.tcx.hir().body(body_id);
|
||||
if let ExprKind::Closure { body, .. } = filter_arg.kind;
|
||||
let body = cx.tcx.hir().body(body);
|
||||
if let [param] = body.params;
|
||||
if let PatKind::Binding(_, arg_id, _, _) = strip_pat_refs(param.pat).kind;
|
||||
if let ExprKind::Binary(ref op, l, r) = body.value.kind;
|
||||
|
@ -498,7 +498,7 @@ fn is_linted_explicit_deref_position(parent: Option<Node<'_>>, child_id: HirId,
|
||||
| ExprKind::Loop(..)
|
||||
| ExprKind::Match(..)
|
||||
| ExprKind::Let(..)
|
||||
| ExprKind::Closure(..)
|
||||
| ExprKind::Closure{..}
|
||||
| ExprKind::Block(..)
|
||||
| ExprKind::Assign(..)
|
||||
| ExprKind::AssignOp(..)
|
||||
|
@ -78,7 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
|
||||
return;
|
||||
}
|
||||
let body = match expr.kind {
|
||||
ExprKind::Closure(_, _, id, _, _) => cx.tcx.hir().body(id),
|
||||
ExprKind::Closure { body, .. } => cx.tcx.hir().body(body),
|
||||
_ => return,
|
||||
};
|
||||
if body.value.span.from_expansion() {
|
||||
|
@ -158,8 +158,8 @@ fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
|
||||
}
|
||||
}
|
||||
if method.ident.name == sym!(flat_map) && args.len() == 2 {
|
||||
if let ExprKind::Closure(_, _, body_id, _, _) = args[1].kind {
|
||||
let body = cx.tcx.hir().body(body_id);
|
||||
if let ExprKind::Closure { body, .. } = args[1].kind {
|
||||
let body = cx.tcx.hir().body(body);
|
||||
return is_infinite(cx, &body.value);
|
||||
}
|
||||
}
|
||||
|
@ -369,8 +369,8 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
|
||||
self.visit_expr(expr);
|
||||
}
|
||||
},
|
||||
ExprKind::Closure(_, _, body_id, ..) => {
|
||||
let body = self.cx.tcx.hir().body(body_id);
|
||||
ExprKind::Closure { body, .. } => {
|
||||
let body = self.cx.tcx.hir().body(body);
|
||||
self.visit_expr(&body.value);
|
||||
},
|
||||
_ => walk_expr(self, expr),
|
||||
|
@ -182,7 +182,7 @@ fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult {
|
||||
.fold(NeverLoopResult::Otherwise, combine_both),
|
||||
ExprKind::Struct(_, _, None)
|
||||
| ExprKind::Yield(_, _)
|
||||
| ExprKind::Closure(_, _, _, _, _)
|
||||
| ExprKind::Closure { .. }
|
||||
| ExprKind::Path(_)
|
||||
| ExprKind::ConstBlock(_)
|
||||
| ExprKind::Lit(_)
|
||||
|
@ -220,7 +220,7 @@ fn uses_iter<'tcx>(cx: &LateContext<'tcx>, iter_expr: &IterExpr, container: &'tc
|
||||
if let Some(e) = e {
|
||||
self.visit_expr(e);
|
||||
}
|
||||
} else if let ExprKind::Closure(_, _, id, _, _) = e.kind {
|
||||
} else if let ExprKind::Closure { body: id, .. } = e.kind {
|
||||
if is_res_used(self.cx, self.iter_expr.path, id) {
|
||||
self.uses_iter = true;
|
||||
}
|
||||
@ -260,7 +260,7 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: &
|
||||
if let Some(e) = e {
|
||||
self.visit_expr(e);
|
||||
}
|
||||
} else if let ExprKind::Closure(_, _, id, _, _) = e.kind {
|
||||
} else if let ExprKind::Closure { body: id, .. } = e.kind {
|
||||
self.used_iter = is_res_used(self.cx, self.iter_expr.path, id);
|
||||
} else {
|
||||
walk_expr(self, e);
|
||||
@ -307,7 +307,7 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: &
|
||||
if let Some(e) = e {
|
||||
self.visit_expr(e);
|
||||
}
|
||||
} else if let ExprKind::Closure(_, _, id, _, _) = e.kind {
|
||||
} else if let ExprKind::Closure { body: id, .. } = e.kind {
|
||||
self.used_after = is_res_used(self.cx, self.iter_expr.path, id);
|
||||
} else {
|
||||
walk_expr(self, e);
|
||||
|
@ -177,8 +177,8 @@ fn desugared_async_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>)
|
||||
if let Some(block_expr) = block.expr;
|
||||
if let Some(args) = match_function_call(cx, block_expr, &FUTURE_FROM_GENERATOR);
|
||||
if args.len() == 1;
|
||||
if let Expr{kind: ExprKind::Closure(_, _, body_id, ..), ..} = args[0];
|
||||
let closure_body = cx.tcx.hir().body(body_id);
|
||||
if let Expr{kind: ExprKind::Closure { body, .. }, ..} = args[0];
|
||||
let closure_body = cx.tcx.hir().body(body);
|
||||
if closure_body.generator_kind == Some(GeneratorKind::Async(AsyncGeneratorKind::Block));
|
||||
then {
|
||||
return Some(closure_body);
|
||||
|
@ -88,8 +88,8 @@ fn is_ok_wrapping(cx: &LateContext<'_>, map_expr: &Expr<'_>) -> bool {
|
||||
}
|
||||
}
|
||||
if_chain! {
|
||||
if let ExprKind::Closure(_, _, body_id, ..) = map_expr.kind;
|
||||
let body = cx.tcx.hir().body(body_id);
|
||||
if let ExprKind::Closure { body, .. } = map_expr.kind;
|
||||
let body = cx.tcx.hir().body(body);
|
||||
if let PatKind::Binding(_, param_id, ..) = body.params[0].pat.kind;
|
||||
if let ExprKind::Call(Expr { kind: ExprKind::Path(ok_path), .. }, &[ref ok_arg]) = body.value.kind;
|
||||
if is_lang_ctor(cx, ok_path, ResultOk);
|
||||
|
@ -67,9 +67,9 @@ impl<'tcx> LateLintPass<'tcx> for MapClone {
|
||||
if method.ident.name == sym::map;
|
||||
let ty = cx.typeck_results().expr_ty(&args[0]);
|
||||
if is_type_diagnostic_item(cx, ty, sym::Option) || is_trait_method(cx, e, sym::Iterator);
|
||||
if let hir::ExprKind::Closure(_, _, body_id, _, _) = args[1].kind;
|
||||
if let hir::ExprKind::Closure { body, .. } = args[1].kind;
|
||||
then {
|
||||
let closure_body = cx.tcx.hir().body(body_id);
|
||||
let closure_body = cx.tcx.hir().body(body);
|
||||
let closure_expr = peel_blocks(&closure_body.value);
|
||||
match closure_body.params[0].pat.kind {
|
||||
hir::PatKind::Ref(inner, hir::Mutability::Not) => if let hir::PatKind::Binding(
|
||||
|
@ -117,12 +117,19 @@ impl<'tcx> LateLintPass<'tcx> for MapErrIgnore {
|
||||
// only work if the method name is `map_err` and there are only 2 arguments (e.g. x.map_err(|_|[1]
|
||||
// Enum::Variant[2]))
|
||||
if method.ident.as_str() == "map_err" && args.len() == 2 {
|
||||
// make sure the first argument is a closure, and grab the CaptureRef, body_id, and body_span fields
|
||||
if let ExprKind::Closure(capture, _, body_id, body_span, _) = args[1].kind {
|
||||
// make sure the first argument is a closure, and grab the CaptureRef, BodyId, and fn_decl_span
|
||||
// fields
|
||||
if let ExprKind::Closure {
|
||||
capture_clause,
|
||||
body,
|
||||
fn_decl_span,
|
||||
..
|
||||
} = args[1].kind
|
||||
{
|
||||
// check if this is by Reference (meaning there's no move statement)
|
||||
if capture == CaptureBy::Ref {
|
||||
if capture_clause == CaptureBy::Ref {
|
||||
// Get the closure body to check the parameters and values
|
||||
let closure_body = cx.tcx.hir().body(body_id);
|
||||
let closure_body = cx.tcx.hir().body(body);
|
||||
// make sure there's only one parameter (`|_|`)
|
||||
if closure_body.params.len() == 1 {
|
||||
// make sure that parameter is the wild token (`_`)
|
||||
@ -132,7 +139,7 @@ impl<'tcx> LateLintPass<'tcx> for MapErrIgnore {
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
MAP_ERR_IGNORE,
|
||||
body_span,
|
||||
fn_decl_span,
|
||||
"`map_err(|_|...` wildcard pattern discards the original error",
|
||||
None,
|
||||
"consider storing the original error as a source in the new error, or silence this warning using an ignored identifier (`.map_err(|_foo| ...`)",
|
||||
|
@ -169,12 +169,12 @@ fn unit_closure<'tcx>(
|
||||
expr: &hir::Expr<'_>,
|
||||
) -> Option<(&'tcx hir::Param<'tcx>, &'tcx hir::Expr<'tcx>)> {
|
||||
if_chain! {
|
||||
if let hir::ExprKind::Closure(_, decl, inner_expr_id, _, _) = expr.kind;
|
||||
let body = cx.tcx.hir().body(inner_expr_id);
|
||||
if let hir::ExprKind::Closure { fn_decl, body, .. } = expr.kind;
|
||||
let body = cx.tcx.hir().body(body);
|
||||
let body_expr = &body.value;
|
||||
if decl.inputs.len() == 1;
|
||||
if fn_decl.inputs.len() == 1;
|
||||
if is_unit_expression(cx, body_expr);
|
||||
if let Some(binding) = iter_input_pats(decl, body).next();
|
||||
if let Some(binding) = iter_input_pats(fn_decl, body).next();
|
||||
then {
|
||||
return Some((binding, body_expr));
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ fn sugg_with_curlies<'a>(
|
||||
|
||||
let (mut cbrace_start, mut cbrace_end) = (String::new(), String::new());
|
||||
if let Some(parent_expr) = get_parent_expr(cx, match_expr) {
|
||||
if let ExprKind::Closure(..) = parent_expr.kind {
|
||||
if let ExprKind::Closure { .. } = parent_expr.kind {
|
||||
cbrace_end = format!("\n{}}}", indent);
|
||||
// Fix body indent due to the closure
|
||||
indent = " ".repeat(indent_of(cx, bind_names).unwrap_or(0));
|
||||
|
@ -305,7 +305,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SigDropHelper<'a, 'tcx> {
|
||||
ExprKind::Break(_, _) |
|
||||
ExprKind::Cast(_, _) |
|
||||
// Don't want to check the closure itself, only invocation, which is covered by MethodCall
|
||||
ExprKind::Closure(_, _, _, _, _) |
|
||||
ExprKind::Closure { .. } |
|
||||
ExprKind::ConstBlock(_) |
|
||||
ExprKind::Continue(_) |
|
||||
ExprKind::DropTemps(_) |
|
||||
|
@ -150,11 +150,11 @@ pub(crate) trait BindInsteadOfMap {
|
||||
}
|
||||
|
||||
match arg.kind {
|
||||
hir::ExprKind::Closure(_, _, body_id, closure_args_span, _) => {
|
||||
let closure_body = cx.tcx.hir().body(body_id);
|
||||
hir::ExprKind::Closure { body, fn_decl_span, .. } => {
|
||||
let closure_body = cx.tcx.hir().body(body);
|
||||
let closure_expr = peel_blocks(&closure_body.value);
|
||||
|
||||
if Self::lint_closure_autofixable(cx, expr, recv, closure_expr, closure_args_span) {
|
||||
if Self::lint_closure_autofixable(cx, expr, recv, closure_expr, fn_decl_span) {
|
||||
true
|
||||
} else {
|
||||
Self::lint_closure(cx, expr, closure_expr)
|
||||
|
@ -22,8 +22,8 @@ fn is_method<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, method_name: Sy
|
||||
hir::ExprKind::Path(QPath::Resolved(_, segments)) => {
|
||||
segments.segments.last().unwrap().ident.name == method_name
|
||||
},
|
||||
hir::ExprKind::Closure(_, _, c, _, _) => {
|
||||
let body = cx.tcx.hir().body(*c);
|
||||
hir::ExprKind::Closure { body, .. } => {
|
||||
let body = cx.tcx.hir().body(*body);
|
||||
let closure_expr = peel_blocks(&body.value);
|
||||
let arg_id = body.params[0].pat.hir_id;
|
||||
match closure_expr.kind {
|
||||
@ -106,7 +106,7 @@ pub(super) fn check<'tcx>(
|
||||
if is_trait_method(cx, map_recv, sym::Iterator);
|
||||
|
||||
// filter(|x| ...is_some())...
|
||||
if let ExprKind::Closure(_, _, filter_body_id, ..) = filter_arg.kind;
|
||||
if let ExprKind::Closure { body: filter_body_id, .. } = filter_arg.kind;
|
||||
let filter_body = cx.tcx.hir().body(filter_body_id);
|
||||
if let [filter_param] = filter_body.params;
|
||||
// optional ref pattern: `filter(|&x| ..)`
|
||||
@ -129,7 +129,7 @@ pub(super) fn check<'tcx>(
|
||||
if path.ident.name.as_str() == if is_result { "is_ok" } else { "is_some" };
|
||||
|
||||
// ...map(|x| ...unwrap())
|
||||
if let ExprKind::Closure(_, _, map_body_id, ..) = map_arg.kind;
|
||||
if let ExprKind::Closure { body: map_body_id, .. } = map_arg.kind;
|
||||
let map_body = cx.tcx.hir().body(map_body_id);
|
||||
if let [map_param] = map_body.params;
|
||||
if let PatKind::Binding(_, map_param_id, map_param_ident, None) = map_param.pat.kind;
|
||||
|
@ -51,8 +51,8 @@ pub(super) fn check<'tcx>(
|
||||
.map_or(false, |fun_def_id| {
|
||||
deref_aliases.iter().any(|path| match_def_path(cx, fun_def_id, path))
|
||||
}),
|
||||
hir::ExprKind::Closure(_, _, body_id, _, _) => {
|
||||
let closure_body = cx.tcx.hir().body(body_id);
|
||||
hir::ExprKind::Closure { body, .. } => {
|
||||
let closure_body = cx.tcx.hir().body(body);
|
||||
let closure_expr = peel_blocks(&closure_body.value);
|
||||
|
||||
match &closure_expr.kind {
|
||||
|
@ -71,27 +71,26 @@ pub(super) fn check<'tcx>(
|
||||
if is_option {
|
||||
let self_snippet = snippet(cx, recv.span, "..");
|
||||
if_chain! {
|
||||
if let hir::ExprKind::Closure(_, _, id, span, _) = map_arg.kind;
|
||||
let arg_snippet = snippet(cx, span, "..");
|
||||
let body = cx.tcx.hir().body(id);
|
||||
if let Some((func, [arg_char])) = reduce_unit_expression(&body.value);
|
||||
if let Some(id) = path_def_id(cx, func).map(|ctor_id| cx.tcx.parent(ctor_id));
|
||||
if Some(id) == cx.tcx.lang_items().option_some_variant();
|
||||
then {
|
||||
let func_snippet = snippet(cx, arg_char.span, "..");
|
||||
let msg = "called `map_or(None, ..)` on an `Option` value. This can be done more directly by calling \
|
||||
`map(..)` instead";
|
||||
return span_lint_and_sugg(
|
||||
cx,
|
||||
OPTION_MAP_OR_NONE,
|
||||
expr.span,
|
||||
msg,
|
||||
"try using `map` instead",
|
||||
format!("{0}.map({1} {2})", self_snippet, arg_snippet,func_snippet),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
|
||||
if let hir::ExprKind::Closure { body, fn_decl_span, .. } = map_arg.kind;
|
||||
let arg_snippet = snippet(cx, fn_decl_span, "..");
|
||||
let body = cx.tcx.hir().body(body);
|
||||
if let Some((func, [arg_char])) = reduce_unit_expression(&body.value);
|
||||
if let Some(id) = path_def_id(cx, func).map(|ctor_id| cx.tcx.parent(ctor_id));
|
||||
if Some(id) == cx.tcx.lang_items().option_some_variant();
|
||||
then {
|
||||
let func_snippet = snippet(cx, arg_char.span, "..");
|
||||
let msg = "called `map_or(None, ..)` on an `Option` value. This can be done more directly by calling \
|
||||
`map(..)` instead";
|
||||
return span_lint_and_sugg(
|
||||
cx,
|
||||
OPTION_MAP_OR_NONE,
|
||||
expr.span,
|
||||
msg,
|
||||
"try using `map` instead",
|
||||
format!("{0}.map({1} {2})", self_snippet, arg_snippet,func_snippet),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let func_snippet = snippet(cx, map_arg.span, "..");
|
||||
|
@ -41,8 +41,8 @@ pub(super) fn check<'tcx>(
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
let any_search_snippet = if_chain! {
|
||||
if search_method == "find";
|
||||
if let hir::ExprKind::Closure(_, _, body_id, ..) = search_arg.kind;
|
||||
let closure_body = cx.tcx.hir().body(body_id);
|
||||
if let hir::ExprKind::Closure { body, .. } = search_arg.kind;
|
||||
let closure_body = cx.tcx.hir().body(body);
|
||||
if let Some(closure_arg) = closure_body.params.get(0);
|
||||
then {
|
||||
if let hir::PatKind::Ref(..) = closure_arg.pat.kind {
|
||||
|
@ -18,8 +18,8 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<
|
||||
return;
|
||||
}
|
||||
|
||||
if let hir::ExprKind::Closure(_, _, body_id, ..) = arg.kind {
|
||||
let body = cx.tcx.hir().body(body_id);
|
||||
if let hir::ExprKind::Closure { body, .. } = arg.kind {
|
||||
let body = cx.tcx.hir().body(body);
|
||||
let arg_id = body.params[0].pat.hir_id;
|
||||
let mutates_arg =
|
||||
mutated_variables(&body.value, cx).map_or(true, |used_mutably| used_mutably.contains(&arg_id));
|
||||
|
@ -29,8 +29,8 @@ pub(super) fn check(
|
||||
) {
|
||||
if_chain! {
|
||||
// Extract the body of the closure passed to fold
|
||||
if let hir::ExprKind::Closure(_, _, body_id, _, _) = acc.kind;
|
||||
let closure_body = cx.tcx.hir().body(body_id);
|
||||
if let hir::ExprKind::Closure { body, .. } = acc.kind;
|
||||
let closure_body = cx.tcx.hir().body(body);
|
||||
let closure_expr = peel_blocks(&closure_body.value);
|
||||
|
||||
// Check if the closure body is of the form `acc <op> some_expr(x)`
|
||||
|
@ -22,8 +22,8 @@ pub(super) fn check<'tcx>(
|
||||
let is_result = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result);
|
||||
|
||||
if is_option || is_result {
|
||||
if let hir::ExprKind::Closure(_, _, eid, _, _) = arg.kind {
|
||||
let body = cx.tcx.hir().body(eid);
|
||||
if let hir::ExprKind::Closure { body, .. } = arg.kind {
|
||||
let body = cx.tcx.hir().body(body);
|
||||
let body_expr = &body.value;
|
||||
|
||||
if usage::BindingUsageFinder::are_params_used(cx, body) {
|
||||
|
@ -112,7 +112,7 @@ struct DivergenceVisitor<'a, 'tcx> {
|
||||
impl<'a, 'tcx> DivergenceVisitor<'a, 'tcx> {
|
||||
fn maybe_walk_expr(&mut self, e: &'tcx Expr<'_>) {
|
||||
match e.kind {
|
||||
ExprKind::Closure(..) => {},
|
||||
ExprKind::Closure { .. } => {},
|
||||
ExprKind::Match(e, arms, _) => {
|
||||
self.visit_expr(e);
|
||||
for arm in arms {
|
||||
@ -243,7 +243,7 @@ fn check_expr<'a, 'tcx>(vis: &mut ReadVisitor<'a, 'tcx>, expr: &'tcx Expr<'_>) -
|
||||
walk_expr(vis, expr);
|
||||
}
|
||||
},
|
||||
ExprKind::Closure(_, _, _, _, _) => {
|
||||
ExprKind::Closure { .. } => {
|
||||
// Either
|
||||
//
|
||||
// * `var` is defined in the closure body, in which case we've reached the top of the enclosing
|
||||
@ -315,7 +315,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReadVisitor<'a, 'tcx> {
|
||||
// We're about to descend a closure. Since we don't know when (or
|
||||
// if) the closure will be evaluated, any reads in it might not
|
||||
// occur here (or ever). Like above, bail to avoid false positives.
|
||||
ExprKind::Closure(_, _, _, _, _) |
|
||||
ExprKind::Closure{..} |
|
||||
|
||||
// We want to avoid a false positive when a variable name occurs
|
||||
// only to have its address taken, so we stop here. Technically,
|
||||
|
@ -72,8 +72,8 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessForEach {
|
||||
if has_iter_method(cx, cx.typeck_results().expr_ty(iter_recv)).is_some();
|
||||
// Skip the lint if the body is not block because this is simpler than `for` loop.
|
||||
// e.g. `v.iter().for_each(f)` is simpler and clearer than using `for` loop.
|
||||
if let ExprKind::Closure(_, _, body_id, ..) = for_each_arg.kind;
|
||||
let body = cx.tcx.hir().body(body_id);
|
||||
if let ExprKind::Closure { body, .. } = for_each_arg.kind;
|
||||
let body = cx.tcx.hir().body(body);
|
||||
if let ExprKind::Block(..) = body.value.kind;
|
||||
then {
|
||||
let mut ret_collector = RetCollector::default();
|
||||
|
@ -116,7 +116,7 @@ fn has_no_effect(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
||||
return false;
|
||||
}
|
||||
match peel_blocks(expr).kind {
|
||||
ExprKind::Lit(..) | ExprKind::Closure(..) => true,
|
||||
ExprKind::Lit(..) | ExprKind::Closure { .. } => true,
|
||||
ExprKind::Path(..) => !has_drop(cx, cx.typeck_results().expr_ty(expr)),
|
||||
ExprKind::Index(a, b) | ExprKind::Binary(_, a, b) => has_no_effect(cx, a) && has_no_effect(cx, b),
|
||||
ExprKind::Array(v) | ExprKind::Tup(v) => v.iter().all(|val| has_no_effect(cx, val)),
|
||||
|
@ -298,8 +298,8 @@ impl<'tcx> Visitor<'tcx> for SideEffectVisit<'tcx> {
|
||||
},
|
||||
ExprKind::Match(expr, arms, _) => self.visit_match(expr, arms),
|
||||
// since analysing the closure is not easy, just set all variables in it to side-effect
|
||||
ExprKind::Closure(_, _, body_id, _, _) => {
|
||||
let body = self.tcx.hir().body(body_id);
|
||||
ExprKind::Closure { body, .. } => {
|
||||
let body = self.tcx.hir().body(body);
|
||||
self.visit_body(body);
|
||||
let vars = std::mem::take(&mut self.ret_vars);
|
||||
self.add_side_effect(vars);
|
||||
|
@ -134,7 +134,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
|
||||
if_chain! {
|
||||
if let hir::StmtKind::Local(local) = w[0].kind;
|
||||
if let Option::Some(t) = local.init;
|
||||
if let hir::ExprKind::Closure(..) = t.kind;
|
||||
if let hir::ExprKind::Closure { .. } = t.kind;
|
||||
if let hir::PatKind::Binding(_, _, ident, _) = local.pat.kind;
|
||||
if let hir::StmtKind::Semi(second) = w[1].kind;
|
||||
if let hir::ExprKind::Assign(_, call, _) = second.kind;
|
||||
|
@ -116,13 +116,13 @@ fn get_args_to_check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Ve
|
||||
|
||||
fn check_arg<'tcx>(cx: &LateContext<'tcx>, arg: &'tcx Expr<'tcx>) -> Option<(Span, Option<Span>)> {
|
||||
if_chain! {
|
||||
if let ExprKind::Closure(_, _fn_decl, body_id, span, _) = arg.kind;
|
||||
if let ExprKind::Closure { body, fn_decl_span, .. } = arg.kind;
|
||||
if let ty::Closure(_def_id, substs) = &cx.typeck_results().node_type(arg.hir_id).kind();
|
||||
let ret_ty = substs.as_closure().sig().output();
|
||||
let ty = cx.tcx.erase_late_bound_regions(ret_ty);
|
||||
if ty.is_unit();
|
||||
then {
|
||||
let body = cx.tcx.hir().body(body_id);
|
||||
let body = cx.tcx.hir().body(body);
|
||||
if_chain! {
|
||||
if let ExprKind::Block(block, _) = body.value.kind;
|
||||
if block.expr.is_none();
|
||||
@ -131,9 +131,9 @@ fn check_arg<'tcx>(cx: &LateContext<'tcx>, arg: &'tcx Expr<'tcx>) -> Option<(Spa
|
||||
then {
|
||||
let data = stmt.span.data();
|
||||
// Make a span out of the semicolon for the help message
|
||||
Some((span, Some(data.with_lo(data.hi-BytePos(1)))))
|
||||
Some((fn_decl_span, Some(data.with_lo(data.hi-BytePos(1)))))
|
||||
} else {
|
||||
Some((span, None))
|
||||
Some((fn_decl_span, None))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -155,7 +155,7 @@ fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<LintTrigger> {
|
||||
if let ExprKind::MethodCall(name_ident, args, _) = &expr.kind;
|
||||
if let name = name_ident.ident.name.to_ident_string();
|
||||
if name == "sort_by" || name == "sort_unstable_by";
|
||||
if let [vec, Expr { kind: ExprKind::Closure(_, _, closure_body_id, _, _), .. }] = args;
|
||||
if let [vec, Expr { kind: ExprKind::Closure{ body: closure_body_id, .. }, .. }] = args;
|
||||
if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(vec), sym::Vec);
|
||||
if let closure_body = cx.tcx.hir().body(*closure_body_id);
|
||||
if let &[
|
||||
|
@ -466,7 +466,13 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
|
||||
self.expr(scrutinee);
|
||||
self.slice(arms, |arm| self.arm(arm));
|
||||
},
|
||||
ExprKind::Closure(capture_by, fn_decl, body_id, _, movability) => {
|
||||
ExprKind::Closure {
|
||||
capture_clause,
|
||||
fn_decl,
|
||||
body: body_id,
|
||||
movability,
|
||||
..
|
||||
} => {
|
||||
let movability = OptionPat::new(movability.map(|m| format!("Movability::{m:?}")));
|
||||
|
||||
let ret_ty = match fn_decl.output {
|
||||
@ -475,7 +481,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
|
||||
};
|
||||
|
||||
bind!(self, fn_decl, body_id);
|
||||
kind!("Closure(CaptureBy::{capture_by:?}, {fn_decl}, {body_id}, _, {movability})");
|
||||
kind!("Closure(CaptureBy::{capture_clause:?}, {fn_decl}, {body_id}, _, {movability})");
|
||||
out!("if let {ret_ty} = {fn_decl}.output;");
|
||||
self.body(body_id);
|
||||
},
|
||||
|
@ -198,7 +198,7 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
|
||||
| ExprKind::Let(..)
|
||||
| ExprKind::If(..)
|
||||
| ExprKind::Match(..)
|
||||
| ExprKind::Closure(..)
|
||||
| ExprKind::Closure { .. }
|
||||
| ExprKind::Field(..)
|
||||
| ExprKind::Path(_)
|
||||
| ExprKind::AddrOf(..)
|
||||
|
@ -622,10 +622,12 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
||||
self.hash_expr(e);
|
||||
self.hash_ty(ty);
|
||||
},
|
||||
ExprKind::Closure(cap, _, eid, _, _) => {
|
||||
std::mem::discriminant(&cap).hash(&mut self.s);
|
||||
ExprKind::Closure {
|
||||
capture_clause, body, ..
|
||||
} => {
|
||||
std::mem::discriminant(&capture_clause).hash(&mut self.s);
|
||||
// closures inherit TypeckResults
|
||||
self.hash_expr(&self.cx.tcx.hir().body(eid).value);
|
||||
self.hash_expr(&self.cx.tcx.hir().body(body).value);
|
||||
},
|
||||
ExprKind::Field(e, ref f) => {
|
||||
self.hash_expr(e);
|
||||
|
@ -962,7 +962,7 @@ pub fn can_move_expr_to_closure<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'
|
||||
self.captures.entry(l).and_modify(|e| *e |= cap).or_insert(cap);
|
||||
}
|
||||
},
|
||||
ExprKind::Closure(..) => {
|
||||
ExprKind::Closure { .. } => {
|
||||
let closure_id = self.cx.tcx.hir().local_def_id(e.hir_id).to_def_id();
|
||||
for capture in self.cx.typeck_results().closure_min_captures_flattened(closure_id) {
|
||||
let local_id = match capture.place.base {
|
||||
@ -1200,7 +1200,7 @@ pub fn get_enclosing_loop_or_closure<'tcx>(tcx: TyCtxt<'tcx>, expr: &Expr<'_>) -
|
||||
match node {
|
||||
Node::Expr(
|
||||
e @ Expr {
|
||||
kind: ExprKind::Loop(..) | ExprKind::Closure(..),
|
||||
kind: ExprKind::Loop(..) | ExprKind::Closure { .. },
|
||||
..
|
||||
},
|
||||
) => return Some(e),
|
||||
@ -1693,7 +1693,7 @@ pub fn get_async_fn_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Option<&'t
|
||||
_,
|
||||
&[
|
||||
Expr {
|
||||
kind: ExprKind::Closure(_, _, body, _, _),
|
||||
kind: ExprKind::Closure { body, .. },
|
||||
..
|
||||
},
|
||||
],
|
||||
@ -1780,7 +1780,7 @@ pub fn is_expr_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool
|
||||
}
|
||||
|
||||
match expr.kind {
|
||||
ExprKind::Closure(_, _, body_id, _, _) => is_body_identity_function(cx, cx.tcx.hir().body(body_id)),
|
||||
ExprKind::Closure { body, .. } => is_body_identity_function(cx, cx.tcx.hir().body(body)),
|
||||
_ => path_def_id(cx, expr).map_or(false, |id| match_def_path(cx, id, &paths::CONVERT_IDENTITY)),
|
||||
}
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ impl<'a> Sugg<'a> {
|
||||
| hir::ExprKind::Box(..)
|
||||
| hir::ExprKind::If(..)
|
||||
| hir::ExprKind::Let(..)
|
||||
| hir::ExprKind::Closure(..)
|
||||
| hir::ExprKind::Closure { .. }
|
||||
| hir::ExprKind::Unary(..)
|
||||
| hir::ExprKind::Match(..) => Sugg::MaybeParen(get_snippet(expr.span)),
|
||||
hir::ExprKind::Continue(..)
|
||||
@ -188,7 +188,7 @@ impl<'a> Sugg<'a> {
|
||||
match expr.kind {
|
||||
ast::ExprKind::AddrOf(..)
|
||||
| ast::ExprKind::Box(..)
|
||||
| ast::ExprKind::Closure(..)
|
||||
| ast::ExprKind::Closure { .. }
|
||||
| ast::ExprKind::If(..)
|
||||
| ast::ExprKind::Let(..)
|
||||
| ast::ExprKind::Unary(..)
|
||||
@ -790,8 +790,8 @@ pub struct DerefClosure {
|
||||
///
|
||||
/// note: this only works on single line immutable closures with exactly one input parameter.
|
||||
pub fn deref_closure_args<'tcx>(cx: &LateContext<'_>, closure: &'tcx hir::Expr<'_>) -> Option<DerefClosure> {
|
||||
if let hir::ExprKind::Closure(_, fn_decl, body_id, ..) = closure.kind {
|
||||
let closure_body = cx.tcx.hir().body(body_id);
|
||||
if let hir::ExprKind::Closure { fn_decl, body, .. } = closure.kind {
|
||||
let closure_body = cx.tcx.hir().body(body);
|
||||
// is closure arg a type annotated double reference (i.e.: `|x: &&i32| ...`)
|
||||
// a type annotation is present if param `kind` is different from `TyKind::Infer`
|
||||
let closure_arg_is_type_annotated_double_ref = if let TyKind::Rptr(_, MutTy { ty, .. }) = fn_decl.inputs[0].kind
|
||||
|
@ -185,7 +185,7 @@ pub fn local_used_after_expr(cx: &LateContext<'_>, local_id: HirId, after: &Expr
|
||||
matches!(
|
||||
node,
|
||||
Node::Expr(Expr {
|
||||
kind: ExprKind::Loop(..) | ExprKind::Closure(..),
|
||||
kind: ExprKind::Loop(..) | ExprKind::Closure { .. },
|
||||
..
|
||||
})
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user