diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index f87269960bc84..44e4dea34817e 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -403,8 +403,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } let typeck = self.infcx.tcx.typeck(self.mir_def_id()); - let hir_id = hir.parent_id(expr.hir_id); - let parent = self.infcx.tcx.hir_node(hir_id); + let parent = self.infcx.tcx.parent_hir_node(expr.hir_id); let (def_id, args, offset) = if let hir::Node::Expr(parent_expr) = parent && let hir::ExprKind::MethodCall(_, _, args, _) = parent_expr.kind && let Some(def_id) = typeck.type_dependent_def_id(parent_expr.hir_id) @@ -1660,8 +1659,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // Check that the parent of the closure is a method call, // with receiver matching with local's type (modulo refs) - let parent = hir.parent_id(closure_expr.hir_id); - if let hir::Node::Expr(parent) = tcx.hir_node(parent) { + if let hir::Node::Expr(parent) = tcx.parent_hir_node(closure_expr.hir_id) { if let hir::ExprKind::MethodCall(_, recv, ..) = parent.kind { let recv_ty = typeck_results.expr_ty(recv); diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 9e7fd45ec19ad..5aed18ca4563b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -944,7 +944,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let hir = self.infcx.tcx.hir(); let closure_id = self.mir_hir_id(); let closure_span = self.infcx.tcx.def_span(self.mir_def_id()); - let fn_call_id = hir.parent_id(closure_id); + let fn_call_id = self.infcx.tcx.parent_hir_id(closure_id); let node = self.infcx.tcx.hir_node(fn_call_id); let def_id = hir.enclosing_body_owner(fn_call_id); let mut look_at_return = true; @@ -1034,7 +1034,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if let InstanceDef::Item(def_id) = source.instance && let Some(Node::Expr(hir::Expr { hir_id, kind, .. })) = hir.get_if_local(def_id) && let ExprKind::Closure(hir::Closure { kind: hir::ClosureKind::Closure, .. }) = kind - && let Some(Node::Expr(expr)) = hir.find_parent(*hir_id) + && let Node::Expr(expr) = self.infcx.tcx.parent_hir_node(*hir_id) { let mut cur_expr = expr; while let ExprKind::MethodCall(path_segment, recv, _, _) = cur_expr.kind { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index e69d2ca966ba0..7529ec53a9869 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -214,8 +214,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if let Some(id) = placeholder.bound.kind.get_id() && let Some(placeholder_id) = id.as_local() && let gat_hir_id = self.infcx.tcx.local_def_id_to_hir_id(placeholder_id) - && let Some(generics_impl) = - hir.get_parent(hir.parent_id(gat_hir_id)).generics() + && let Some(generics_impl) = self + .infcx + .tcx + .parent_hir_node(self.infcx.tcx.parent_hir_id(gat_hir_id)) + .generics() { Some((gat_hir_id, generics_impl)) } else { diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index 3a441c1d649ca..7b68a37fdf3ea 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -149,6 +149,8 @@ where "`field` projection called on a slice -- call `index` projection instead" ); let offset = base.layout().fields.offset(field); + // Computing the layout does normalization, so we get a normalized type out of this + // even if the field type is non-normalized (possible e.g. via associated types). let field_layout = base.layout().field(self, field); // Offset may need adjustment for unsized fields. diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs index de0590a4b14de..340a496a68990 100644 --- a/compiler/rustc_const_eval/src/interpret/visitor.rs +++ b/compiler/rustc_const_eval/src/interpret/visitor.rs @@ -153,6 +153,16 @@ pub trait ValueVisitor<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>>: Sized { // We visited all parts of this one. return Ok(()); } + + // Non-normalized types should never show up here. + ty::Param(..) + | ty::Alias(..) + | ty::Bound(..) + | ty::Placeholder(..) + | ty::Infer(..) + | ty::Error(..) => throw_inval!(TooGeneric), + + // The rest is handled below. _ => {} }; diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs index 98276ff2e68d6..1be2a2bc1f3c0 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs @@ -131,11 +131,10 @@ fn is_parent_const_stable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool { let local_def_id = def_id.expect_local(); let hir_id = tcx.local_def_id_to_hir_id(local_def_id); - let Some(parent) = tcx.hir().opt_parent_id(hir_id) else { return false }; - - if !tcx.is_const_trait_impl_raw(parent.owner.def_id.to_def_id()) { + let parent_owner_id = tcx.parent_hir_id(hir_id).owner; + if !tcx.is_const_trait_impl_raw(parent_owner_id.to_def_id()) { return false; } - tcx.lookup_const_stability(parent.owner).is_some_and(|stab| stab.is_const_stable()) + tcx.lookup_const_stability(parent_owner_id).is_some_and(|stab| stab.is_const_stable()) } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index abf7a695fd2d1..a7a1c69b9bed6 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3508,7 +3508,7 @@ impl<'hir> Node<'hir> { /// ```ignore (illustrative) /// ctor /// .ctor_hir_id() - /// .and_then(|ctor_id| tcx.hir().find_parent(ctor_id)) + /// .map(|ctor_id| tcx.parent_hir_node(ctor_id)) /// .and_then(|parent| parent.ident()) /// ``` pub fn ident(&self) -> Option { diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index d438d3e7c60bb..1ae3ebaebbbb7 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -2749,14 +2749,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { arg_idx: Option, ) -> Option> { let tcx = self.tcx(); - let hir = tcx.hir(); - let hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), ident, .. }) = tcx.hir_node(fn_hir_id) else { return None; }; - let i = hir.get_parent(fn_hir_id).expect_item().expect_impl(); + let i = tcx.parent_hir_node(fn_hir_id).expect_item().expect_impl(); let trait_ref = self.instantiate_mono_trait_ref(i.of_trait.as_ref()?, self.ast_ty_to_ty(i.self_ty)); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index fbcebb7c87c9b..f458ff01c104c 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -224,11 +224,8 @@ pub(crate) fn placeholder_type_error_diag<'tcx>( is_fn = true; // Check if parent is const or static - let parent_id = tcx.hir().parent_id(hir_ty.hir_id); - let parent_node = tcx.hir_node(parent_id); - is_const_or_static = matches!( - parent_node, + tcx.parent_hir_node(hir_ty.hir_id), Node::Item(&hir::Item { kind: hir::ItemKind::Const(..) | hir::ItemKind::Static(..), .. @@ -1085,7 +1082,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder { // Do not try to infer the return type for a impl method coming from a trait - if let Item(hir::Item { kind: ItemKind::Impl(i), .. }) = tcx.hir().get_parent(hir_id) + if let Item(hir::Item { kind: ItemKind::Impl(i), .. }) = tcx.parent_hir_node(hir_id) && i.of_trait.is_some() { icx.astconv().ty_of_fn( diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 4860555de2056..e5e731bbe8c6d 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -51,7 +51,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { // of a const parameter type, e.g. `struct Foo` is not allowed. None } else if tcx.features().generic_const_exprs { - let parent_node = tcx.hir().get_parent(hir_id); + let parent_node = tcx.parent_hir_node(hir_id); if let Node::Variant(Variant { disr_expr: Some(constant), .. }) = parent_node && constant.hir_id == hir_id { @@ -113,7 +113,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { Some(parent_def_id.to_def_id()) } } else { - let parent_node = tcx.hir().get_parent(hir_id); + let parent_node = tcx.parent_hir_node(hir_id); match parent_node { // HACK(eddyb) this provides the correct generics for repeat // expressions' count (i.e. `N` in `[x; N]`), and explicit diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index ab9ed6ef98d9f..05755f98f202d 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -315,8 +315,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // We create bi-directional Outlives predicates between the original // and the duplicated parameter, to ensure that they do not get out of sync. if let Node::Item(&Item { kind: ItemKind::OpaqueTy(..), .. }) = node { - let opaque_ty_id = tcx.hir().parent_id(hir_id); - let opaque_ty_node = tcx.hir_node(opaque_ty_id); + let opaque_ty_node = tcx.parent_hir_node(hir_id); let Node::Ty(&Ty { kind: TyKind::OpaqueDef(_, lifetimes, _), .. }) = opaque_ty_node else { bug!("unexpected {opaque_ty_node:?}") }; diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 3849c0893f471..1aa9c6929f819 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -732,7 +732,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { let Some(def_id) = def_id.as_local() else { continue }; let hir_id = self.tcx.local_def_id_to_hir_id(def_id); // Ensure that the parent of the def is an item, not HRTB - let parent_id = self.tcx.hir().parent_id(hir_id); + let parent_id = self.tcx.parent_hir_id(hir_id); if !parent_id.is_owner() { struct_span_code_err!( self.tcx.dcx(), diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 20a7663f86441..c0128afe2bf6c 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -30,7 +30,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { ); }; - let parent_node_id = tcx.hir().parent_id(hir_id); + let parent_node_id = tcx.parent_hir_id(hir_id); let parent_node = tcx.hir_node(parent_node_id); let (generics, arg_idx) = match parent_node { @@ -79,7 +79,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { } Node::TypeBinding(binding @ &TypeBinding { hir_id: binding_id, .. }) - if let Node::TraitRef(trait_ref) = tcx.hir_node(tcx.hir().parent_id(binding_id)) => + if let Node::TraitRef(trait_ref) = tcx.parent_hir_node(binding_id) => { let Some(trait_def_id) = trait_ref.trait_def_id() else { return Ty::new_error_with_message( diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs index 3b1ee2975fd97..52ff8b2e45d7c 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs @@ -135,7 +135,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { // Here we check if the reference to the generic type // is from the 'of_trait' field of the enclosing impl - let parent = self.tcx.hir().get_parent(self.path_segment.hir_id); + let parent = self.tcx.parent_hir_node(self.path_segment.hir_id); let parent_item = self.tcx.hir_node_by_def_id( self.tcx.hir().get_parent_item(self.path_segment.hir_id).def_id, ); @@ -770,9 +770,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { num = num_trait_generics_except_self, ); - if let Some(parent_node) = self.tcx.hir().opt_parent_id(self.path_segment.hir_id) - && let hir::Node::Expr(expr) = self.tcx.hir_node(parent_node) - { + if let hir::Node::Expr(expr) = self.tcx.parent_hir_node(self.path_segment.hir_id) { match &expr.kind { hir::ExprKind::Path(qpath) => self .suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path( diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 7ea0469deddee..0311aa94cd485 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -287,7 +287,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { // If this `if` expr is the parent's function return expr, // the cause of the type coercion is the return type, point at it. (#25228) - let hir_id = self.tcx.hir().parent_id(self.tcx.hir().parent_id(then_expr.hir_id)); + let hir_id = self.tcx.parent_hir_id(self.tcx.parent_hir_id(then_expr.hir_id)); let ret_reason = self.maybe_get_coercion_reason(hir_id, if_span); let cause = self.cause(if_span, ObligationCauseCode::IfExpressionWithNoElse); let mut error = false; @@ -396,7 +396,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let node = self.tcx.hir_node(hir_id); if let hir::Node::Block(block) = node { // check that the body's parent is an fn - let parent = self.tcx.hir().get_parent(self.tcx.hir().parent_id(block.hir_id)); + let parent = self.tcx.parent_hir_node(self.tcx.parent_hir_id(block.hir_id)); if let (Some(expr), hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(..), .. })) = (&block.expr, parent) { diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 299ee092a80df..c4271c66e1c9d 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -361,7 +361,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let fn_decl_span = if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }), .. - }) = hir.get_parent(hir_id) + }) = self.tcx.parent_hir_node(hir_id) { fn_decl_span } else if let Some(( @@ -383,11 +383,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { // Actually need to unwrap one more layer of HIR to get to // the _real_ closure... - let async_closure = hir.parent_id(parent_hir_id); if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }), .. - }) = self.tcx.hir_node(async_closure) + }) = self.tcx.parent_hir_node(parent_hir_id) { fn_decl_span } else { @@ -415,8 +414,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { call_expr: &'tcx hir::Expr<'tcx>, callee_expr: &'tcx hir::Expr<'tcx>, ) -> bool { - let hir_id = self.tcx.hir().parent_id(call_expr.hir_id); - let parent_node = self.tcx.hir_node(hir_id); + let parent_node = self.tcx.parent_hir_node(call_expr.hir_id); if let ( hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Array(_), .. }), hir::ExprKind::Tup(exp), diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 28f850a50a0db..549ad44d7e349 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1594,7 +1594,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { err.span_label(cause.span, "return type is not `()`"); } ObligationCauseCode::BlockTailExpression(blk_id, ..) => { - let parent_id = fcx.tcx.hir().parent_id(blk_id); + let parent_id = fcx.tcx.parent_hir_id(blk_id); err = self.report_return_mismatched_types( cause, expected, @@ -1785,7 +1785,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { ) -> DiagnosticBuilder<'a> { let mut err = fcx.err_ctxt().report_mismatched_types(cause, expected, found, ty_err); - let parent_id = fcx.tcx.hir().parent_id(id); + let parent_id = fcx.tcx.parent_hir_id(id); let parent = fcx.tcx.hir_node(parent_id); if let Some(expr) = expression && let hir::Node::Expr(hir::Expr { diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index d8974251de040..fdb2cb69ee7fd 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -298,7 +298,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let hir::Node::Pat(pat) = self.tcx.hir_node(local_hir_id) else { return false; }; - let (init_ty_hir_id, init) = match hir.get_parent(pat.hir_id) { + let (init_ty_hir_id, init) = match self.tcx.parent_hir_node(pat.hir_id) { hir::Node::Local(hir::Local { ty: Some(ty), init, .. }) => (ty.hir_id, *init), hir::Node::Local(hir::Local { init: Some(init), .. }) => (init.hir_id, Some(*init)), _ => return false, @@ -445,7 +445,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { continue; } - if let hir::Node::Expr(parent_expr) = hir.get_parent(binding.hir_id) + if let hir::Node::Expr(parent_expr) = self.tcx.parent_hir_node(binding.hir_id) && let hir::ExprKind::MethodCall(segment, rcvr, args, _) = parent_expr.kind && rcvr.hir_id == binding.hir_id { @@ -557,7 +557,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let Some(TypeError::Sorts(ExpectedFound { expected, .. })) = error else { return; }; - let mut parent_id = self.tcx.hir().parent_id(expr.hir_id); + let mut parent_id = self.tcx.parent_hir_id(expr.hir_id); let mut parent; 'outer: loop { // Climb the HIR tree to see if the current `Expr` is part of a `break;` statement. @@ -568,7 +568,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { break; }; parent = p; - parent_id = self.tcx.hir().parent_id(parent_id); + parent_id = self.tcx.parent_hir_id(parent_id); let hir::ExprKind::Break(destination, _) = parent.kind else { continue; }; @@ -578,7 +578,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Climb the HIR tree to find the (desugared) `loop` this `break` corresponds to. let parent = match self.tcx.hir_node(parent_id) { hir::Node::Expr(&ref parent) => { - parent_id = self.tcx.hir().parent_id(parent.hir_id); + parent_id = self.tcx.parent_hir_id(parent.hir_id); parent } hir::Node::Stmt(hir::Stmt { @@ -586,11 +586,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { kind: hir::StmtKind::Semi(&ref parent) | hir::StmtKind::Expr(&ref parent), .. }) => { - parent_id = self.tcx.hir().parent_id(*hir_id); + parent_id = self.tcx.parent_hir_id(*hir_id); parent } hir::Node::Block(_) => { - parent_id = self.tcx.hir().parent_id(parent_id); + parent_id = self.tcx.parent_hir_id(parent_id); parent } _ => break, @@ -677,8 +677,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &hir::Expr<'_>, error: Option>, ) { - let parent = self.tcx.hir().parent_id(expr.hir_id); - match (self.tcx.hir_node(parent), error) { + match (self.tcx.parent_hir_node(expr.hir_id), error) { (hir::Node::Local(hir::Local { ty: Some(ty), init: Some(init), .. }), _) if init.hir_id == expr.hir_id => { @@ -724,16 +723,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let hir::Node::Pat(pat) = self.tcx.hir_node(*hir_id) { primary_span = pat.span; secondary_span = pat.span; - match self.tcx.hir().find_parent(pat.hir_id) { - Some(hir::Node::Local(hir::Local { ty: Some(ty), .. })) => { + match self.tcx.parent_hir_node(pat.hir_id) { + hir::Node::Local(hir::Local { ty: Some(ty), .. }) => { primary_span = ty.span; post_message = " type"; } - Some(hir::Node::Local(hir::Local { init: Some(init), .. })) => { + hir::Node::Local(hir::Local { init: Some(init), .. }) => { primary_span = init.span; post_message = " value"; } - Some(hir::Node::Param(hir::Param { ty_span, .. })) => { + hir::Node::Param(hir::Param { ty_span, .. }) => { primary_span = *ty_span; post_message = " parameter type"; } @@ -787,12 +786,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &hir::Expr<'_>, error: Option>, ) { - let parent = self.tcx.hir().parent_id(expr.hir_id); let Some(TypeError::Sorts(ExpectedFound { expected, .. })) = error else { return; }; let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(lhs, rhs, _), .. }) = - self.tcx.hir_node(parent) + self.tcx.parent_hir_node(expr.hir_id) else { return; }; @@ -1017,7 +1015,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { )) = expr.kind { let bind = self.tcx.hir_node(*bind_hir_id); - let parent = self.tcx.hir_node(self.tcx.hir().parent_id(*bind_hir_id)); + let parent = self.tcx.parent_hir_node(*bind_hir_id); if let hir::Node::Pat(hir::Pat { kind: hir::PatKind::Binding(_, _hir_id, _, _), .. }) = bind @@ -1088,7 +1086,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &hir::Expr<'_>, checked_ty: Ty<'tcx>, ) { - let Some(hir::Node::Expr(parent_expr)) = self.tcx.hir().find_parent(expr.hir_id) else { + let hir::Node::Expr(parent_expr) = self.tcx.parent_hir_node(expr.hir_id) else { return; }; enum CallableKind { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 292b85eb97f7f..31c97aab7fb83 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1016,7 +1016,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { original_expr_id: HirId, then: impl FnOnce(&hir::Expr<'_>), ) { - let mut parent = self.tcx.hir().parent_id(original_expr_id); + let mut parent = self.tcx.parent_hir_id(original_expr_id); loop { let node = self.tcx.hir_node(parent); match node { @@ -1038,15 +1038,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ), .. }) => { - // Check if our original expression is a child of the condition of a while loop - let expr_is_ancestor = std::iter::successors(Some(original_expr_id), |id| { - self.tcx.hir().opt_parent_id(*id) - }) - .take_while(|id| *id != parent) - .any(|id| id == expr.hir_id); - // if it is, then we have a situation like `while Some(0) = value.get(0) {`, + // Check if our original expression is a child of the condition of a while loop. + // If it is, then we have a situation like `while Some(0) = value.get(0) {`, // where `while let` was more likely intended. - if expr_is_ancestor { + if self.tcx.hir().parent_id_iter(original_expr_id).any(|id| id == expr.hir_id) { then(expr); } break; @@ -1056,7 +1051,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | hir::Node::TraitItem(_) | hir::Node::Crate(_) => break, _ => { - parent = self.tcx.hir().parent_id(parent); + parent = self.tcx.parent_hir_id(parent); } } } @@ -1199,9 +1194,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && !matches!(lhs.kind, hir::ExprKind::Lit(_)) { // Do not suggest `if let x = y` as `==` is way more likely to be the intention. - let hir = self.tcx.hir(); if let hir::Node::Expr(hir::Expr { kind: ExprKind::If { .. }, .. }) = - hir.get_parent(hir.parent_id(expr.hir_id)) + self.tcx.parent_hir_node(expr.hir_id) { err.span_suggestion_verbose( expr.span.shrink_to_lo(), @@ -2645,7 +2639,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_label(field.span, "method, not a field"); let expr_is_call = if let hir::Node::Expr(hir::Expr { kind: ExprKind::Call(callee, _args), .. }) = - self.tcx.hir().get_parent(expr.hir_id) + self.tcx.parent_hir_node(expr.hir_id) { expr.hir_id == callee.hir_id } else { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 36c3eef82fccb..7eb421ca8f5a9 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -764,7 +764,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let code = match lang_item { hir::LangItem::IntoFutureIntoFuture => { - if let hir::Node::Expr(into_future_call) = self.tcx.hir().get_parent(hir_id) + if let hir::Node::Expr(into_future_call) = self.tcx.parent_hir_node(hir_id) && let hir::ExprKind::Call(_, [arg0]) = &into_future_call.kind { Some(ObligationCauseCode::AwaitableExpr(arg0.hir_id)) @@ -956,12 +956,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .. }) => Some((hir::HirId::make_owner(owner_id.def_id), &sig.decl, ident, false)), Node::Expr(&hir::Expr { hir_id, kind: hir::ExprKind::Closure(..), .. }) - if let Some(Node::Item(&hir::Item { + if let Node::Item(&hir::Item { ident, kind: hir::ItemKind::Fn(ref sig, ..), owner_id, .. - })) = self.tcx.hir().find_parent(hir_id) => + }) = self.tcx.parent_hir_node(hir_id) => { Some(( hir::HirId::make_owner(owner_id.def_id), @@ -1574,7 +1574,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(in super::super) fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool { let mut contained_in_place = false; - while let hir::Node::Expr(parent_expr) = self.tcx.hir().get_parent(expr_id) { + while let hir::Node::Expr(parent_expr) = self.tcx.parent_hir_node(expr_id) { match &parent_expr.kind { hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => { if lhs.hir_id == expr_id { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index 1ad79cb78c4b1..6aa986b0df4c9 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -93,7 +93,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.find_ambiguous_parameter_in(def_id, error.root_obligation.predicate); } - let hir = self.tcx.hir(); let (expr, qpath) = match self.tcx.hir_node(hir_id) { hir::Node::Expr(expr) => { if self.closure_span_overlaps_error(error, expr.span) { @@ -122,7 +121,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir_id: call_hir_id, span: call_span, .. - }) = hir.get_parent(hir_id) + }) = self.tcx.parent_hir_node(hir_id) && callee.hir_id == hir_id { if self.closure_span_overlaps_error(error, *call_span) { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index ed0bdb9bdaa0d..193c9a4b90879 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -681,9 +681,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Check if the parent expression is a call to Pin::new. If it // is and we were expecting a Box, ergo Pin>, we // can suggest Box::pin. - let parent = self.tcx.hir().parent_id(expr.hir_id); let Node::Expr(Expr { kind: ExprKind::Call(fn_name, _), .. }) = - self.tcx.hir_node(parent) + self.tcx.parent_hir_node(expr.hir_id) else { return false; }; @@ -1687,7 +1686,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return expr; }; - match self.tcx.hir_node(self.tcx.hir().parent_id(*hir_id)) { + match self.tcx.parent_hir_node(*hir_id) { // foo.clone() hir::Node::Local(hir::Local { init: Some(init), .. }) => { self.note_type_is_not_clone_inner_expr(init) @@ -1699,7 +1698,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .. }) => { let hir::Node::Local(hir::Local { init: Some(init), .. }) = - self.tcx.hir_node(self.tcx.hir().parent_id(*pat_hir_id)) + self.tcx.parent_hir_node(*pat_hir_id) else { return expr; }; @@ -1733,7 +1732,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { call_expr_path && let hir::Node::Pat(hir::Pat { hir_id, .. }) = self.tcx.hir_node(*binding) && let hir::Node::Local(hir::Local { init: Some(init), .. }) = - self.tcx.hir_node(self.tcx.hir().parent_id(*hir_id)) + self.tcx.parent_hir_node(*hir_id) && let Expr { kind: hir::ExprKind::Closure(hir::Closure { body: body_id, .. }), .. @@ -1899,8 +1898,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> bool { let map = self.tcx.hir(); let returned = matches!( - map.find_parent(expr.hir_id), - Some(hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Ret(_), .. })) + self.tcx.parent_hir_node(expr.hir_id), + hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Ret(_), .. }) ) || map.get_return_block(expr.hir_id).is_some(); if returned && let ty::Adt(e, args_e) = expected.kind() @@ -1972,7 +1971,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Unroll desugaring, to make sure this works for `for` loops etc. loop { - parent = self.tcx.hir().parent_id(id); + parent = self.tcx.parent_hir_id(id); let parent_span = self.tcx.hir().span(parent); if parent_span.find_ancestor_inside(expr.span).is_some() { // The parent node is part of the same span, so is the result of the @@ -2211,24 +2210,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return None; }; - let local_parent = self.tcx.hir().parent_id(local_id); - let Node::Param(hir::Param { hir_id: param_hir_id, .. }) = self.tcx.hir_node(local_parent) + let Node::Param(hir::Param { hir_id: param_hir_id, .. }) = + self.tcx.parent_hir_node(local_id) else { return None; }; - let param_parent = self.tcx.hir().parent_id(*param_hir_id); let Node::Expr(hir::Expr { hir_id: expr_hir_id, kind: hir::ExprKind::Closure(hir::Closure { fn_decl: closure_fn_decl, .. }), .. - }) = self.tcx.hir_node(param_parent) + }) = self.tcx.parent_hir_node(*param_hir_id) else { return None; }; - let expr_parent = self.tcx.hir().parent_id(*expr_hir_id); - let hir = self.tcx.hir_node(expr_parent); + let hir = self.tcx.parent_hir_node(*expr_hir_id); let closure_params_len = closure_fn_decl.inputs.len(); let ( Node::Expr(hir::Expr { @@ -2409,10 +2406,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None => String::new(), }; - if let Some(hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::Assign(..), - .. - })) = self.tcx.hir().find_parent(expr.hir_id) + if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(..), .. }) = + self.tcx.parent_hir_node(expr.hir_id) { if mutability.is_mut() { // Suppressing this diagnostic, we'll properly print it in `check_expr_assign` @@ -2443,10 +2438,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // Suggest dereferencing the lhs for expressions such as `&T <= T` - if let Some(hir::Node::Expr(hir::Expr { + if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Binary(_, lhs, ..), .. - })) = self.tcx.hir().find_parent(expr.hir_id) + }) = self.tcx.parent_hir_node(expr.hir_id) && let &ty::Ref(..) = self.check_expr(lhs).kind() { let (sugg, verbose) = make_sugg(lhs, lhs.span, "*"); @@ -2602,7 +2597,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { || (checked_ty.is_box() && steps == 1) // We can always deref a binop that takes its arguments by ref. || matches!( - self.tcx.hir().get_parent(expr.hir_id), + self.tcx.parent_hir_node(expr.hir_id), hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Binary(op, ..), .. }) if !op.node.is_by_value() ) @@ -2664,10 +2659,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Returns whether the given expression is an `else if`. fn is_else_if_block(&self, expr: &hir::Expr<'_>) -> bool { if let hir::ExprKind::If(..) = expr.kind { - let parent_id = self.tcx.hir().parent_id(expr.hir_id); if let Node::Expr(hir::Expr { kind: hir::ExprKind::If(_, _, Some(else_expr)), .. - }) = self.tcx.hir_node(parent_id) + }) = self.tcx.parent_hir_node(expr.hir_id) { return else_expr.hir_id == expr.hir_id; } @@ -2704,7 +2698,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut sugg = vec![]; - if let Some(hir::Node::ExprField(field)) = self.tcx.hir().find_parent(expr.hir_id) { + if let hir::Node::ExprField(field) = self.tcx.parent_hir_node(expr.hir_id) { // `expr` is a literal field for a struct, only suggest if appropriate if field.is_shorthand { // This is a field literal @@ -3056,8 +3050,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { else { return; }; - let parent = self.tcx.hir().parent_id(expr.hir_id); - if let hir::Node::ExprField(_) = self.tcx.hir_node(parent) { + if let hir::Node::ExprField(_) = self.tcx.parent_hir_node(expr.hir_id) { // Ignore `Foo { field: a..Default::default() }` return; } @@ -3139,8 +3132,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let hir::Node::Pat(pat) = self.tcx.hir_node(hir_id) else { return; }; - let Some(hir::Node::Local(hir::Local { ty: None, init: Some(init), .. })) = - self.tcx.hir().find_parent(pat.hir_id) + let hir::Node::Local(hir::Local { ty: None, init: Some(init), .. }) = + self.tcx.parent_hir_node(pat.hir_id) else { return; }; diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 06a1461356707..c1af4b5983ebb 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -220,7 +220,7 @@ fn typeck_with_fallback<'tcx>( span, })) } else if let Node::AnonConst(_) = node { - match tcx.hir_node(tcx.hir().parent_id(id)) { + match tcx.parent_hir_node(id) { Node::Ty(&hir::Ty { kind: hir::TyKind::Typeof(ref anon_const), .. }) if anon_const.hir_id == id => { diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 81b8239351547..7fc51e36a2b64 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -128,7 +128,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let sugg_span = if let SelfSource::MethodCall(expr) = source { // Given `foo.bar(baz)`, `expr` is `bar`, but we want to point to the whole thing. - self.tcx.hir().expect_expr(self.tcx.hir().parent_id(expr.hir_id)).span + self.tcx.hir().expect_expr(self.tcx.parent_hir_id(expr.hir_id)).span } else { span }; @@ -231,9 +231,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = kind && let hir::def::Res::Local(hir_id) = path.res && let hir::Node::Pat(b) = self.tcx.hir_node(hir_id) - && let Some(hir::Node::Param(p)) = self.tcx.hir().find_parent(b.hir_id) - && let Some(node) = self.tcx.hir().find_parent(p.hir_id) - && let Some(decl) = node.fn_decl() + && let hir::Node::Param(p) = self.tcx.parent_hir_node(b.hir_id) + && let Some(decl) = self.tcx.parent_hir_node(p.hir_id).fn_decl() && let Some(ty) = decl.inputs.iter().find(|ty| ty.span == p.ty_span) && let hir::TyKind::Ref(_, mut_ty) = &ty.kind && let hir::Mutability::Not = mut_ty.mutbl @@ -471,7 +470,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let SelfSource::MethodCall(rcvr_expr) = source { self.suggest_fn_call(&mut err, rcvr_expr, rcvr_ty, |output_ty| { let call_expr = - self.tcx.hir().expect_expr(self.tcx.hir().parent_id(rcvr_expr.hir_id)); + self.tcx.hir().expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id)); let probe = self.lookup_probe_for_diagnostic( item_name, output_ty, @@ -1020,7 +1019,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { rcvr_ty, &item_segment, span, - tcx.hir().get_parent(rcvr_expr.hir_id).expect_expr(), + tcx.parent_hir_node(rcvr_expr.hir_id).expect_expr(), rcvr_expr, ) { err.span_note( @@ -1254,7 +1253,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let msg = "remove this method call"; let mut fallback_span = true; if let SelfSource::MethodCall(expr) = source { - let call_expr = self.tcx.hir().expect_expr(self.tcx.hir().parent_id(expr.hir_id)); + let call_expr = self.tcx.hir().expect_expr(self.tcx.parent_hir_id(expr.hir_id)); if let Some(span) = call_expr.span.trim_start(expr.span) { err.span_suggestion(span, msg, "", Applicability::MachineApplicable); fallback_span = false; @@ -1753,7 +1752,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Applicability::MachineApplicable, ); } else { - let call_expr = tcx.hir().expect_expr(tcx.hir().parent_id(expr.hir_id)); + let call_expr = tcx.hir().expect_expr(tcx.parent_hir_id(expr.hir_id)); if let Some(span) = call_expr.span.trim_start(item_name.span) { err.span_suggestion( @@ -1937,7 +1936,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let span = tcx.hir().span(hir_id); let filename = tcx.sess.source_map().span_to_filename(span); - let parent_node = self.tcx.hir().get_parent(hir_id); + let parent_node = self.tcx.parent_hir_node(hir_id); let msg = format!( "you must specify a type for this binding, like `{concrete_type}`", ); @@ -2016,8 +2015,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut visitor = LetVisitor { result: None, ident_name: seg1.ident.name }; visitor.visit_body(body); - let parent = self.tcx.hir().parent_id(seg1.hir_id); - if let Node::Expr(call_expr) = self.tcx.hir_node(parent) + if let Node::Expr(call_expr) = self.tcx.parent_hir_node(seg1.hir_id) && let Some(expr) = visitor.result && let Some(self_ty) = self.node_ty_opt(expr.hir_id) { @@ -2056,7 +2054,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for (fields, args) in self.get_field_candidates_considering_privacy(span, actual, mod_id, expr.hir_id) { - let call_expr = self.tcx.hir().expect_expr(self.tcx.hir().parent_id(expr.hir_id)); + let call_expr = self.tcx.hir().expect_expr(self.tcx.parent_hir_id(expr.hir_id)); let lang_items = self.tcx.lang_items(); let never_mention_traits = [ @@ -2133,7 +2131,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let SelfSource::MethodCall(expr) = source else { return; }; - let call_expr = tcx.hir().expect_expr(tcx.hir().parent_id(expr.hir_id)); + let call_expr = tcx.hir().expect_expr(tcx.parent_hir_id(expr.hir_id)); let ty::Adt(kind, args) = actual.kind() else { return; @@ -3250,8 +3248,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return false; } - let parent = self.tcx.hir().parent_id(expr.hir_id); - if let Node::Expr(call_expr) = self.tcx.hir_node(parent) + if let Node::Expr(call_expr) = self.tcx.parent_hir_node(expr.hir_id) && let hir::ExprKind::MethodCall( hir::PathSegment { ident: method_name, .. }, self_expr, diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index 9ce6189856194..9a8444e6a2bcd 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -383,7 +383,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; if self.check_for_missing_semi(expr, &mut err) - && let hir::Node::Expr(expr) = self.tcx.hir().get_parent(expr.hir_id) + && let hir::Node::Expr(expr) = self.tcx.parent_hir_node(expr.hir_id) && let hir::ExprKind::Assign(..) = expr.kind { // We defer to the later error produced by `check_lhs_assignable`. diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index fcf4b59e93fcd..67aa92185852f 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -720,8 +720,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let PatKind::Ref(inner, mutbl) = pat.kind && let PatKind::Binding(_, _, binding, ..) = inner.kind { - let binding_parent_id = tcx.hir().parent_id(pat.hir_id); - let binding_parent = tcx.hir_node(binding_parent_id); + let binding_parent = tcx.parent_hir_node(pat.hir_id); debug!(?inner, ?pat, ?binding_parent); let mutability = match mutbl { @@ -989,7 +988,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { res.descr(), ), ); - match self.tcx.hir().get_parent(pat.hir_id) { + match self.tcx.parent_hir_node(pat.hir_id) { hir::Node::PatField(..) => { e.span_suggestion_verbose( ident.span.shrink_to_hi(), diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index dd9ed80ca7242..4d2d19b51e22c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -862,8 +862,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ) { err.subdiagnostic(subdiag); } - if let Some(hir::Node::Expr(m)) = self.tcx.hir().find_parent(scrut_hir_id) - && let Some(hir::Node::Stmt(stmt)) = self.tcx.hir().find_parent(m.hir_id) + if let hir::Node::Expr(m) = self.tcx.parent_hir_node(scrut_hir_id) + && let hir::Node::Stmt(stmt) = self.tcx.parent_hir_node(m.hir_id) && let hir::StmtKind::Expr(_) = stmt.kind { err.span_suggestion_verbose( diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index f884ca83073df..3c42f13141dd0 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -106,7 +106,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } p_def_id.as_local().and_then(|id| { let local_id = tcx.local_def_id_to_hir_id(id); - let generics = tcx.hir().find_parent(local_id)?.generics()?; + let generics = tcx.parent_hir_node(local_id).generics()?; Some((id, generics)) }) }); diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index bbe07b8ed72b2..248e1c0fcc878 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -735,30 +735,29 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }; local.pat.walk(&mut find_compatible_candidates); } - match hir.find_parent(blk.hir_id) { - Some(hir::Node::Expr(hir::Expr { hir_id, .. })) => match hir.find_parent(*hir_id) { - Some(hir::Node::Arm(hir::Arm { pat, .. })) => { + match self.tcx.parent_hir_node(blk.hir_id) { + hir::Node::Expr(hir::Expr { hir_id, .. }) => match self.tcx.parent_hir_node(*hir_id) { + hir::Node::Arm(hir::Arm { pat, .. }) => { pat.walk(&mut find_compatible_candidates); } - Some( - hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body), .. }) - | hir::Node::ImplItem(hir::ImplItem { - kind: hir::ImplItemKind::Fn(_, body), .. - }) - | hir::Node::TraitItem(hir::TraitItem { - kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body)), - .. - }) - | hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::Closure(hir::Closure { body, .. }), - .. - }), - ) => { + + hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body), .. }) + | hir::Node::ImplItem(hir::ImplItem { + kind: hir::ImplItemKind::Fn(_, body), .. + }) + | hir::Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body)), + .. + }) + | hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Closure(hir::Closure { body, .. }), + .. + }) => { for param in hir.body(*body).params { param.pat.walk(&mut find_compatible_candidates); } } - Some(hir::Node::Expr(hir::Expr { + hir::Node::Expr(hir::Expr { kind: hir::ExprKind::If( hir::Expr { kind: hir::ExprKind::Let(let_), .. }, @@ -766,7 +765,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { _, ), .. - })) if then_block.hir_id == *hir_id => { + }) if then_block.hir_id == *hir_id => { let_.pat.walk(&mut find_compatible_candidates); } _ => {} diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs index 7401654aea8bf..0253f5a2df2a2 100644 --- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs @@ -65,10 +65,10 @@ pub fn report_object_safety_error<'tcx>( && let hir::TyKind::TraitObject([trait_ref, ..], ..) = ty.kind { let mut hir_id = hir_id; - while let hir::Node::Ty(ty) = tcx.hir().get_parent(hir_id) { + while let hir::Node::Ty(ty) = tcx.parent_hir_node(hir_id) { hir_id = ty.hir_id; } - if tcx.hir().get_parent(hir_id).fn_sig().is_some() { + if tcx.parent_hir_node(hir_id).fn_sig().is_some() { // Do not suggest `impl Trait` when dealing with things like super-traits. err.span_suggestion_verbose( ty.span.until(trait_ref.span), diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index f10d3d4a68a76..6ee1d1ca92472 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1416,8 +1416,7 @@ impl<'tcx> LateLintPass<'tcx> for UnreachablePub { } fn check_field_def(&mut self, cx: &LateContext<'_>, field: &hir::FieldDef<'_>) { - let map = cx.tcx.hir(); - if matches!(map.get_parent(field.hir_id), Node::Variant(_)) { + if matches!(cx.tcx.parent_hir_node(field.hir_id), Node::Variant(_)) { return; } self.perform_lint(cx, "field", field.def_id, field.vis_span, false); diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 1c480ec8f53b1..30f05444d2103 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -933,7 +933,7 @@ impl<'tcx> LateContext<'tcx> { while let hir::ExprKind::Path(ref qpath) = expr.kind && let Some(parent_node) = match self.qpath_res(qpath, expr.hir_id) { - Res::Local(hir_id) => self.tcx.hir().find_parent(hir_id), + Res::Local(hir_id) => Some(self.tcx.parent_hir_node(hir_id)), _ => None, } && let Some(init) = match parent_node { @@ -977,7 +977,7 @@ impl<'tcx> LateContext<'tcx> { while let hir::ExprKind::Path(ref qpath) = expr.kind && let Some(parent_node) = match self.qpath_res(qpath, expr.hir_id) { - Res::Local(hir_id) => self.tcx.hir().find_parent(hir_id), + Res::Local(hir_id) => Some(self.tcx.parent_hir_node(hir_id)), Res::Def(_, def_id) => self.tcx.hir().get_if_local(def_id), _ => None, } diff --git a/compiler/rustc_lint/src/drop_forget_useless.rs b/compiler/rustc_lint/src/drop_forget_useless.rs index 9a31aa062f01a..78ac7f9b2354d 100644 --- a/compiler/rustc_lint/src/drop_forget_useless.rs +++ b/compiler/rustc_lint/src/drop_forget_useless.rs @@ -214,8 +214,7 @@ fn is_single_call_in_arm<'tcx>( drop_expr: &'tcx Expr<'_>, ) -> bool { if arg.can_have_side_effects() { - let parent_node = cx.tcx.hir().find_parent(drop_expr.hir_id); - if let Some(Node::Arm(Arm { body, .. })) = &parent_node { + if let Node::Arm(Arm { body, .. }) = cx.tcx.parent_hir_node(drop_expr.hir_id) { return body.hir_id == drop_expr.hir_id; } } diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 516df14c8943a..596221a8455c5 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -144,15 +144,14 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind { match &ty.kind { TyKind::Path(QPath::Resolved(_, path)) => { if lint_ty_kind_usage(cx, &path.res) { - let hir = cx.tcx.hir(); - let span = match hir.find_parent(ty.hir_id) { - Some(Node::Pat(Pat { + let span = match cx.tcx.parent_hir_node(ty.hir_id) { + Node::Pat(Pat { kind: PatKind::Path(qpath) | PatKind::TupleStruct(qpath, ..) | PatKind::Struct(qpath, ..), .. - })) => { + }) => { if let QPath::TypeRelative(qpath_ty, ..) = qpath && qpath_ty.hir_id == ty.hir_id { @@ -161,7 +160,7 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind { None } } - Some(Node::Expr(Expr { kind: ExprKind::Path(qpath), .. })) => { + Node::Expr(Expr { kind: ExprKind::Path(qpath), .. }) => { if let QPath::TypeRelative(qpath_ty, ..) = qpath && qpath_ty.hir_id == ty.hir_id { @@ -172,7 +171,7 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind { } // Can't unify these two branches because qpath below is `&&` and above is `&` // and `A | B` paths don't play well together with adjustments, apparently. - Some(Node::Expr(Expr { kind: ExprKind::Struct(qpath, ..), .. })) => { + Node::Expr(Expr { kind: ExprKind::Struct(qpath, ..), .. }) => { if let QPath::TypeRelative(qpath_ty, ..) = qpath && qpath_ty.hir_id == ty.hir_id { diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 05b39829a12f1..4ecd87e37d3b5 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -427,7 +427,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase { fn check_pat(&mut self, cx: &LateContext<'_>, p: &hir::Pat<'_>) { if let PatKind::Binding(_, hid, ident, _) = p.kind { - if let hir::Node::PatField(field) = cx.tcx.hir().get_parent(hid) { + if let hir::Node::PatField(field) = cx.tcx.parent_hir_node(hid) { if !field.is_shorthand { // Only check if a new name has been introduced, to avoid warning // on both the struct definition and this pattern. diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 1205395b8908d..e4ebae2a97320 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -200,8 +200,7 @@ fn lint_overflowing_range_endpoint<'tcx>( ty: &str, ) -> bool { // Look past casts to support cases like `0..256 as u8` - let (expr, lit_span) = if let Node::Expr(par_expr) = - cx.tcx.hir_node(cx.tcx.hir().parent_id(expr.hir_id)) + let (expr, lit_span) = if let Node::Expr(par_expr) = cx.tcx.parent_hir_node(expr.hir_id) && let ExprKind::Cast(_, _) = par_expr.kind { (par_expr, expr.span) @@ -211,9 +210,8 @@ fn lint_overflowing_range_endpoint<'tcx>( // We only want to handle exclusive (`..`) ranges, // which are represented as `ExprKind::Struct`. - let par_id = cx.tcx.hir().parent_id(expr.hir_id); - let Node::ExprField(field) = cx.tcx.hir_node(par_id) else { return false }; - let Node::Expr(struct_expr) = cx.tcx.hir().get_parent(field.hir_id) else { return false }; + let Node::ExprField(field) = cx.tcx.parent_hir_node(expr.hir_id) else { return false }; + let Node::Expr(struct_expr) = cx.tcx.parent_hir_node(field.hir_id) else { return false }; if !is_range_literal(struct_expr) { return false; }; @@ -496,8 +494,7 @@ fn lint_uint_literal<'tcx>( _ => bug!(), }; if lit_val < min || lit_val > max { - let parent_id = cx.tcx.hir().parent_id(e.hir_id); - if let Node::Expr(par_e) = cx.tcx.hir_node(parent_id) { + if let Node::Expr(par_e) = cx.tcx.parent_hir_node(e.hir_id) { match par_e.kind { hir::ExprKind::Cast(..) => { if let ty::Char = cx.typeck_results().expr_ty(par_e).kind() { diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 7cd2f58779f84..988388edfd5ff 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -250,6 +250,7 @@ provide! { tcx, def_id, other, cdata, asyncness => { table_direct } fn_arg_names => { table } coroutine_kind => { table_direct } + coroutine_for_closure => { table } trait_def => { table } deduced_param_attrs => { table } is_type_alias_impl_trait => { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 79aa9a547f7c6..6ca1973396f81 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1447,6 +1447,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { { self.tables.coroutine_kind.set(def_id.index, Some(coroutine_kind)) } + if def_kind == DefKind::Closure + && tcx.type_of(def_id).skip_binder().is_coroutine_closure() + { + self.tables + .coroutine_for_closure + .set_some(def_id.index, self.tcx.coroutine_for_closure(def_id).into()); + } if let DefKind::Enum | DefKind::Struct | DefKind::Union = def_kind { self.encode_info_for_adt(local_id); } diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 2f77588269345..8205e995c1962 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -443,6 +443,7 @@ define_tables! { asyncness: Table, fn_arg_names: Table>, coroutine_kind: Table, + coroutine_for_closure: Table, trait_def: Table>, trait_item_def_id: Table, expn_that_defined: Table>, diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index bf72aac10332e..50817dd0a8093 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -82,7 +82,7 @@ impl<'hir> Iterator for ParentHirIterator<'hir> { } // There are nodes that do not have entries, so we need to skip them. - let parent_id = self.map.parent_id(self.current_id); + let parent_id = self.map.tcx.parent_hir_id(self.current_id); if parent_id == self.current_id { self.current_id = CRATE_HIR_ID; @@ -175,6 +175,28 @@ impl<'tcx> TyCtxt<'tcx> { self.opt_hir_node_by_def_id(id) .unwrap_or_else(|| bug!("couldn't find HIR node for def id {id:?}")) } + + /// Returns `HirId` of the parent HIR node of node with this `hir_id`. + /// Returns the same `hir_id` if and only if `hir_id == CRATE_HIR_ID`. + /// + /// If calling repeatedly and iterating over parents, prefer [`Map::parent_iter`]. + pub fn parent_hir_id(self, hir_id: HirId) -> HirId { + let HirId { owner, local_id } = hir_id; + if local_id == ItemLocalId::from_u32(0) { + self.hir_owner_parent(owner) + } else { + let parent_local_id = self.hir_owner_nodes(owner).nodes[local_id].parent; + // HIR indexing should have checked that. + debug_assert_ne!(parent_local_id, local_id); + HirId { owner, local_id: parent_local_id } + } + } + + /// Returns parent HIR node of node with this `hir_id`. + /// Returns HIR node of the same `hir_id` if and only if `hir_id == CRATE_HIR_ID`. + pub fn parent_hir_node(self, hir_id: HirId) -> Node<'tcx> { + self.hir_node(self.parent_hir_id(hir_id)) + } } impl<'hir> Map<'hir> { @@ -217,39 +239,6 @@ impl<'hir> Map<'hir> { self.tcx.definitions_untracked().def_path_hash(def_id) } - /// Finds the id of the parent node to this one. - /// - /// If calling repeatedly and iterating over parents, prefer [`Map::parent_iter`]. - pub fn opt_parent_id(self, id: HirId) -> Option { - if id.local_id == ItemLocalId::from_u32(0) { - // FIXME: This function never returns `None` right now, and the parent chain end is - // determined by checking for `parent(id) == id`. This function should return `None` - // for the crate root instead. - Some(self.tcx.hir_owner_parent(id.owner)) - } else { - let owner = self.tcx.hir_owner_nodes(id.owner); - let node = &owner.nodes[id.local_id]; - let hir_id = HirId { owner: id.owner, local_id: node.parent }; - // HIR indexing should have checked that. - debug_assert_ne!(id.local_id, node.parent); - Some(hir_id) - } - } - - #[track_caller] - pub fn parent_id(self, hir_id: HirId) -> HirId { - self.opt_parent_id(hir_id) - .unwrap_or_else(|| bug!("No parent for node {}", self.node_to_string(hir_id))) - } - - pub fn get_parent(self, hir_id: HirId) -> Node<'hir> { - self.tcx.hir_node(self.parent_id(hir_id)) - } - - pub fn find_parent(self, hir_id: HirId) -> Option> { - Some(self.tcx.hir_node(self.opt_parent_id(hir_id)?)) - } - pub fn get_if_local(self, id: DefId) -> Option> { id.as_local() .and_then(|id| Some(self.tcx.hir_node(self.tcx.opt_local_def_id_to_hir_id(id)?))) @@ -304,14 +293,13 @@ impl<'hir> Map<'hir> { /// which this is the body of, i.e., a `fn`, `const` or `static` /// item (possibly associated), a closure, or a `hir::AnonConst`. pub fn body_owner(self, BodyId { hir_id }: BodyId) -> HirId { - let parent = self.parent_id(hir_id); + let parent = self.tcx.parent_hir_id(hir_id); assert!(is_body_owner(self.tcx.hir_node(parent), hir_id), "{hir_id:?}"); parent } pub fn body_owner_def_id(self, BodyId { hir_id }: BodyId) -> LocalDefId { - let parent = self.parent_id(hir_id); - associated_body(self.tcx.hir_node(parent)).unwrap().0 + associated_body(self.tcx.parent_hir_node(hir_id)).unwrap().0 } /// Given a `LocalDefId`, returns the `BodyId` associated with it, @@ -569,8 +557,8 @@ impl<'hir> Map<'hir> { /// Checks if the node is left-hand side of an assignment. pub fn is_lhs(self, id: HirId) -> bool { - match self.find_parent(id) { - Some(Node::Expr(expr)) => match expr.kind { + match self.tcx.parent_hir_node(id) { + Node::Expr(expr) => match expr.kind { ExprKind::Assign(lhs, _rhs, _span) => lhs.hir_id == id, _ => false, }, @@ -793,7 +781,7 @@ impl<'hir> Map<'hir> { Node::Pat(&Pat { kind: PatKind::Binding(_, _, ident, _), .. }) => Some(ident), // A `Ctor` doesn't have an identifier itself, but its parent // struct/variant does. Compare with `hir::Map::span`. - Node::Ctor(..) => match self.find_parent(id)? { + Node::Ctor(..) => match self.tcx.parent_hir_node(id) { Node::Item(item) => Some(item.ident), Node::Variant(variant) => Some(variant.ident), _ => unreachable!(), @@ -925,7 +913,7 @@ impl<'hir> Map<'hir> { ForeignItemKind::Fn(decl, _, _) => until_within(item.span, decl.output.span()), _ => named_span(item.span, item.ident, None), }, - Node::Ctor(_) => return self.span(self.parent_id(hir_id)), + Node::Ctor(_) => return self.span(self.tcx.parent_hir_id(hir_id)), Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl_span, .. }), span, @@ -968,7 +956,7 @@ impl<'hir> Map<'hir> { Node::PatField(field) => field.span, Node::Arm(arm) => arm.span, Node::Block(block) => block.span, - Node::Ctor(..) => self.span_with_body(self.parent_id(hir_id)), + Node::Ctor(..) => self.span_with_body(self.tcx.parent_hir_id(hir_id)), Node::Lifetime(lifetime) => lifetime.ident.span, Node::GenericParam(param) => param.span, Node::Infer(i) => i.span, @@ -1001,7 +989,7 @@ impl<'hir> Map<'hir> { /// Returns the HirId of `N` in `struct Foo` when /// called with the HirId for the `{ ... }` anon const pub fn opt_const_param_default_param_def_id(self, anon_const: HirId) -> Option { - match self.get_parent(anon_const) { + match self.tcx.parent_hir_node(anon_const) { Node::GenericParam(GenericParam { def_id: param_id, kind: GenericParamKind::Const { .. }, @@ -1026,7 +1014,7 @@ impl<'hir> Map<'hir> { _ => None, }?; - match self.find_parent(expr.hir_id)? { + match self.tcx.parent_hir_node(expr.hir_id) { Node::ExprField(field) => { if field.ident.name == local.name && field.is_shorthand { return Some(local.name); diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index f66cd2370e3ee..4ef9bc16221f2 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -136,13 +136,14 @@ pub fn provide(providers: &mut Providers) { }; providers.opt_hir_owner_nodes = |tcx, id| tcx.hir_crate(()).owners.get(id)?.as_owner().map(|i| &i.nodes); - providers.hir_owner_parent = |tcx, id| { - // Accessing the local_parent is ok since its value is hashed as part of `id`'s DefPathHash. - tcx.opt_local_parent(id.def_id).map_or(CRATE_HIR_ID, |parent| { - let mut parent_hir_id = tcx.local_def_id_to_hir_id(parent); - parent_hir_id.local_id = - tcx.hir_crate(()).owners[parent_hir_id.owner.def_id].unwrap().parenting[&id.def_id]; - parent_hir_id + providers.hir_owner_parent = |tcx, owner_id| { + tcx.opt_local_parent(owner_id.def_id).map_or(CRATE_HIR_ID, |parent_def_id| { + let parent_owner_id = tcx.local_def_id_to_hir_id(parent_def_id).owner; + HirId { + owner: parent_owner_id, + local_id: tcx.hir_crate(()).owners[parent_owner_id.def_id].unwrap().parenting + [&owner_id.def_id], + } }) }; providers.hir_attrs = |tcx, id| { diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index 2d3669487718b..04740a9629152 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -792,7 +792,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { return id; } - let next = hir.parent_id(id); + let next = self.tcx.parent_hir_id(id); if next == id { bug!("lint traversal reached the root of the crate"); } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index ec704dec352da..c24827ea902da 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -2069,14 +2069,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { span: Span, target: Target, ) -> bool { - let hir = self.tcx.hir(); - if let Target::ForeignFn = target - && let Some(parent) = hir.opt_parent_id(hir_id) && let hir::Node::Item(Item { kind: ItemKind::ForeignMod { abi: Abi::RustIntrinsic | Abi::PlatformIntrinsic, .. }, .. - }) = self.tcx.hir_node(parent) + }) = self.tcx.parent_hir_node(hir_id) { return true; } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index f68200b6f4d5e..eb75b04ed1c0d 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1032,15 +1032,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } }; - let hir = self.tcx.hir(); let hir_id = self.tcx.local_def_id_to_hir_id(def_id.as_local()?); - match hir.find_parent(hir_id) { - Some(hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(local), .. })) => { + match self.tcx.parent_hir_node(hir_id) { + hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(local), .. }) => { get_name(err, &local.pat.kind) } // Different to previous arm because one is `&hir::Local` and the other // is `P`. - Some(hir::Node::Local(local)) => get_name(err, &local.pat.kind), + hir::Node::Local(local) => get_name(err, &local.pat.kind), _ => None, } } @@ -1202,8 +1201,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let hir::Node::Pat(pat) = self.tcx.hir_node(hir_id) else { return; }; - let Some(hir::Node::Local(hir::Local { ty: None, init: Some(init), .. })) = - self.tcx.hir().find_parent(pat.hir_id) + let hir::Node::Local(hir::Local { ty: None, init: Some(init), .. }) = + self.tcx.parent_hir_node(pat.hir_id) else { return; }; @@ -1790,7 +1789,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind && let Res::Local(hir_id) = path.res && let hir::Node::Pat(binding) = self.tcx.hir_node(hir_id) - && let Some(hir::Node::Local(local)) = self.tcx.hir().find_parent(binding.hir_id) + && let hir::Node::Local(local) = self.tcx.parent_hir_node(binding.hir_id) && let None = local.ty && let Some(binding_expr) = local.init { @@ -3188,8 +3187,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } ObligationCauseCode::VariableType(hir_id) => { - let parent_node = tcx.hir().parent_id(hir_id); - match tcx.hir_node(parent_node) { + match tcx.parent_hir_node(hir_id) { Node::Local(hir::Local { ty: Some(ty), .. }) => { err.span_suggestion_verbose( ty.span.shrink_to_lo(), @@ -3237,8 +3235,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { types always have a known size"; if let Some(hir_id) = hir_id && let hir::Node::Param(param) = self.tcx.hir_node(hir_id) - && let Some(item) = self.tcx.hir().find_parent(hir_id) - && let Some(decl) = item.fn_decl() + && let Some(decl) = self.tcx.parent_hir_node(hir_id).fn_decl() && let Some(t) = decl.inputs.iter().find(|t| param.ty_span.contains(t.span)) { // We use `contains` because the type might be surrounded by parentheses, @@ -4079,8 +4076,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind && let hir::Path { res: Res::Local(hir_id), .. } = path && let hir::Node::Pat(binding) = self.tcx.hir_node(*hir_id) - && let parent_hir_id = self.tcx.hir().parent_id(binding.hir_id) - && let hir::Node::Local(local) = self.tcx.hir_node(parent_hir_id) + && let hir::Node::Local(local) = self.tcx.parent_hir_node(binding.hir_id) && let Some(binding_expr) = local.init { // If the expression we're calling on is a binding, we want to point at the @@ -4338,8 +4334,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind && let hir::Path { res: Res::Local(hir_id), .. } = path && let hir::Node::Pat(binding) = self.tcx.hir_node(*hir_id) - && let Some(parent) = self.tcx.hir().find_parent(binding.hir_id) { + let parent = self.tcx.parent_hir_node(binding.hir_id); // We've reached the root of the method call chain... if let hir::Node::Local(local) = parent && let Some(binding_expr) = local.init diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 07e4fef9dd4f2..7d14395850b04 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -1162,8 +1162,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind && let hir::Path { res: hir::def::Res::Local(hir_id), .. } = path && let hir::Node::Pat(binding) = self.tcx.hir_node(*hir_id) - && let Some(parent) = self.tcx.hir().find_parent(binding.hir_id) { + let parent = self.tcx.parent_hir_node(binding.hir_id); // We've reached the root of the method call chain... if let hir::Node::Local(local) = parent && let Some(binding_expr) = local.init diff --git a/library/alloc/src/boxed/thin.rs b/library/alloc/src/boxed/thin.rs index f83c8f83cc989..3b29c144a89f8 100644 --- a/library/alloc/src/boxed/thin.rs +++ b/library/alloc/src/boxed/thin.rs @@ -67,6 +67,26 @@ impl ThinBox { let ptr = WithOpaqueHeader::new(meta, value); ThinBox { ptr, _marker: PhantomData } } + + /// Moves a type to the heap with its [`Metadata`] stored in the heap allocation instead of on + /// the stack. Returns an error if allocation fails, instead of aborting. + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_api)] + /// #![feature(thin_box)] + /// use std::boxed::ThinBox; + /// + /// let five = ThinBox::try_new(5)?; + /// # Ok::<(), std::alloc::AllocError>(()) + /// ``` + /// + /// [`Metadata`]: core::ptr::Pointee::Metadata + pub fn try_new(value: T) -> Result { + let meta = ptr::metadata(&value); + WithOpaqueHeader::try_new(meta, value).map(|ptr| ThinBox { ptr, _marker: PhantomData }) + } } #[unstable(feature = "thin_box", issue = "92791")] @@ -179,6 +199,10 @@ impl WithOpaqueHeader { let ptr = WithHeader::new(header, value); Self(ptr.0) } + + fn try_new(header: H, value: T) -> Result { + WithHeader::try_new(header, value).map(|ptr| Self(ptr.0)) + } } impl WithHeader { @@ -224,6 +248,46 @@ impl WithHeader { } } + /// Non-panicking version of `new`. + /// Any error is returned as `Err(core::alloc::AllocError)`. + fn try_new(header: H, value: T) -> Result, core::alloc::AllocError> { + let value_layout = Layout::new::(); + let Ok((layout, value_offset)) = Self::alloc_layout(value_layout) else { + return Err(core::alloc::AllocError); + }; + + unsafe { + // Note: It's UB to pass a layout with a zero size to `alloc::alloc`, so + // we use `layout.dangling()` for this case, which should have a valid + // alignment for both `T` and `H`. + let ptr = if layout.size() == 0 { + // Some paranoia checking, mostly so that the ThinBox tests are + // more able to catch issues. + debug_assert!( + value_offset == 0 && mem::size_of::() == 0 && mem::size_of::() == 0 + ); + layout.dangling() + } else { + let ptr = alloc::alloc(layout); + if ptr.is_null() { + return Err(core::alloc::AllocError); + } + + // Safety: + // - The size is at least `aligned_header_size`. + let ptr = ptr.add(value_offset) as *mut _; + + NonNull::new_unchecked(ptr) + }; + + let result = WithHeader(ptr, PhantomData); + ptr::write(result.header(), header); + ptr::write(result.value().cast(), value); + + Ok(result) + } + } + // Safety: // - Assumes that either `value` can be dereferenced, or is the // `NonNull::dangling()` we use when both `T` and `H` are ZSTs. diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 030040ba09abb..c77fa371cc74a 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -237,9 +237,9 @@ use crate::cmp::Ordering; use crate::fmt::{self, Debug, Display}; -use crate::intrinsics::is_nonoverlapping; +use crate::intrinsics; use crate::marker::{PhantomData, Unsize}; -use crate::mem; +use crate::mem::{self, size_of}; use crate::ops::{CoerceUnsized, Deref, DerefMut, DispatchFromDyn}; use crate::ptr::{self, NonNull}; @@ -435,11 +435,15 @@ impl Cell { #[inline] #[stable(feature = "move_cell", since = "1.17.0")] pub fn swap(&self, other: &Self) { + fn is_nonoverlapping(src: *const T, dst: *const T) -> bool { + intrinsics::is_nonoverlapping(src.cast(), dst.cast(), size_of::(), 1) + } + if ptr::eq(self, other) { // Swapping wouldn't change anything. return; } - if !is_nonoverlapping(self, other, 1) { + if !is_nonoverlapping(self, other) { // See for why we need to stop here. panic!("`Cell::swap` on overlapping non-identical `Cell`s"); } diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 18c82f97c28e9..c8259c0024c75 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -56,7 +56,7 @@ use crate::marker::DiscriminantKind; use crate::marker::Tuple; -use crate::mem::{self, align_of}; +use crate::mem::align_of; pub mod mir; pub mod simd; @@ -1027,7 +1027,7 @@ extern "rust-intrinsic" { /// The size of the referenced value in bytes. /// - /// The stabilized version of this intrinsic is [`mem::size_of_val`]. + /// The stabilized version of this intrinsic is [`crate::mem::size_of_val`]. #[rustc_const_unstable(feature = "const_size_of_val", issue = "46571")] #[rustc_nounwind] pub fn size_of_val(_: *const T) -> usize; @@ -1107,7 +1107,7 @@ extern "rust-intrinsic" { /// Moves a value out of scope without running drop glue. /// - /// This exists solely for [`mem::forget_unsized`]; normal `forget` uses + /// This exists solely for [`crate::mem::forget_unsized`]; normal `forget` uses /// `ManuallyDrop` instead. /// /// Note that, unlike most intrinsics, this is safe to call; @@ -1233,7 +1233,7 @@ extern "rust-intrinsic" { /// Depending on what the code is doing, the following alternatives are preferable to /// pointer-to-integer transmutation: /// - If the code just wants to store data of arbitrary type in some buffer and needs to pick a - /// type for that buffer, it can use [`MaybeUninit`][mem::MaybeUninit]. + /// type for that buffer, it can use [`MaybeUninit`][crate::mem::MaybeUninit]. /// - If the code actually wants to work on the address the pointer points to, it can use `as` /// casts or [`ptr.addr()`][pointer::addr]. /// @@ -2317,7 +2317,7 @@ extern "rust-intrinsic" { /// Therefore, implementations must not require the user to uphold /// any safety invariants. /// - /// The to-be-stabilized version of this intrinsic is [`mem::variant_count`]. + /// The to-be-stabilized version of this intrinsic is [`crate::mem::variant_count`]. #[rustc_const_unstable(feature = "variant_count", issue = "73662")] #[rustc_safe_intrinsic] #[rustc_nounwind] @@ -2569,6 +2569,19 @@ extern "rust-intrinsic" { #[rustc_nounwind] pub fn is_val_statically_known(arg: T) -> bool; + /// Returns the value of `cfg!(debug_assertions)`, but after monomorphization instead of in + /// macro expansion. + /// + /// This always returns `false` in const eval and Miri. The interpreter provides better + /// diagnostics than the checks that this is used to implement. However, this means + /// you should only be using this intrinsic to guard requirements that, if violated, + /// immediately lead to UB. Otherwise, const-eval and Miri will miss out on those + /// checks entirely. + /// + /// Since this is evaluated after monomorphization, branching on this value can be used to + /// implement debug assertions that are included in the precompiled standard library, but can + /// be optimized out by builds that monomorphize the standard library code with debug + /// assertions disabled. This intrinsic is primarily used by [`assert_unsafe_precondition`]. #[rustc_const_unstable(feature = "delayed_debug_assertions", issue = "none")] #[rustc_safe_intrinsic] #[cfg(not(bootstrap))] @@ -2597,7 +2610,7 @@ pub(crate) const fn debug_assertions() -> bool { /// These checks are behind a condition which is evaluated at codegen time, not expansion time like /// [`debug_assert`]. This means that a standard library built with optimizations and debug /// assertions disabled will have these checks optimized out of its monomorphizations, but if a -/// a caller of the standard library has debug assertions enabled and monomorphizes an expansion of +/// caller of the standard library has debug assertions enabled and monomorphizes an expansion of /// this macro, that monomorphization will contain the check. /// /// Since these checks cannot be optimized out in MIR, some care must be taken in both call and @@ -2606,8 +2619,8 @@ pub(crate) const fn debug_assertions() -> bool { /// combination of properties ensures that the code for the checks is only compiled once, and has a /// minimal impact on the caller's code size. /// -/// Caller should also introducing any other `let` bindings or any code outside this macro in order -/// to call it. Since the precompiled standard library is built with full debuginfo and these +/// Callers should also avoid introducing any other `let` bindings or any code outside this macro in +/// order to call it. Since the precompiled standard library is built with full debuginfo and these /// variables cannot be optimized out in MIR, an innocent-looking `let` can produce enough /// debuginfo to have a measurable compile-time impact on debug builds. /// @@ -2659,33 +2672,12 @@ pub(crate) fn is_valid_allocation_size(size: usize, len: usize) -> bool { len <= max_len } -pub(crate) fn is_nonoverlapping_mono( - src: *const (), - dst: *const (), - size: usize, - count: usize, -) -> bool { - let src_usize = src.addr(); - let dst_usize = dst.addr(); - let Some(size) = size.checked_mul(count) else { - crate::panicking::panic_nounwind( - "is_nonoverlapping: `size_of::() * count` overflows a usize", - ) - }; - let diff = src_usize.abs_diff(dst_usize); - // If the absolute distance between the ptrs is at least as big as the size of the buffer, - // they do not overlap. - diff >= size -} - /// Checks whether the regions of memory starting at `src` and `dst` of size -/// `count * size_of::()` do *not* overlap. -#[inline] -pub(crate) fn is_nonoverlapping(src: *const T, dst: *const T, count: usize) -> bool { +/// `count * size` do *not* overlap. +pub(crate) fn is_nonoverlapping(src: *const (), dst: *const (), size: usize, count: usize) -> bool { let src_usize = src.addr(); let dst_usize = dst.addr(); - let Some(size) = mem::size_of::().checked_mul(count) else { - // Use panic_nounwind instead of Option::expect, so that this function is nounwind. + let Some(size) = size.checked_mul(count) else { crate::panicking::panic_nounwind( "is_nonoverlapping: `size_of::() * count` overflows a usize", ) @@ -2809,7 +2801,7 @@ pub const unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: us ) => is_aligned_and_not_null(src, align) && is_aligned_and_not_null(dst, align) - && is_nonoverlapping_mono(src, dst, size, count) + && is_nonoverlapping(src, dst, size, count) ); copy_nonoverlapping(src, dst, count) } diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 85595b059ad9a..eb3f93a6e9657 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1660,6 +1660,11 @@ mod prim_ref {} /// * [`UnwindSafe`] /// * [`RefUnwindSafe`] /// +/// Note that while this type implements `PartialEq`, comparing function pointers is unreliable: +/// pointers to the same function can compare inequal (because functions are duplicated in multiple +/// codegen units), and pointers to *different* functions can compare equal (since identical +/// functions can be deduplicated within a codegen unit). +/// /// [`Hash`]: hash::Hash /// [`Pointer`]: fmt::Pointer /// [`UnwindSafe`]: panic::UnwindSafe diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index a6a390db043b6..c7b0fe5694a75 100644 --- a/library/core/src/ptr/metadata.rs +++ b/library/core/src/ptr/metadata.rs @@ -175,6 +175,11 @@ impl Clone for PtrComponents { /// /// It is possible to name this struct with a type parameter that is not a `dyn` trait object /// (for example `DynMetadata`) but not to obtain a meaningful value of that struct. +/// +/// Note that while this type implements `PartialEq`, comparing vtable pointers is unreliable: +/// pointers to vtables of the same type for the same trait can compare inequal (because vtables are +/// duplicated in multiple codegen units), and pointers to vtables of *different* types/traits can +/// compare equal (since identical vtables can be deduplicated within a codegen unit). #[lang = "dyn_metadata"] pub struct DynMetadata { vtable_ptr: &'static VTable, diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 1c2c9901e52eb..2bd14f357d80c 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -383,7 +383,7 @@ use crate::cmp::Ordering; use crate::fmt; use crate::hash; use crate::intrinsics::{ - self, assert_unsafe_precondition, is_aligned_and_not_null, is_nonoverlapping_mono, + self, assert_unsafe_precondition, is_aligned_and_not_null, is_nonoverlapping, }; use crate::marker::FnPtr; @@ -978,7 +978,7 @@ pub const unsafe fn swap_nonoverlapping(x: *mut T, y: *mut T, count: usize) { ) => is_aligned_and_not_null(x, align) && is_aligned_and_not_null(y, align) - && is_nonoverlapping_mono(x, y, size, count) + && is_nonoverlapping(x, y, size, count) ); } diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 9ad71e394eacf..09f3f2f02eab1 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -99,6 +99,12 @@ impl RawWaker { /// [`RawWaker`] implementation. Calling one of the contained functions using /// any other `data` pointer will cause undefined behavior. /// +/// Note that while this type implements `PartialEq`, comparing function pointers, and hence +/// comparing structs like this that contain function pointers, is unreliable: pointers to the same +/// function can compare inequal (because functions are duplicated in multiple codegen units), and +/// pointers to *different* functions can compare equal (since identical functions can be +/// deduplicated within a codegen unit). +/// /// # Thread safety /// If the [`RawWaker`] will be used to construct a [`Waker`] then /// these functions must all be thread-safe (even though [`RawWaker`] is diff --git a/library/std/src/sys/cmath.rs b/library/std/src/sys/cmath.rs new file mode 100644 index 0000000000000..99df503b82de2 --- /dev/null +++ b/library/std/src/sys/cmath.rs @@ -0,0 +1,88 @@ +#![cfg(not(test))] + +// These symbols are all defined by `libm`, +// or by `compiler-builtins` on unsupported platforms. +extern "C" { + pub fn acos(n: f64) -> f64; + pub fn asin(n: f64) -> f64; + pub fn atan(n: f64) -> f64; + pub fn atan2(a: f64, b: f64) -> f64; + pub fn cbrt(n: f64) -> f64; + pub fn cbrtf(n: f32) -> f32; + pub fn cosh(n: f64) -> f64; + pub fn expm1(n: f64) -> f64; + pub fn expm1f(n: f32) -> f32; + pub fn fdim(a: f64, b: f64) -> f64; + pub fn fdimf(a: f32, b: f32) -> f32; + #[cfg_attr(target_env = "msvc", link_name = "_hypot")] + pub fn hypot(x: f64, y: f64) -> f64; + #[cfg_attr(target_env = "msvc", link_name = "_hypotf")] + pub fn hypotf(x: f32, y: f32) -> f32; + pub fn log1p(n: f64) -> f64; + pub fn log1pf(n: f32) -> f32; + pub fn sinh(n: f64) -> f64; + pub fn tan(n: f64) -> f64; + pub fn tanh(n: f64) -> f64; + pub fn tgamma(n: f64) -> f64; + pub fn tgammaf(n: f32) -> f32; + pub fn lgamma_r(n: f64, s: &mut i32) -> f64; + pub fn lgammaf_r(n: f32, s: &mut i32) -> f32; + + cfg_if::cfg_if! { + if #[cfg(not(all(target_os = "windows", target_env = "msvc", target_arch = "x86")))] { + pub fn acosf(n: f32) -> f32; + pub fn asinf(n: f32) -> f32; + pub fn atan2f(a: f32, b: f32) -> f32; + pub fn atanf(n: f32) -> f32; + pub fn coshf(n: f32) -> f32; + pub fn sinhf(n: f32) -> f32; + pub fn tanf(n: f32) -> f32; + pub fn tanhf(n: f32) -> f32; + }} +} + +// On 32-bit x86 MSVC these functions aren't defined, so we just define shims +// which promote everything to f64, perform the calculation, and then demote +// back to f32. While not precisely correct should be "correct enough" for now. +cfg_if::cfg_if! { +if #[cfg(all(target_os = "windows", target_env = "msvc", target_arch = "x86"))] { + #[inline] + pub unsafe fn acosf(n: f32) -> f32 { + f64::acos(n as f64) as f32 + } + + #[inline] + pub unsafe fn asinf(n: f32) -> f32 { + f64::asin(n as f64) as f32 + } + + #[inline] + pub unsafe fn atan2f(n: f32, b: f32) -> f32 { + f64::atan2(n as f64, b as f64) as f32 + } + + #[inline] + pub unsafe fn atanf(n: f32) -> f32 { + f64::atan(n as f64) as f32 + } + + #[inline] + pub unsafe fn coshf(n: f32) -> f32 { + f64::cosh(n as f64) as f32 + } + + #[inline] + pub unsafe fn sinhf(n: f32) -> f32 { + f64::sinh(n as f64) as f32 + } + + #[inline] + pub unsafe fn tanf(n: f32) -> f32 { + f64::tan(n as f64) as f32 + } + + #[inline] + pub unsafe fn tanhf(n: f32) -> f32 { + f64::tanh(n as f64) as f32 + } +}} diff --git a/library/std/src/sys/cmath/builtins.rs b/library/std/src/sys/cmath/builtins.rs deleted file mode 100644 index c680132efa4ba..0000000000000 --- a/library/std/src/sys/cmath/builtins.rs +++ /dev/null @@ -1,35 +0,0 @@ -// These symbols are all defined by `libm`, -// or by `compiler-builtins` on unsupported platforms. - -extern "C" { - pub fn acos(n: f64) -> f64; - pub fn acosf(n: f32) -> f32; - pub fn asin(n: f64) -> f64; - pub fn asinf(n: f32) -> f32; - pub fn atan(n: f64) -> f64; - pub fn atan2(a: f64, b: f64) -> f64; - pub fn atan2f(a: f32, b: f32) -> f32; - pub fn atanf(n: f32) -> f32; - pub fn cbrt(n: f64) -> f64; - pub fn cbrtf(n: f32) -> f32; - pub fn cosh(n: f64) -> f64; - pub fn coshf(n: f32) -> f32; - pub fn expm1(n: f64) -> f64; - pub fn expm1f(n: f32) -> f32; - pub fn fdim(a: f64, b: f64) -> f64; - pub fn fdimf(a: f32, b: f32) -> f32; - pub fn hypot(x: f64, y: f64) -> f64; - pub fn hypotf(x: f32, y: f32) -> f32; - pub fn log1p(n: f64) -> f64; - pub fn log1pf(n: f32) -> f32; - pub fn sinh(n: f64) -> f64; - pub fn sinhf(n: f32) -> f32; - pub fn tan(n: f64) -> f64; - pub fn tanf(n: f32) -> f32; - pub fn tanh(n: f64) -> f64; - pub fn tanhf(n: f32) -> f32; - pub fn tgamma(n: f64) -> f64; - pub fn tgammaf(n: f32) -> f32; - pub fn lgamma_r(n: f64, s: &mut i32) -> f64; - pub fn lgammaf_r(n: f32, s: &mut i32) -> f32; -} diff --git a/library/std/src/sys/cmath/mod.rs b/library/std/src/sys/cmath/mod.rs deleted file mode 100644 index 79d5021dd8dc3..0000000000000 --- a/library/std/src/sys/cmath/mod.rs +++ /dev/null @@ -1,11 +0,0 @@ -#![cfg(not(test))] - -cfg_if::cfg_if! { - if #[cfg(target_os = "windows")] { - mod windows; - pub use windows::*; - } else { - mod builtins; - pub use builtins::*; - } -} diff --git a/library/std/src/sys/cmath/windows.rs b/library/std/src/sys/cmath/windows.rs deleted file mode 100644 index 712097f06ff30..0000000000000 --- a/library/std/src/sys/cmath/windows.rs +++ /dev/null @@ -1,94 +0,0 @@ -use core::ffi::{c_double, c_float, c_int}; - -extern "C" { - pub fn acos(n: c_double) -> c_double; - pub fn asin(n: c_double) -> c_double; - pub fn atan(n: c_double) -> c_double; - pub fn atan2(a: c_double, b: c_double) -> c_double; - pub fn cbrt(n: c_double) -> c_double; - pub fn cbrtf(n: c_float) -> c_float; - pub fn cosh(n: c_double) -> c_double; - pub fn expm1(n: c_double) -> c_double; - pub fn expm1f(n: c_float) -> c_float; - pub fn fdim(a: c_double, b: c_double) -> c_double; - pub fn fdimf(a: c_float, b: c_float) -> c_float; - #[cfg_attr(target_env = "msvc", link_name = "_hypot")] - pub fn hypot(x: c_double, y: c_double) -> c_double; - #[cfg_attr(target_env = "msvc", link_name = "_hypotf")] - pub fn hypotf(x: c_float, y: c_float) -> c_float; - pub fn log1p(n: c_double) -> c_double; - pub fn log1pf(n: c_float) -> c_float; - pub fn sinh(n: c_double) -> c_double; - pub fn tan(n: c_double) -> c_double; - pub fn tanh(n: c_double) -> c_double; - pub fn tgamma(n: c_double) -> c_double; - pub fn tgammaf(n: c_float) -> c_float; - pub fn lgamma_r(n: c_double, s: &mut c_int) -> c_double; - pub fn lgammaf_r(n: c_float, s: &mut c_int) -> c_float; -} - -pub use self::shims::*; - -#[cfg(not(all(target_env = "msvc", target_arch = "x86")))] -mod shims { - use core::ffi::c_float; - - extern "C" { - pub fn acosf(n: c_float) -> c_float; - pub fn asinf(n: c_float) -> c_float; - pub fn atan2f(a: c_float, b: c_float) -> c_float; - pub fn atanf(n: c_float) -> c_float; - pub fn coshf(n: c_float) -> c_float; - pub fn sinhf(n: c_float) -> c_float; - pub fn tanf(n: c_float) -> c_float; - pub fn tanhf(n: c_float) -> c_float; - } -} - -// On 32-bit x86 MSVC these functions aren't defined, so we just define shims -// which promote everything to f64, perform the calculation, and then demote -// back to f32. While not precisely correct should be "correct enough" for now. -#[cfg(all(target_env = "msvc", target_arch = "x86"))] -mod shims { - use core::ffi::c_float; - - #[inline] - pub unsafe fn acosf(n: c_float) -> c_float { - f64::acos(n as f64) as c_float - } - - #[inline] - pub unsafe fn asinf(n: c_float) -> c_float { - f64::asin(n as f64) as c_float - } - - #[inline] - pub unsafe fn atan2f(n: c_float, b: c_float) -> c_float { - f64::atan2(n as f64, b as f64) as c_float - } - - #[inline] - pub unsafe fn atanf(n: c_float) -> c_float { - f64::atan(n as f64) as c_float - } - - #[inline] - pub unsafe fn coshf(n: c_float) -> c_float { - f64::cosh(n as f64) as c_float - } - - #[inline] - pub unsafe fn sinhf(n: c_float) -> c_float { - f64::sinh(n as f64) as c_float - } - - #[inline] - pub unsafe fn tanf(n: c_float) -> c_float { - f64::tan(n as f64) as c_float - } - - #[inline] - pub unsafe fn tanhf(n: c_float) -> c_float { - f64::tanh(n as f64) as c_float - } -} diff --git a/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md b/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md index 2ce0ccb78769c..540e5a4af938e 100644 --- a/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md +++ b/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md @@ -10,6 +10,9 @@ from nor used with any official Nintendo SDK. ## Target maintainers +This target is maintained by members of the [@rust3ds](https://github.com/rust3ds) +organization: + - [@Meziu](https://github.com/Meziu) - [@AzureMarker](https://github.com/AzureMarker) - [@ian-h-chamberlain](https://github.com/ian-h-chamberlain) @@ -35,8 +38,8 @@ Additionally, some helper crates provide implementations of some `libc` function use by `std` that may otherwise be missing. These, or an alternate implementation of the relevant functions, are required to use `std`: -- [`pthread-3ds`](https://github.com/Meziu/pthread-3ds) provides pthread APIs for `std::thread`. -- [`linker-fix-3ds`](https://github.com/Meziu/rust-linker-fix-3ds) fulfills some other missing libc APIs. +- [`pthread-3ds`](https://github.com/rust3ds/pthread-3ds) provides pthread APIs for `std::thread`. +- [`shim-3ds`](https://github.com/rust3ds/shim-3ds) fulfills some other missing libc APIs (e.g. `getrandom`). Binaries built for this target should be compatible with all variants of the 3DS (and 2DS) hardware and firmware, but testing is limited and some versions may @@ -74,8 +77,10 @@ export CFLAGS_armv6k_nintendo_3ds="-mfloat-abi=hard -mtune=mpcore -mtp=soft -mar Rust does not yet ship pre-compiled artifacts for this target. The recommended way to build binaries is by using the -[cargo-3ds](https://github.com/Meziu/cargo-3ds) tool, which uses `build-std` +[cargo-3ds](https://github.com/rust3ds/cargo-3ds) tool, which uses `build-std` and provides commands that work like the usual `cargo run`, `cargo build`, etc. +The `cargo 3ds new` will automatically set up a new project with the dependencies +needed to build a simple binary. You can also build Rust with the target enabled (see [Building the target](#building-the-target) above). @@ -83,23 +88,16 @@ You can also build Rust with the target enabled (see As mentioned in [Requirements](#requirements), programs that use `std` must link against both the devkitARM toolchain and libraries providing the `libc` APIs used in `std`. There is a general-purpose utility crate for working with nonstandard -APIs provided by the OS: [`ctru-rs`](https://github.com/Meziu/ctru-rs). +APIs provided by the OS: [`ctru-rs`](https://github.com/rust3ds/ctru-rs). Add it to Cargo.toml to use it in your program: ```toml [dependencies] -ctru-rs = { git = "https://github.com/Meziu/ctru-rs.git" } +ctru-rs = { git = "https://github.com/rust3ds/ctru-rs.git" } ``` -Using this library's `init()` function ensures the symbols needed to link -against `std` are present (as mentioned in [Requirements](#requirements) -above), as well as providing a runtime suitable for `std`: - -```rust,ignore (requires-3rd-party-library) -fn main() { - ctru::init(); -} -``` +Depending on `ctru-rs` ensures that all the necessary symbols are available at +link time. ## Testing diff --git a/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs b/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs index 1e327f7a6dfb8..9365fbfaed088 100644 --- a/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs +++ b/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs @@ -46,11 +46,10 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnConstants { return; }; if let ConstantSource::Constant = source - && let Some(node) = cx.tcx.hir().find_parent(e.hir_id) && let Node::Item(Item { kind: ItemKind::Const(..), .. - }) = node + }) = cx.tcx.parent_hir_node(e.hir_id) { return; } diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs b/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs index 0f29743856ac9..a31943f002180 100644 --- a/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs +++ b/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs @@ -67,25 +67,20 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: &Msrv } fn is_child_of_cast(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - let map = cx.tcx.hir(); - if let Some(parent_id) = map.opt_parent_id(expr.hir_id) { - let parent = cx.tcx.hir_node(parent_id); - let expr = match parent { - Node::Block(block) => { - if let Some(parent_expr) = block.expr { - parent_expr - } else { - return false; - } - }, - Node::Expr(expr) => expr, - _ => return false, - }; + let parent = cx.tcx.parent_hir_node(expr.hir_id); + let expr = match parent { + Node::Block(block) => { + if let Some(parent_expr) = block.expr { + parent_expr + } else { + return false; + } + }, + Node::Expr(expr) => expr, + _ => return false, + }; - matches!(expr.kind, ExprKind::Cast(..)) - } else { - false - } + matches!(expr.kind, ExprKind::Cast(..)) } /// Returns the type T of the pointed to *const [T] or *mut [T] and the mutability of the slice if diff --git a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs index 81d0def4322d3..b4a23d0d4db41 100644 --- a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs +++ b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs @@ -65,7 +65,7 @@ pub(super) fn check<'tcx>( && let ExprKind::Path(qpath) = inner.kind && let QPath::Resolved(None, Path { res, .. }) = qpath && let Res::Local(hir_id) = res - && let parent = cx.tcx.hir().get_parent(*hir_id) + && let parent = cx.tcx.parent_hir_node(*hir_id) && let Node::Local(local) = parent { if let Some(ty) = local.ty diff --git a/src/tools/clippy/clippy_lints/src/dbg_macro.rs b/src/tools/clippy/clippy_lints/src/dbg_macro.rs index 9424a9103db83..ec66556cebffa 100644 --- a/src/tools/clippy/clippy_lints/src/dbg_macro.rs +++ b/src/tools/clippy/clippy_lints/src/dbg_macro.rs @@ -63,7 +63,7 @@ impl LateLintPass<'_> for DbgMacro { ExprKind::Block(..) => { // If the `dbg!` macro is a "free" statement and not contained within other expressions, // remove the whole statement. - if let Some(Node::Stmt(_)) = cx.tcx.hir().find_parent(expr.hir_id) + if let Node::Stmt(_) = cx.tcx.parent_hir_node(expr.hir_id) && let Some(semi_span) = cx.sess().source_map().mac_call_stmt_semi_span(macro_call.span) { (macro_call.span.to(semi_span), String::new()) diff --git a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs index c4437a3c4b339..59d2df0295fb4 100644 --- a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs +++ b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs @@ -128,8 +128,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> { }, _, ) => { - if let Some(parent) = self.cx.tcx.hir().find_parent(expr.hir_id) - && let Some(fn_sig) = parent.fn_sig() + if let Some(fn_sig) = self.cx.tcx.parent_hir_node(expr.hir_id).fn_sig() && let FnRetTy::Return(_ty) = fn_sig.decl.output { // We cannot check the exact type since it's a `hir::Ty`` which does not implement `is_numeric` diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index 194cf69ea7ed0..cdbb52f497b36 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -1088,7 +1088,7 @@ fn report<'tcx>( // // e.g. `&mut x.y.z` where `x` is a union, and accessing `z` requires a // deref through `ManuallyDrop<_>` will not compile. - let parent_id = cx.tcx.hir().parent_id(expr.hir_id); + let parent_id = cx.tcx.parent_hir_id(expr.hir_id); if parent_id == data.first_expr.hir_id { return; } diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index 218d7c6c01ae1..064bac2e7dc74 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -131,7 +131,7 @@ fn is_argument(tcx: TyCtxt<'_>, id: HirId) -> bool { _ => return false, } - matches!(tcx.hir().find_parent(id), Some(Node::Param(_))) + matches!(tcx.parent_hir_node(id), Node::Param(_)) } impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { @@ -156,8 +156,8 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { let map = &self.cx.tcx.hir(); if is_argument(self.cx.tcx, cmt.hir_id) { // Skip closure arguments - let parent_id = map.parent_id(cmt.hir_id); - if let Some(Node::Expr(..)) = map.find_parent(parent_id) { + let parent_id = self.cx.tcx.parent_hir_id(cmt.hir_id); + if let Node::Expr(..) = self.cx.tcx.parent_hir_node(parent_id) { return; } diff --git a/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs b/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs index 8fba41c0e24d5..6fb38a0d6dd84 100644 --- a/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs +++ b/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs @@ -53,7 +53,7 @@ pub(super) fn check_fn<'tcx>(cx: &LateContext<'_>, kind: &'tcx FnKind<'_>, body: pub(super) fn check_impl_item(cx: &LateContext<'_>, impl_item: &ImplItem<'_>) { if let ImplItemKind::Fn(_, body_id) = impl_item.kind - && let hir::Node::Item(item) = cx.tcx.hir().get_parent(impl_item.hir_id()) + && let hir::Node::Item(item) = cx.tcx.parent_hir_node(impl_item.hir_id()) && let hir::ItemKind::Impl(impl_) = item.kind && let hir::Impl { of_trait, .. } = *impl_ && of_trait.is_none() @@ -72,7 +72,7 @@ pub(super) fn check_impl_item(cx: &LateContext<'_>, impl_item: &ImplItem<'_>) { pub(super) fn check_trait_item(cx: &LateContext<'_>, trait_item: &TraitItem<'_>, avoid_breaking_exported_api: bool) { if !avoid_breaking_exported_api && let TraitItemKind::Fn(_, _) = trait_item.kind - && let hir::Node::Item(item) = cx.tcx.hir().get_parent(trait_item.hir_id()) + && let hir::Node::Item(item) = cx.tcx.parent_hir_node(trait_item.hir_id()) // ^^ (Will always be a trait) && !item.vis_span.is_empty() // Is public && !is_in_test_function(cx.tcx, trait_item.hir_id()) diff --git a/src/tools/clippy/clippy_lints/src/ignored_unit_patterns.rs b/src/tools/clippy/clippy_lints/src/ignored_unit_patterns.rs index 0a2fd0c663e54..80a537b9f9413 100644 --- a/src/tools/clippy/clippy_lints/src/ignored_unit_patterns.rs +++ b/src/tools/clippy/clippy_lints/src/ignored_unit_patterns.rs @@ -41,8 +41,8 @@ impl<'tcx> LateLintPass<'tcx> for IgnoredUnitPatterns { return; } - match cx.tcx.hir().get_parent(pat.hir_id) { - Node::Param(param) if matches!(cx.tcx.hir().get_parent(param.hir_id), Node::Item(_)) => { + match cx.tcx.parent_hir_node(pat.hir_id) { + Node::Param(param) if matches!(cx.tcx.parent_hir_node(param.hir_id), Node::Item(_)) => { // Ignore function parameters return; }, diff --git a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs index 252be30c4e27d..51b4f26b6d131 100644 --- a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs +++ b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs @@ -242,12 +242,8 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> { } = *self; if let Some(use_info) = slice_lint_info.get_mut(&local_id) - // Check if this is even a local we're interested in - - && let map = cx.tcx.hir() - // Checking for slice indexing - && let parent_id = map.parent_id(expr.hir_id) + && let parent_id = cx.tcx.parent_hir_id(expr.hir_id) && let hir::Node::Expr(parent_expr) = cx.tcx.hir_node(parent_id) && let hir::ExprKind::Index(_, index_expr, _) = parent_expr.kind && let Some(Constant::Int(index_value)) = constant(cx, cx.typeck_results(), index_expr) @@ -255,11 +251,10 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> { && index_value < max_suggested_slice // Make sure that this slice index is read only - && let maybe_addrof_id = map.parent_id(parent_id) - && let hir::Node::Expr(maybe_addrof_expr) = cx.tcx.hir_node(maybe_addrof_id) + && let hir::Node::Expr(maybe_addrof_expr) = cx.tcx.parent_hir_node(parent_id) && let hir::ExprKind::AddrOf(_kind, hir::Mutability::Not, _inner_expr) = maybe_addrof_expr.kind { - use_info.index_use.push((index_value, map.span(parent_expr.hir_id))); + use_info.index_use.push((index_value, cx.tcx.hir().span(parent_expr.hir_id))); return; } diff --git a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs index 82a37bb4f278a..b5821d909f849 100644 --- a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs +++ b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs @@ -269,7 +269,7 @@ impl {self_ty_without_ref} {{ // } let span_behind_impl = cx .tcx - .def_span(cx.tcx.hir().parent_id(item.hir_id()).owner.def_id) + .def_span(cx.tcx.parent_hir_id(item.hir_id()).owner.def_id) .shrink_to_lo(); let sugg = format!( diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs index f5636945f2037..2b73663d229ea 100644 --- a/src/tools/clippy/clippy_lints/src/lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs @@ -285,7 +285,7 @@ fn elision_suggestions( .iter() .filter(|usage| named_lifetime(usage).map_or(false, |id| elidable_lts.contains(&id))) .map(|usage| { - match cx.tcx.hir().get_parent(usage.hir_id) { + match cx.tcx.parent_hir_node(usage.hir_id) { Node::Ty(Ty { kind: TyKind::Ref(..), .. }) => { diff --git a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs index 5f015db2b33bf..0f35514b8ad66 100644 --- a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs +++ b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs @@ -62,8 +62,7 @@ pub(super) fn check<'tcx>( if let Node::Pat(pat) = node && let PatKind::Binding(bind_ann, ..) = pat.kind && !matches!(bind_ann, BindingAnnotation(_, Mutability::Mut)) - && let parent_node = cx.tcx.hir().parent_id(hir_id) - && let Node::Local(parent_let_expr) = cx.tcx.hir_node(parent_node) + && let Node::Local(parent_let_expr) = cx.tcx.parent_hir_node(hir_id) && let Some(init) = parent_let_expr.init { match init.kind { diff --git a/src/tools/clippy/clippy_lints/src/manual_hash_one.rs b/src/tools/clippy/clippy_lints/src/manual_hash_one.rs index 73687fbbe54e1..5cbab0ec977c1 100644 --- a/src/tools/clippy/clippy_lints/src/manual_hash_one.rs +++ b/src/tools/clippy/clippy_lints/src/manual_hash_one.rs @@ -68,8 +68,8 @@ impl LateLintPass<'_> for ManualHashOne { && let ExprKind::MethodCall(seg, build_hasher, [], _) = init.kind && seg.ident.name == sym!(build_hasher) - && let Node::Stmt(local_stmt) = cx.tcx.hir().get_parent(local.hir_id) - && let Node::Block(block) = cx.tcx.hir().get_parent(local_stmt.hir_id) + && let Node::Stmt(local_stmt) = cx.tcx.parent_hir_node(local.hir_id) + && let Node::Block(block) = cx.tcx.parent_hir_node(local_stmt.hir_id) && let mut stmts = block.stmts.iter() .skip_while(|stmt| stmt.hir_id != local_stmt.hir_id) @@ -91,7 +91,7 @@ impl LateLintPass<'_> for ManualHashOne { // `hasher.finish()`, may be anywhere in a statement or the trailing expr of the block && let Some(path_expr) = local_used_once(cx, (maybe_finish_stmt, block.expr), hasher) - && let Node::Expr(finish_expr) = cx.tcx.hir().get_parent(path_expr.hir_id) + && let Node::Expr(finish_expr) = cx.tcx.parent_hir_node(path_expr.hir_id) && !finish_expr.span.from_expansion() && let ExprKind::MethodCall(seg, _, [], _) = finish_expr.kind && seg.ident.name == sym!(finish) diff --git a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs index e1768c6d97641..0bde62bd55490 100644 --- a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs +++ b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs @@ -79,9 +79,9 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid { && let Node::Pat(_) = cx.tcx.hir_node(hir_id) { // Apply only to params or locals with annotated types - match cx.tcx.hir().find_parent(hir_id) { - Some(Node::Param(..)) => (), - Some(Node::Local(local)) => { + match cx.tcx.parent_hir_node(hir_id) { + Node::Param(..) => (), + Node::Local(local) => { let Some(ty) = local.ty else { return }; if matches!(ty.kind, TyKind::Infer) { return; diff --git a/src/tools/clippy/clippy_lints/src/matches/match_single_binding.rs b/src/tools/clippy/clippy_lints/src/matches/match_single_binding.rs index 89da7a55cbd5f..61977045fd460 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_single_binding.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_single_binding.rs @@ -36,7 +36,7 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e .to_string(); // Do we need to add ';' to suggestion ? - if let Node::Stmt(stmt) = cx.tcx.hir().get_parent(expr.hir_id) + if let Node::Stmt(stmt) = cx.tcx.parent_hir_node(expr.hir_id) && let StmtKind::Expr(_) = stmt.kind && match match_body.kind { // We don't need to add a ; to blocks, unless that block is from a macro expansion @@ -146,18 +146,16 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e /// Returns true if the `ex` match expression is in a local (`let`) or assign expression fn opt_parent_assign_span<'a>(cx: &LateContext<'a>, ex: &Expr<'a>) -> Option { - let map = &cx.tcx.hir(); - - if let Some(Node::Expr(parent_arm_expr)) = map.find_parent(ex.hir_id) { - return match map.find_parent(parent_arm_expr.hir_id) { - Some(Node::Local(parent_let_expr)) => Some(AssignmentExpr::Local { + if let Node::Expr(parent_arm_expr) = cx.tcx.parent_hir_node(ex.hir_id) { + return match cx.tcx.parent_hir_node(parent_arm_expr.hir_id) { + Node::Local(parent_let_expr) => Some(AssignmentExpr::Local { span: parent_let_expr.span, pat_span: parent_let_expr.pat.span(), }), - Some(Node::Expr(Expr { + Node::Expr(Expr { kind: ExprKind::Assign(parent_assign_expr, match_expr, _), .. - })) => Some(AssignmentExpr::Assign { + }) => Some(AssignmentExpr::Assign { span: parent_assign_expr.span, match_span: match_expr.span, }), @@ -191,7 +189,7 @@ fn sugg_with_curlies<'a>( // If the parent is already an arm, and the body is another match statement, // we need curly braces around suggestion - if let Node::Arm(arm) = &cx.tcx.hir().get_parent(match_expr.hir_id) { + if let Node::Arm(arm) = &cx.tcx.parent_hir_node(match_expr.hir_id) { if let ExprKind::Match(..) = arm.body.kind { cbrace_end = format!("\n{indent}}}"); // Fix body indent due to the match diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs index dfaaeb14ca3cb..a1b82679f2e2a 100644 --- a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs +++ b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs @@ -199,7 +199,7 @@ fn get_pat_binding<'tcx>( return span.map(|span| PatBindingInfo { span, byref_ident, - is_field: matches!(cx.tcx.hir().get_parent(local), Node::PatField(_)), + is_field: matches!(cx.tcx.parent_hir_node(local), Node::PatField(_)), }); } } diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index e8a7a321bf4b7..1452547807ba2 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -4458,7 +4458,7 @@ impl Methods { _ => {}, }, ("drain", ..) => { - if let Node::Stmt(Stmt { hir_id: _, kind, .. }) = cx.tcx.hir().get_parent(expr.hir_id) + if let Node::Stmt(Stmt { hir_id: _, kind, .. }) = cx.tcx.parent_hir_node(expr.hir_id) && matches!(kind, StmtKind::Semi(_)) && args.len() <= 1 { diff --git a/src/tools/clippy/clippy_lints/src/methods/readonly_write_lock.rs b/src/tools/clippy/clippy_lints/src/methods/readonly_write_lock.rs index 1184dd4525a73..6c6846c4b476c 100644 --- a/src/tools/clippy/clippy_lints/src/methods/readonly_write_lock.rs +++ b/src/tools/clippy/clippy_lints/src/methods/readonly_write_lock.rs @@ -21,9 +21,9 @@ fn is_unwrap_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, receiver: &Expr<'_>) { if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(receiver).peel_refs(), sym::RwLock) - && let Node::Expr(unwrap_call_expr) = cx.tcx.hir().get_parent(expr.hir_id) + && let Node::Expr(unwrap_call_expr) = cx.tcx.parent_hir_node(expr.hir_id) && is_unwrap_call(cx, unwrap_call_expr) - && let parent = cx.tcx.hir().get_parent(unwrap_call_expr.hir_id) + && let parent = cx.tcx.parent_hir_node(unwrap_call_expr.hir_id) && let Node::Local(local) = parent && let Some(mir) = enclosing_mir(cx.tcx, expr.hir_id) && let Some((local, _)) = mir diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs index 2046692bbd0bd..988f3e86fcf08 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs @@ -16,7 +16,7 @@ use super::UNNECESSARY_FOLD; /// Changing `fold` to `sum` needs it sometimes when the return type can't be /// inferred. This checks for some common cases where it can be safely omitted fn needs_turbofish(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { - let parent = cx.tcx.hir().get_parent(expr.hir_id); + let parent = cx.tcx.parent_hir_node(expr.hir_id); // some common cases where turbofish isn't needed: // - assigned to a local variable with a type annotation diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs index a1125d70db39a..1b2bfbf4090ec 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs @@ -76,7 +76,7 @@ pub(super) fn check( (expr.span.with_lo(call_args[0].span.hi()), String::new()), ]; // try to also remove the unsafe block if present - if let hir::Node::Block(block) = cx.tcx.hir().get_parent(expr.hir_id) + if let hir::Node::Block(block) = cx.tcx.parent_hir_node(expr.hir_id) && let hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::UserProvided) = block.rules { suggs.extend([ diff --git a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs index b593e48ae2e16..a1f7dc7b38c40 100644 --- a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs +++ b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs @@ -206,10 +206,9 @@ impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> { /// /// When such a read is found, the lint is triggered. fn check_for_unsequenced_reads(vis: &mut ReadVisitor<'_, '_>) { - let map = &vis.cx.tcx.hir(); let mut cur_id = vis.write_expr.hir_id; loop { - let parent_id = map.parent_id(cur_id); + let parent_id = vis.cx.tcx.parent_hir_id(cur_id); if parent_id == cur_id { break; } diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs index d2eef6ae4338e..149d440ecac49 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -161,7 +161,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { }; // Exclude non-inherent impls - if let Some(Node::Item(item)) = cx.tcx.hir().find_parent(hir_id) { + if let Node::Item(item) = cx.tcx.parent_hir_node(hir_id) { if matches!( item.kind, ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..) diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 2c5c3dcaa7528..384a402ce5b01 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -100,7 +100,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { } // Exclude non-inherent impls - if let Some(Node::Item(item)) = cx.tcx.hir().find_parent(hir_id) { + if let Node::Item(item) = cx.tcx.parent_hir_node(hir_id) { if matches!( item.kind, ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..) diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 10ab380ba1bc5..ea73d9afa2ea0 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -449,7 +449,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst { let mut dereferenced_expr = expr; let mut needs_check_adjustment = true; loop { - let parent_id = cx.tcx.hir().parent_id(cur_expr.hir_id); + let parent_id = cx.tcx.parent_hir_id(cur_expr.hir_id); if parent_id == cur_expr.hir_id { break; } diff --git a/src/tools/clippy/clippy_lints/src/operators/modulo_arithmetic.rs b/src/tools/clippy/clippy_lints/src/operators/modulo_arithmetic.rs index 40d4a842befb8..2a933a11e12c0 100644 --- a/src/tools/clippy/clippy_lints/src/operators/modulo_arithmetic.rs +++ b/src/tools/clippy/clippy_lints/src/operators/modulo_arithmetic.rs @@ -34,7 +34,7 @@ pub(super) fn check<'tcx>( } fn used_in_comparison_with_zero(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - let Some(Node::Expr(parent_expr)) = cx.tcx.hir().find_parent(expr.hir_id) else { + let Node::Expr(parent_expr) = cx.tcx.parent_hir_node(expr.hir_id) else { return false; }; let ExprKind::Binary(op, lhs, rhs) = parent_expr.kind else { diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs index 57d37067e8f98..ec03ab0e41ab7 100644 --- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs +++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs @@ -301,7 +301,7 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue { } // Exclude non-inherent impls - if let Some(Node::Item(item)) = cx.tcx.hir().find_parent(hir_id) { + if let Node::Item(item) = cx.tcx.parent_hir_node(hir_id) { if matches!( item.kind, ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..) diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs index 513a913f56adb..bbecc39a8130c 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs @@ -41,7 +41,7 @@ pub(super) fn check<'tcx>( _ => return false, }; - if let Node::Expr(parent) = cx.tcx.hir().get_parent(e.hir_id) + if let Node::Expr(parent) = cx.tcx.parent_hir_node(e.hir_id) && parent.precedence().order() > ExprPrecedence::Cast.order() { sugg = format!("({sugg})"); diff --git a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs index e1cd82e18d56d..c11504cd2d4f9 100644 --- a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs +++ b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs @@ -153,13 +153,10 @@ fn all_bindings_are_for_conv<'tcx>( let Some(locals) = locals.iter().map(|e| path_to_local(e)).collect::>>() else { return false; }; - let Some(local_parents) = locals + let local_parents = locals .iter() - .map(|&l| cx.tcx.hir().find_parent(l)) - .collect::>>() - else { - return false; - }; + .map(|l| cx.tcx.parent_hir_node(*l)) + .collect::>(); local_parents .iter() diff --git a/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs b/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs index 44cff78a7936d..eba7fa7b993c2 100644 --- a/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs +++ b/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs @@ -19,9 +19,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { if is_questionmark_desugar_marked_call(expr) { return; } - let map = &cx.tcx.hir(); - let opt_parent_node = map.find_parent(expr.hir_id); - if let Some(hir::Node::Expr(parent_expr)) = opt_parent_node + if let hir::Node::Expr(parent_expr) = cx.tcx.parent_hir_node(expr.hir_id) && is_questionmark_desugar_marked_call(parent_expr) { return; @@ -183,8 +181,8 @@ fn fmt_stmts_and_call( let mut stmts_and_call_snippet = stmts_and_call.join(&format!("{}{}", ";\n", " ".repeat(call_expr_indent))); // expr is not in a block statement or result expression position, wrap in a block - let parent_node = cx.tcx.hir().find_parent(call_expr.hir_id); - if !matches!(parent_node, Some(Node::Block(_))) && !matches!(parent_node, Some(Node::Stmt(_))) { + let parent_node = cx.tcx.parent_hir_node(call_expr.hir_id); + if !matches!(parent_node, Node::Block(_)) && !matches!(parent_node, Node::Stmt(_)) { let block_indent = call_expr_indent + 4; stmts_and_call_snippet = reindent_multiline(stmts_and_call_snippet.into(), true, Some(block_indent)).into_owned(); diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs b/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs index f5af540fa1486..c332cf076ae7d 100644 --- a/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs +++ b/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs @@ -116,7 +116,7 @@ impl LateLintPass<'_> for UnnecessaryBoxReturns { fn check_impl_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::ImplItem<'_>) { // Ignore implementations of traits, because the lint should be on the // trait, not on the implementation of it. - let Node::Item(parent) = cx.tcx.hir().get_parent(item.hir_id()) else { + let Node::Item(parent) = cx.tcx.parent_hir_node(item.hir_id()) else { return; }; let ItemKind::Impl(parent) = parent.kind else { return }; diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs index 446160f8e0fdc..9c8b0ae172763 100644 --- a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs +++ b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs @@ -92,7 +92,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps { // Abort if the method is implementing a trait or of it a trait method. let hir_id = cx.tcx.local_def_id_to_hir_id(def_id); - if let Some(Node::Item(item)) = cx.tcx.hir().find_parent(hir_id) { + if let Node::Item(item) = cx.tcx.parent_hir_node(hir_id) { if matches!( item.kind, ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..) diff --git a/src/tools/clippy/clippy_lints/src/unused_async.rs b/src/tools/clippy/clippy_lints/src/unused_async.rs index 1d42375ba8e55..738fba54fa83f 100644 --- a/src/tools/clippy/clippy_lints/src/unused_async.rs +++ b/src/tools/clippy/clippy_lints/src/unused_async.rs @@ -156,7 +156,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAsync { && let Some(local_def_id) = def_id.as_local() && cx.tcx.def_kind(def_id) == DefKind::Fn && cx.tcx.asyncness(def_id).is_async() - && !is_node_func_call(cx.tcx.hir().get_parent(hir_id), path.span) + && !is_node_func_call(cx.tcx.parent_hir_node(hir_id), path.span) { self.async_fns_as_value.insert(local_def_id); } diff --git a/src/tools/clippy/clippy_lints/src/unwrap.rs b/src/tools/clippy/clippy_lints/src/unwrap.rs index ae2ac38cffe1b..f2eb774b5cbfe 100644 --- a/src/tools/clippy/clippy_lints/src/unwrap.rs +++ b/src/tools/clippy/clippy_lints/src/unwrap.rs @@ -208,7 +208,7 @@ struct MutationVisitor<'tcx> { /// (i.e. the `x` in `x.as_mut()`), and that is the reason for why we care about its parent /// expression: that will be where the actual method call is. fn is_option_as_mut_use(tcx: TyCtxt<'_>, expr_id: HirId) -> bool { - if let Node::Expr(mutating_expr) = tcx.hir().get_parent(expr_id) + if let Node::Expr(mutating_expr) = tcx.parent_hir_node(expr_id) && let ExprKind::MethodCall(path, ..) = mutating_expr.kind { path.ident.name.as_str() == "as_mut" diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs index fae1b90ace21c..349e0e3e077a8 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs @@ -1007,9 +1007,9 @@ fn get_parent_local<'hir>(cx: &LateContext<'hir>, expr: &'hir hir::Expr<'hir>) - fn get_parent_local_hir_id<'hir>(cx: &LateContext<'hir>, hir_id: hir::HirId) -> Option<&'hir hir::Local<'hir>> { let map = cx.tcx.hir(); - match map.find_parent(hir_id) { - Some(hir::Node::Local(local)) => Some(local), - Some(hir::Node::Pat(pattern)) => get_parent_local_hir_id(cx, pattern.hir_id), + match cx.tcx.parent_hir_node(hir_id) { + hir::Node::Local(local) => Some(local), + hir::Node::Pat(pattern) => get_parent_local_hir_id(cx, pattern.hir_id), _ => None, } } diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs index 6e449dc980630..38c832931fc68 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs @@ -217,8 +217,7 @@ fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option match cx.qpath_res(qpath, expr.hir_id) { Res::Local(hir_id) => { - let parent_id = cx.tcx.hir().parent_id(hir_id); - if let Node::Local(Local { init: Some(init), .. }) = cx.tcx.hir_node(parent_id) { + if let Node::Local(Local { init: Some(init), .. }) = cx.tcx.parent_hir_node(hir_id) { path_to_matched_type(cx, init) } else { None diff --git a/src/tools/clippy/clippy_lints/src/vec.rs b/src/tools/clippy/clippy_lints/src/vec.rs index 2c33c93412a3d..b3489142558e3 100644 --- a/src/tools/clippy/clippy_lints/src/vec.rs +++ b/src/tools/clippy/clippy_lints/src/vec.rs @@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec { if let Some(vec_args) = higher::VecArgs::hir(cx, expr.peel_borrows()) { // search for `let foo = vec![_]` expressions where all uses of `foo` // adjust to slices or call a method that exist on slices (e.g. len) - if let Node::Local(local) = cx.tcx.hir().get_parent(expr.hir_id) + if let Node::Local(local) = cx.tcx.parent_hir_node(expr.hir_id) // for now ignore locals with type annotations. // this is to avoid compile errors when doing the suggestion here: let _: Vec<_> = vec![..]; && local.ty.is_none() @@ -103,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec { } // if the local pattern has a specified type, do not lint. else if let Some(_) = higher::VecArgs::hir(cx, expr) - && let Node::Local(local) = cx.tcx.hir().get_parent(expr.hir_id) + && let Node::Local(local) = cx.tcx.parent_hir_node(expr.hir_id) && local.ty.is_some() { let span = expr.span.ctxt().outer_expn_data().call_site; diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 6a33e11be465b..67a18caca0e2d 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -182,11 +182,9 @@ pub fn expr_or_init<'a, 'b, 'tcx: 'b>(cx: &LateContext<'tcx>, mut expr: &'a Expr /// Note: If you have an expression that references a binding `x`, use `path_to_local` to get the /// canonical binding `HirId`. pub fn find_binding_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Expr<'tcx>> { - let hir = cx.tcx.hir(); if let Node::Pat(pat) = cx.tcx.hir_node(hir_id) && matches!(pat.kind, PatKind::Binding(BindingAnnotation::NONE, ..)) - && let parent = hir.parent_id(hir_id) - && let Node::Local(local) = cx.tcx.hir_node(parent) + && let Node::Local(local) = cx.tcx.parent_hir_node(hir_id) { return local.init; } @@ -333,7 +331,7 @@ pub fn is_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, diag_item: Symbol) /// Checks if the `def_id` belongs to a function that is part of a trait impl. pub fn is_def_id_trait_method(cx: &LateContext<'_>, def_id: LocalDefId) -> bool { if let Some(hir_id) = cx.tcx.opt_local_def_id_to_hir_id(def_id) - && let Node::Item(item) = cx.tcx.hir().get_parent(hir_id) + && let Node::Item(item) = cx.tcx.parent_hir_node(hir_id) && let ItemKind::Impl(imp) = item.kind { imp.of_trait.is_some() @@ -1311,7 +1309,7 @@ pub fn contains_return<'tcx>(expr: impl Visitable<'tcx>) -> bool { /// Gets the parent node, if any. pub fn get_parent_node(tcx: TyCtxt<'_>, id: HirId) -> Option> { - tcx.hir().find_parent(id) + Some(tcx.parent_hir_node(id)) } /// Gets the parent expression, if any –- this is useful to constrain a lint. @@ -2227,7 +2225,7 @@ pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool { /// } /// ``` pub fn is_trait_impl_item(cx: &LateContext<'_>, hir_id: HirId) -> bool { - if let Some(Node::Item(item)) = cx.tcx.hir().find_parent(hir_id) { + if let Node::Item(item) = cx.tcx.parent_hir_node(hir_id) { matches!(item.kind, ItemKind::Impl(hir::Impl { of_trait: Some(_), .. })) } else { false diff --git a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs index adca2ca1c3efa..7913926928f2a 100644 --- a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs @@ -237,7 +237,7 @@ fn path_segment_certainty( }, // `get_parent` because `hir_id` refers to a `Pat`, and we're interested in the node containing the `Pat`. - Res::Local(hir_id) => match cx.tcx.hir().get_parent(hir_id) { + Res::Local(hir_id) => match cx.tcx.parent_hir_node(hir_id) { // An argument's type is always certain. Node::Param(..) => Certainty::Certain(None), // A local's type is certain if its type annotation is certain or it has an initializer whose diff --git a/tests/ui/async-await/async-closures/auxiliary/foreign.rs b/tests/ui/async-await/async-closures/auxiliary/foreign.rs new file mode 100644 index 0000000000000..e11dfc22213b1 --- /dev/null +++ b/tests/ui/async-await/async-closures/auxiliary/foreign.rs @@ -0,0 +1,7 @@ +// edition:2021 + +#![feature(async_closure)] + +pub fn closure() -> impl async Fn() { + async || { /* Don't really need to do anything here. */ } +} diff --git a/tests/ui/async-await/async-closures/foreign.rs b/tests/ui/async-await/async-closures/foreign.rs new file mode 100644 index 0000000000000..60fea90980102 --- /dev/null +++ b/tests/ui/async-await/async-closures/foreign.rs @@ -0,0 +1,19 @@ +// aux-build:block-on.rs +// aux-build:foreign.rs +// edition:2021 +// build-pass + +#![feature(async_closure)] + +use std::future::Future; + +extern crate block_on; +extern crate foreign; + +struct NoCopy; + +fn main() { + block_on::block_on(async { + foreign::closure()().await; + }); +}