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:
bors 2022-06-15 11:04:23 +00:00
commit a4cec9742b
96 changed files with 563 additions and 537 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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(

View File

@ -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),

View File

@ -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,
};

View File

@ -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,

View File

@ -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,

View File

@ -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);

View File

@ -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.

View File

@ -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,
},
})

View File

@ -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;
}
_ => {}

View File

@ -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);
}
}

View File

@ -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(..), .. })

View File

@ -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,
}

View File

@ -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),

View File

@ -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),

View File

@ -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,
};

View File

@ -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(..)

View File

@ -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));

View File

@ -212,7 +212,7 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
| ExprKind::Loop(..)
| ExprKind::Match(..)
| ExprKind::If(..)
| ExprKind::Closure(..)
| ExprKind::Closure { .. }
| ExprKind::Assign(..)
| ExprKind::AssignOp(..)
| ExprKind::Field(..)

View File

@ -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

View File

@ -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,

View File

@ -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.

View File

@ -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);
}

View File

@ -1188,7 +1188,6 @@ symbols! {
rustc_const_unstable,
rustc_conversion_suggestion,
rustc_def_path,
rustc_deprecated,
rustc_diagnostic_item,
rustc_diagnostic_macros,
rustc_dirty,

View File

@ -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| {

View File

@ -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);

View File

@ -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)
}

View File

@ -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 \

View File

@ -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),
};

View File

@ -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);
}

View File

@ -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;

View File

@ -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),

View File

@ -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

View File

@ -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,
..
})) => {

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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),
}

View File

@ -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);
}

View File

@ -437,7 +437,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
self.consume_expr(base);
}
hir::ExprKind::Closure(..) => {
hir::ExprKind::Closure { .. } => {
self.walk_captures(expr);
}

View File

@ -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(..)

View File

@ -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.

View File

@ -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 {

View File

@ -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::*;

View File

@ -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::*;

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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)]

View File

@ -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 {

View File

@ -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()

View File

@ -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<'_> {

View File

@ -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() {}

View File

@ -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

View File

@ -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

View File

@ -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() {

View File

@ -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;

View File

@ -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(..)

View File

@ -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() {

View File

@ -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);
}
}

View File

@ -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),

View File

@ -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(_)

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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(

View File

@ -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| ...`)",

View File

@ -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));
}

View File

@ -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));

View File

@ -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(_) |

View File

@ -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)

View File

@ -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;

View File

@ -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 {

View File

@ -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, "..");

View File

@ -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 {

View File

@ -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));

View File

@ -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)`

View File

@ -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) {

View File

@ -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,

View File

@ -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();

View File

@ -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)),

View File

@ -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);

View File

@ -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;

View File

@ -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 {

View File

@ -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 &[

View File

@ -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);
},

View File

@ -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(..)

View File

@ -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);

View File

@ -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)),
}
}

View File

@ -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

View File

@ -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 { .. },
..
})
)