diff options
Diffstat (limited to 'compiler/rustc_borrowck/src')
24 files changed, 382 insertions, 300 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index 30b0a358580..aa968a1e40f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -9,8 +9,8 @@ use rustc_infer::infer::{ }; use rustc_infer::traits::ObligationCause; use rustc_infer::traits::query::{ - CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpNormalizeGoal, - CanonicalTypeOpProvePredicateGoal, + CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpDeeplyNormalizeGoal, + CanonicalTypeOpNormalizeGoal, CanonicalTypeOpProvePredicateGoal, }; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::{ @@ -109,6 +109,14 @@ impl<'tcx, T: Copy + fmt::Display + TypeFoldable<TyCtxt<'tcx>> + 'tcx> ToUnivers } } +impl<'tcx, T: Copy + fmt::Display + TypeFoldable<TyCtxt<'tcx>> + 'tcx> ToUniverseInfo<'tcx> + for CanonicalTypeOpDeeplyNormalizeGoal<'tcx, T> +{ + fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { + UniverseInfo::TypeOp(Rc::new(DeeplyNormalizeQuery { canonical_query: self, base_universe })) + } +} + impl<'tcx> ToUniverseInfo<'tcx> for CanonicalTypeOpAscribeUserTypeGoal<'tcx> { fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { UniverseInfo::TypeOp(Rc::new(AscribeUserTypeQuery { canonical_query: self, base_universe })) @@ -285,6 +293,53 @@ where } } +struct DeeplyNormalizeQuery<'tcx, T> { + canonical_query: CanonicalTypeOpDeeplyNormalizeGoal<'tcx, T>, + base_universe: ty::UniverseIndex, +} + +impl<'tcx, T> TypeOpInfo<'tcx> for DeeplyNormalizeQuery<'tcx, T> +where + T: Copy + fmt::Display + TypeFoldable<TyCtxt<'tcx>> + 'tcx, +{ + fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> Diag<'tcx> { + tcx.dcx().create_err(HigherRankedLifetimeError { + cause: Some(HigherRankedErrorCause::CouldNotNormalize { + value: self.canonical_query.canonical.value.value.value.to_string(), + }), + span, + }) + } + + fn base_universe(&self) -> ty::UniverseIndex { + self.base_universe + } + + fn nice_error<'infcx>( + &self, + mbcx: &mut MirBorrowckCtxt<'_, 'infcx, 'tcx>, + cause: ObligationCause<'tcx>, + placeholder_region: ty::Region<'tcx>, + error_region: Option<ty::Region<'tcx>>, + ) -> Option<Diag<'infcx>> { + let (infcx, key, _) = + mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); + let ocx = ObligationCtxt::new(&infcx); + + let (param_env, value) = key.into_parts(); + let _ = ocx.deeply_normalize(&cause, param_env, value.value); + + let diag = try_extract_error_from_fulfill_cx( + &ocx, + mbcx.mir_def_id(), + placeholder_region, + error_region, + )? + .with_dcx(mbcx.dcx()); + Some(diag) + } +} + struct AscribeUserTypeQuery<'tcx> { canonical_query: CanonicalTypeOpAscribeUserTypeGoal<'tcx>, base_universe: ty::UniverseIndex, diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 6269728e67f..f33f2ab58e0 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -8,22 +8,20 @@ use std::ops::ControlFlow; use either::Either; use hir::{ClosureKind, Path}; -use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::codes::*; use rustc_errors::{Applicability, Diag, MultiSpan, struct_span_code_err}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::intravisit::{Map, Visitor, walk_block, walk_expr}; +use rustc_hir::intravisit::{Visitor, walk_block, walk_expr}; use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, LangItem, PatField}; use rustc_middle::bug; use rustc_middle::hir::nested_filter::OnlyBodies; -use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::{ self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory, FakeBorrowKind, FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, MutBorrowKind, - Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, - TerminatorKind, VarBindingForm, VarDebugInfoContents, + Operand, Place, PlaceRef, PlaceTy, ProjectionElem, Rvalue, Statement, StatementKind, + Terminator, TerminatorKind, VarBindingForm, VarDebugInfoContents, }; use rustc_middle::ty::print::PrintTraitRefExt as _; use rustc_middle::ty::{ @@ -348,13 +346,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { expr: Option<&'hir hir::Expr<'hir>>, pat: Option<&'hir hir::Pat<'hir>>, parent_pat: Option<&'hir hir::Pat<'hir>>, - hir: rustc_middle::hir::map::Map<'hir>, + tcx: TyCtxt<'hir>, } impl<'hir> Visitor<'hir> for ExpressionFinder<'hir> { type NestedFilter = OnlyBodies; - fn nested_visit_map(&mut self) -> Self::Map { - self.hir + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.tcx } fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) { @@ -386,8 +384,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { hir::intravisit::walk_pat(self, p); } } - let hir = self.infcx.tcx.hir(); - if let Some(body) = hir.maybe_body_owned_by(self.mir_def_id()) { + let tcx = self.infcx.tcx; + if let Some(body) = tcx.hir_maybe_body_owned_by(self.mir_def_id()) { let expr = body.value; let place = &self.move_data.move_paths[mpi].place; let span = place.as_local().map(|local| self.body.local_decls[local].source_info.span); @@ -396,13 +394,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { expr: None, pat: None, parent_pat: None, - hir, + tcx, }; finder.visit_expr(expr); if let Some(span) = span && let Some(expr) = finder.expr { - for (_, expr) in hir.parent_iter(expr.hir_id) { + for (_, expr) in tcx.hir_parent_iter(expr.hir_id) { if let hir::Node::Expr(expr) = expr { if expr.span.contains(span) { // If the let binding occurs within the same loop, then that @@ -782,9 +780,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // We use the statements were the binding was initialized, and inspect the HIR to look // for the branching codepaths that aren't covered, to point at them. - let map = self.infcx.tcx.hir(); - let body = map.body_owned_by(self.mir_def_id()); - let mut visitor = ConditionVisitor { tcx: self.infcx.tcx, spans, name, errors: vec![] }; + let tcx = self.infcx.tcx; + let body = tcx.hir_body_owned_by(self.mir_def_id()); + let mut visitor = ConditionVisitor { tcx, spans, name, errors: vec![] }; visitor.visit_body(&body); let spans = visitor.spans; @@ -969,7 +967,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let mut parent = None; // The top-most loop where the moved expression could be moved to a new binding. let mut outer_most_loop: Option<&hir::Expr<'_>> = None; - for (_, node) in tcx.hir().parent_iter(expr.hir_id) { + for (_, node) in tcx.hir_parent_iter(expr.hir_id) { let e = match node { hir::Node::Expr(e) => e, hir::Node::LetStmt(hir::LetStmt { els: Some(els), .. }) => { @@ -1021,8 +1019,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } } let loop_count: usize = tcx - .hir() - .parent_iter(expr.hir_id) + .hir_parent_iter(expr.hir_id) .map(|(_, node)| match node { hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Loop(..), .. }) => 1, _ => 0, @@ -1048,8 +1045,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { .collect::<Vec<Span>>(); // All of the spans for the loops above the expression with the move error. let loop_spans: Vec<_> = tcx - .hir() - .parent_iter(expr.hir_id) + .hir_parent_iter(expr.hir_id) .filter_map(|(_, node)| match node { hir::Node::Expr(hir::Expr { span, kind: hir::ExprKind::Loop(..), .. }) => { Some(*span) @@ -1082,7 +1078,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { ] { for (destination, sp) in elements { if let Ok(hir_id) = destination.target_id - && let hir::Node::Expr(expr) = tcx.hir().hir_node(hir_id) + && let hir::Node::Expr(expr) = tcx.hir_node(hir_id) && !matches!( sp.desugaring_kind(), Some(DesugaringKind::ForLoop | DesugaringKind::WhileLoop) @@ -1334,7 +1330,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } fn in_move_closure(&self, expr: &hir::Expr<'_>) -> bool { - for (_, node) in self.infcx.tcx.hir().parent_iter(expr.hir_id) { + for (_, node) in self.infcx.tcx.hir_parent_iter(expr.hir_id) { if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(closure), .. }) = node && let hir::CaptureBy::Value { .. } = closure.capture_clause { @@ -1437,7 +1433,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let Some(hir_generics) = tcx .typeck_root_def_id(self.mir_def_id().to_def_id()) .as_local() - .and_then(|def_id| tcx.hir().get_generics(def_id)) + .and_then(|def_id| tcx.hir_get_generics(def_id)) else { return; }; @@ -1889,7 +1885,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { fn suggest_copy_for_type_in_cloned_ref(&self, err: &mut Diag<'infcx>, place: Place<'tcx>) { let tcx = self.infcx.tcx; - let hir = tcx.hir(); let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return }; struct FindUselessClone<'tcx> { @@ -1917,7 +1912,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let mut expr_finder = FindUselessClone::new(tcx, self.mir_def_id()); - let body = hir.body(body_id).value; + let body = tcx.hir_body(body_id).value; expr_finder.visit_expr(body); struct Holds<'tcx> { @@ -2106,7 +2101,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let tcx = self.infcx.tcx; let body_id = tcx.hir_node(self.mir_hir_id()).body_id()?; let mut expr_finder = FindExprBySpan::new(span, tcx); - expr_finder.visit_expr(tcx.hir().body(body_id).value); + expr_finder.visit_expr(tcx.hir_body(body_id).value); expr_finder.result } @@ -2119,7 +2114,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { issued_span: Span, ) { let tcx = self.infcx.tcx; - let hir = tcx.hir(); let has_split_at_mut = |ty: Ty<'tcx>| { let ty = ty.peel_refs(); @@ -2172,7 +2166,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { return; }; - let Some(object) = hir.parent_id_iter(index1.hir_id).find_map(|id| { + let Some(object) = tcx.hir_parent_id_iter(index1.hir_id).find_map(|id| { if let hir::Node::Expr(expr) = tcx.hir_node(id) && let hir::ExprKind::Index(obj, ..) = expr.kind { @@ -2190,7 +2184,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { return; }; - let Some(swap_call) = hir.parent_id_iter(object.hir_id).find_map(|id| { + let Some(swap_call) = tcx.hir_parent_id_iter(object.hir_id).find_map(|id| { if let hir::Node::Expr(call) = tcx.hir_node(id) && let hir::ExprKind::Call(callee, ..) = call.kind && let hir::ExprKind::Path(qpath) = callee.kind @@ -2258,7 +2252,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { ) { let issue_span = issued_spans.args_or_use(); let tcx = self.infcx.tcx; - let hir = tcx.hir(); let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return }; let typeck_results = tcx.typeck(self.mir_def_id()); @@ -2346,7 +2339,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { pat_span: None, head: None, }; - finder.visit_expr(hir.body(body_id).value); + finder.visit_expr(tcx.hir_body(body_id).value); if let Some(body_expr) = finder.body_expr && let Some(loop_span) = finder.loop_span @@ -2445,7 +2438,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { ) { let &UseSpans::ClosureUse { capture_kind_span, .. } = issued_spans else { return }; let tcx = self.infcx.tcx; - let hir = tcx.hir(); // Get the type of the local that we are trying to borrow let local = borrowed_place.local; @@ -2454,10 +2446,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // Get the body the error happens in let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return }; - let body_expr = hir.body(body_id).value; + let body_expr = tcx.hir_body(body_id).value; struct ClosureFinder<'hir> { - hir: rustc_middle::hir::map::Map<'hir>, + tcx: TyCtxt<'hir>, borrow_span: Span, res: Option<(&'hir hir::Expr<'hir>, &'hir hir::Closure<'hir>)>, /// The path expression with the `borrow_span` span @@ -2466,8 +2458,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { impl<'hir> Visitor<'hir> for ClosureFinder<'hir> { type NestedFilter = OnlyBodies; - fn nested_visit_map(&mut self) -> Self::Map { - self.hir + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.tcx } fn visit_expr(&mut self, ex: &'hir hir::Expr<'hir>) { @@ -2493,7 +2485,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // Find the closure that most tightly wraps `capture_kind_span` let mut finder = - ClosureFinder { hir, borrow_span: capture_kind_span, res: None, error_path: None }; + ClosureFinder { tcx, borrow_span: capture_kind_span, res: None, error_path: None }; finder.visit_expr(body_expr); let Some((closure_expr, closure)) = finder.res else { return }; @@ -2524,7 +2516,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // Find the first argument with a matching type, get its name let Some((_, this_name)) = - params.iter().zip(hir.body_param_names(closure.body)).find(|(param_ty, name)| { + params.iter().zip(tcx.hir_body_param_names(closure.body)).find(|(param_ty, name)| { // FIXME: also support deref for stuff like `Rc` arguments param_ty.peel_refs() == local_ty && name != &Ident::empty() }) @@ -2558,7 +2550,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } let mut finder = VariableUseFinder { local_id, spans: Vec::new() }; - finder.visit_expr(hir.body(closure.body).value); + finder.visit_expr(tcx.hir_body(closure.body).value); spans = finder.spans; } else { @@ -2624,7 +2616,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { if let hir::Pat { kind: hir::PatKind::Binding(_, hir_id, _ident, _), .. } = local.pat && let Some(init) = local.init - && let hir::Expr { + && let &hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { kind: hir::ClosureKind::Closure, @@ -3211,7 +3203,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { if let Some(scope) = self.body.source_scopes.get(source_info.scope) && let ClearCrossCrate::Set(scope_data) = &scope.local_data && let Some(id) = self.infcx.tcx.hir_node(scope_data.lint_root).body_id() - && let hir::ExprKind::Block(block, _) = self.infcx.tcx.hir().body(id).value.kind + && let hir::ExprKind::Block(block, _) = self.infcx.tcx.hir_body(id).value.kind { for stmt in block.stmts { let mut visitor = NestedStatementVisitor { @@ -3537,10 +3529,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { location: Location, mpi: MovePathIndex, ) -> (Vec<MoveSite>, Vec<Location>) { - fn predecessor_locations<'a, 'tcx>( - body: &'a mir::Body<'tcx>, + fn predecessor_locations<'tcx>( + body: &mir::Body<'tcx>, location: Location, - ) -> impl Iterator<Item = Location> + Captures<'tcx> + 'a { + ) -> impl Iterator<Item = Location> { if location.statement_index == 0 { let predecessors = body.basic_blocks.predecessors()[location.block].to_vec(); Either::Left(predecessors.into_iter().map(move |bb| body.terminator_loc(bb))) @@ -4180,7 +4172,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { debug!("annotate_fn_sig: did={:?} sig={:?}", did, sig); let is_closure = self.infcx.tcx.is_closure_like(did.to_def_id()); let fn_hir_id = self.infcx.tcx.local_def_id_to_hir_id(did); - let fn_decl = self.infcx.tcx.hir().fn_decl_by_hir_id(fn_hir_id)?; + let fn_decl = self.infcx.tcx.hir_fn_decl_by_hir_id(fn_hir_id)?; // We need to work out which arguments to highlight. We do this by looking // at the return type, where there are three cases: diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 3e474225afd..f77dda0d386 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -75,10 +75,10 @@ impl<'tcx> BorrowExplanation<'tcx> { if let Some(span) = borrow_span { let def_id = body.source.def_id(); - if let Some(node) = tcx.hir().get_if_local(def_id) + if let Some(node) = tcx.hir_get_if_local(def_id) && let Some(body_id) = node.body_id() { - let body = tcx.hir().body(body_id); + let body = tcx.hir_body(body_id); let mut expr_finder = FindExprBySpan::new(span, tcx); expr_finder.visit_expr(body.value); if let Some(mut expr) = expr_finder.result { @@ -117,7 +117,7 @@ impl<'tcx> BorrowExplanation<'tcx> { let local_decl = &body.local_decls[dropped_local]; if let &LocalInfo::IfThenRescopeTemp { if_then } = local_decl.local_info() - && let Some((_, hir::Node::Expr(expr))) = tcx.hir().parent_iter(if_then).next() + && let Some((_, hir::Node::Expr(expr))) = tcx.hir_parent_iter(if_then).next() && let hir::ExprKind::If(cond, conseq, alt) = expr.kind && let hir::ExprKind::Let(&hir::LetExpr { span: _, @@ -256,13 +256,13 @@ impl<'tcx> BorrowExplanation<'tcx> { impl<'hir> rustc_hir::intravisit::Visitor<'hir> for FindLetExpr<'hir> { type NestedFilter = rustc_middle::hir::nested_filter::OnlyBodies; - fn nested_visit_map(&mut self) -> Self::Map { - self.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.tcx } fn visit_expr(&mut self, expr: &'hir hir::Expr<'hir>) { if let hir::ExprKind::If(cond, _conseq, _alt) | hir::ExprKind::Loop( - hir::Block { + &hir::Block { expr: Some(&hir::Expr { kind: hir::ExprKind::If(cond, _conseq, _alt), @@ -308,9 +308,9 @@ impl<'tcx> BorrowExplanation<'tcx> { suggest_rewrite_if_let(tcx, expr, &pat, init, conseq, alt, err); } else if let Some((old, new)) = multiple_borrow_span && let def_id = body.source.def_id() - && let Some(node) = tcx.hir().get_if_local(def_id) + && let Some(node) = tcx.hir_get_if_local(def_id) && let Some(body_id) = node.body_id() - && let hir_body = tcx.hir().body(body_id) + && let hir_body = tcx.hir_body(body_id) && let mut expr_finder = (FindLetExpr { span: old, result: None, tcx }) && let Some((let_expr_span, let_expr_pat, let_expr_init)) = { expr_finder.visit_expr(hir_body.value); @@ -522,7 +522,7 @@ fn suggest_rewrite_if_let<G: EmissionGuarantee>( ); if expr.span.can_be_used_for_suggestions() && conseq.span.can_be_used_for_suggestions() { let needs_block = if let Some(hir::Node::Expr(expr)) = - alt.and_then(|alt| tcx.hir().parent_iter(alt.hir_id).next()).map(|(_, node)| node) + alt.and_then(|alt| tcx.hir_parent_iter(alt.hir_id).next()).map(|(_, node)| node) { matches!(expr.kind, hir::ExprKind::If(..)) } else { diff --git a/compiler/rustc_borrowck/src/diagnostics/find_use.rs b/compiler/rustc_borrowck/src/diagnostics/find_use.rs index 26a090f5579..96f48840468 100644 --- a/compiler/rustc_borrowck/src/diagnostics/find_use.rs +++ b/compiler/rustc_borrowck/src/diagnostics/find_use.rs @@ -1,7 +1,7 @@ use std::collections::VecDeque; use rustc_data_structures::fx::FxIndexSet; -use rustc_middle::mir::visit::{MirVisitable, PlaceContext, Visitor}; +use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::{self, Body, Local, Location}; use rustc_middle::ty::{RegionVid, TyCtxt}; @@ -45,7 +45,22 @@ impl<'a, 'tcx> UseFinder<'a, 'tcx> { let block_data = &self.body[p.block]; - match self.def_use(p, block_data.visitable(p.statement_index)) { + let mut visitor = DefUseVisitor { + body: self.body, + tcx: self.tcx, + region_vid: self.region_vid, + def_use_result: None, + }; + + let is_statement = p.statement_index < block_data.statements.len(); + + if is_statement { + visitor.visit_statement(&block_data.statements[p.statement_index], p); + } else { + visitor.visit_terminator(block_data.terminator.as_ref().unwrap(), p); + } + + match visitor.def_use_result { Some(DefUseResult::Def) => {} Some(DefUseResult::UseLive { local }) => { @@ -57,7 +72,7 @@ impl<'a, 'tcx> UseFinder<'a, 'tcx> { } None => { - if p.statement_index < block_data.statements.len() { + if is_statement { queue.push_back(p.successor_within_block()); } else { queue.extend( @@ -77,19 +92,6 @@ impl<'a, 'tcx> UseFinder<'a, 'tcx> { None } - - fn def_use(&self, location: Location, thing: &dyn MirVisitable<'tcx>) -> Option<DefUseResult> { - let mut visitor = DefUseVisitor { - body: self.body, - tcx: self.tcx, - region_vid: self.region_vid, - def_use_result: None, - }; - - thing.apply(location, &mut visitor); - - visitor.def_use_result - } } struct DefUseVisitor<'a, 'tcx> { diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 860c7c267ea..d1f238331d5 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -13,10 +13,9 @@ use rustc_infer::infer::{ }; use rustc_infer::traits::SelectionError; use rustc_middle::bug; -use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::{ AggregateKind, CallSource, ConstOperand, ConstraintCategory, FakeReadCause, Local, LocalInfo, - LocalKind, Location, Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, + LocalKind, Location, Operand, Place, PlaceRef, PlaceTy, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, find_self_call, }; use rustc_middle::ty::print::Print; @@ -570,7 +569,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // If we didn't find an overloaded deref or index, then assume it's a // built in deref and check the type of the base. let base_ty = deref_base.ty(self.body, tcx).ty; - if base_ty.is_unsafe_ptr() { + if base_ty.is_raw_ptr() { BorrowedContentSource::DerefRawPointer } else if base_ty.is_mutable_ptr() { BorrowedContentSource::DerefMutableRef @@ -1127,7 +1126,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let hir_id = self.infcx.tcx.local_def_id_to_hir_id(def_id); let expr = &self.infcx.tcx.hir().expect_expr(hir_id).kind; debug!("closure_span: hir_id={:?} expr={:?}", hir_id, expr); - if let hir::ExprKind::Closure(&hir::Closure { kind, fn_decl_span, .. }) = expr { + if let &hir::ExprKind::Closure(&hir::Closure { kind, fn_decl_span, .. }) = expr { for (captured_place, place) in self.infcx.tcx.closure_captures(def_id).iter().zip(places) { @@ -1220,7 +1219,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { .tcx .typeck_root_def_id(self.mir_def_id().to_def_id()) .as_local() - .and_then(|def_id| self.infcx.tcx.hir().get_generics(def_id)) + .and_then(|def_id| self.infcx.tcx.hir_get_generics(def_id)) && let spans = hir_generics .predicates .iter() diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 58c5c2fd774..5e83d2ffa97 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -7,7 +7,7 @@ use rustc_hir::intravisit::Visitor; use rustc_hir::{self as hir, CaptureBy, ExprKind, HirId, Node}; use rustc_middle::bug; use rustc_middle::mir::*; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_mir_dataflow::move_paths::{LookupResult, MovePathIndex}; use rustc_span::{BytePos, ExpnKind, MacroKind, Span}; use rustc_trait_selection::error_reporting::traits::FindExprBySpan; @@ -347,7 +347,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // Find the closure that captured the binding. let mut expr_finder = FindExprBySpan::new(args_span, tcx); expr_finder.include_closures = true; - expr_finder.visit_expr(tcx.hir().body(body_id).value); + expr_finder.visit_expr(tcx.hir_body(body_id).value); let Some(closure_expr) = expr_finder.result else { return }; let ExprKind::Closure(closure) = closure_expr.kind else { return }; // We'll only suggest cloning the binding if it's a `move` closure. @@ -357,7 +357,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let use_span = use_spans.var_or_use(); let mut expr_finder = FindExprBySpan::new(use_span, tcx); expr_finder.include_closures = true; - expr_finder.visit_expr(tcx.hir().body(body_id).value); + expr_finder.visit_expr(tcx.hir_body(body_id).value); let Some(use_expr) = expr_finder.result else { return }; let parent = tcx.parent_hir_node(use_expr.hir_id); if let Node::Expr(expr) = parent @@ -388,7 +388,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // Search for an appropriate place for the structured `.clone()` suggestion to be applied. // If we encounter a statement before the borrow error, we insert a statement there. - for (_, node) in tcx.hir().parent_iter(closure_expr.hir_id) { + for (_, node) in tcx.hir_parent_iter(closure_expr.hir_id) { if let Node::Stmt(stmt) = node { let padding = tcx .sess @@ -690,7 +690,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { /// make it bind by reference instead (if possible) struct BindingFinder<'tcx> { typeck_results: &'tcx ty::TypeckResults<'tcx>, - hir: rustc_middle::hir::map::Map<'tcx>, + tcx: TyCtxt<'tcx>, /// Input: the span of the pattern we're finding bindings in pat_span: Span, /// Input: the spans of the bindings we're providing suggestions for @@ -709,8 +709,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { impl<'tcx> Visitor<'tcx> for BindingFinder<'tcx> { type NestedFilter = rustc_middle::hir::nested_filter::OnlyBodies; - fn nested_visit_map(&mut self) -> Self::Map { - self.hir + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.tcx } fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) -> Self::Result { @@ -777,12 +777,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } let Some(pat_span) = pat_span else { return }; - let hir = self.infcx.tcx.hir(); - let Some(body) = hir.maybe_body_owned_by(self.mir_def_id()) else { return }; + let tcx = self.infcx.tcx; + let Some(body) = tcx.hir_maybe_body_owned_by(self.mir_def_id()) else { return }; let typeck_results = self.infcx.tcx.typeck(self.mir_def_id()); let mut finder = BindingFinder { typeck_results, - hir, + tcx, pat_span, binding_spans, found_pat: false, diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 706dd7135f7..be4a7736b1c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -404,7 +404,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { pat.kind { if upvar_ident.name == kw::SelfLower { - for (_, node) in self.infcx.tcx.hir().parent_iter(upvar_hir_id) { + for (_, node) in self.infcx.tcx.hir_parent_iter(upvar_hir_id) { if let Some(fn_decl) = node.fn_decl() { if !matches!( fn_decl.implicit_self, @@ -648,10 +648,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } } } - let hir_map = self.infcx.tcx.hir(); let def_id = self.body.source.def_id(); let Some(local_def_id) = def_id.as_local() else { return }; - let Some(body) = hir_map.maybe_body_owned_by(local_def_id) else { return }; + let Some(body) = self.infcx.tcx.hir_maybe_body_owned_by(local_def_id) else { return }; let mut v = SuggestIndexOperatorAlternativeVisitor { assign_span: span, @@ -749,7 +748,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // `fn foo(&x: &i32)` -> `fn foo(&(mut x): &i32)` let def_id = self.body.source.def_id(); if let Some(local_def_id) = def_id.as_local() - && let Some(body) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id) + && let Some(body) = self.infcx.tcx.hir_maybe_body_owned_by(local_def_id) && let Some(hir_id) = (BindingFinder { span: pat_span }).visit_body(&body).break_value() && let node = self.infcx.tcx.hir_node(hir_id) && let hir::Node::LetStmt(hir::LetStmt { @@ -856,7 +855,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { use hir::ExprKind::{AddrOf, Block, Call, MethodCall}; use hir::{BorrowKind, Expr}; - let hir_map = self.infcx.tcx.hir(); + let tcx = self.infcx.tcx; struct Finder { span: Span, } @@ -871,7 +870,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } } } - if let Some(body) = hir_map.maybe_body_owned_by(self.mir_def_id()) + if let Some(body) = tcx.hir_maybe_body_owned_by(self.mir_def_id()) && let Block(block, _) = body.value.kind { // `span` corresponds to the expression being iterated, find the `for`-loop desugared @@ -884,17 +883,15 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { MethodCall(path_segment, _, _, span) => { // We have `for _ in iter.read_only_iter()`, try to // suggest `for _ in iter.mutable_iter()` instead. - let opt_suggestions = self - .infcx - .tcx + let opt_suggestions = tcx .typeck(path_segment.hir_id.owner.def_id) .type_dependent_def_id(expr.hir_id) - .and_then(|def_id| self.infcx.tcx.impl_of_method(def_id)) - .map(|def_id| self.infcx.tcx.associated_items(def_id)) + .and_then(|def_id| tcx.impl_of_method(def_id)) + .map(|def_id| tcx.associated_items(def_id)) .map(|assoc_items| { assoc_items .in_definition_order() - .map(|assoc_item_def| assoc_item_def.ident(self.infcx.tcx)) + .map(|assoc_item_def| assoc_item_def.ident(tcx)) .filter(|&ident| { let original_method_ident = path_segment.ident; original_method_ident != ident @@ -936,12 +933,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { fn expected_fn_found_fn_mut_call(&self, err: &mut Diag<'_>, sp: Span, act: &str) { err.span_label(sp, format!("cannot {act}")); - let hir = self.infcx.tcx.hir(); + let tcx = self.infcx.tcx; let closure_id = self.mir_hir_id(); - let closure_span = self.infcx.tcx.def_span(self.mir_def_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 closure_span = tcx.def_span(self.mir_def_id()); + let fn_call_id = tcx.parent_hir_id(closure_id); + let node = tcx.hir_node(fn_call_id); + let def_id = tcx.hir_enclosing_body_owner(fn_call_id); let mut look_at_return = true; // If the HIR node is a function or method call gets the def ID @@ -951,7 +948,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { return None; }; - let typeck_results = self.infcx.tcx.typeck(def_id); + let typeck_results = tcx.typeck(def_id); match kind { hir::ExprKind::Call(expr, args) => { @@ -980,7 +977,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { .map(|(pos, _)| pos) .next(); - let arg = match hir.get_if_local(callee_def_id) { + let arg = match tcx.hir_get_if_local(callee_def_id) { Some( hir::Node::Item(hir::Item { ident, kind: hir::ItemKind::Fn { sig, .. }, .. @@ -1019,10 +1016,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } } - if look_at_return && hir.get_fn_id_for_return_block(closure_id).is_some() { + if look_at_return && tcx.hir_get_fn_id_for_return_block(closure_id).is_some() { // ...otherwise we are probably in the tail expression of the function, point at the // return type. - match self.infcx.tcx.hir_node_by_def_id(hir.get_parent_item(fn_call_id).def_id) { + match tcx.hir_node_by_def_id(tcx.hir_get_parent_item(fn_call_id).def_id) { hir::Node::Item(hir::Item { ident, kind: hir::ItemKind::Fn { sig, .. }, .. }) @@ -1050,9 +1047,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { fn suggest_using_iter_mut(&self, err: &mut Diag<'_>) { let source = self.body.source; - let hir = self.infcx.tcx.hir(); if let InstanceKind::Item(def_id) = source.instance - && let Some(Node::Expr(hir::Expr { hir_id, kind, .. })) = hir.get_if_local(def_id) + && let Some(Node::Expr(hir::Expr { hir_id, kind, .. })) = + self.infcx.tcx.hir_get_if_local(def_id) && let ExprKind::Closure(hir::Closure { kind: hir::ClosureKind::Closure, .. }) = kind && let Node::Expr(expr) = self.infcx.tcx.parent_hir_node(*hir_id) { @@ -1274,7 +1271,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { }) => { let def_id = self.body.source.def_id(); let hir_id = if let Some(local_def_id) = def_id.as_local() - && let Some(body) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id) + && let Some(body) = self.infcx.tcx.hir_maybe_body_owned_by(local_def_id) { BindingFinder { span: err_label_span }.visit_body(&body).break_value() } else { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index b809b40a399..55b6367f35f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -14,7 +14,10 @@ use rustc_infer::infer::{NllRegionVariableOrigin, RelateParamBound}; use rustc_middle::bug; use rustc_middle::hir::place::PlaceBase; use rustc_middle::mir::{AnnotationSource, ConstraintCategory, ReturnConstraint}; -use rustc_middle::ty::{self, GenericArgs, Region, RegionVid, Ty, TyCtxt, TypeVisitor}; +use rustc_middle::ty::fold::fold_regions; +use rustc_middle::ty::{ + self, GenericArgs, Region, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitor, +}; use rustc_span::{Ident, Span, kw}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::error_reporting::infer::nice_region_error::{ @@ -147,9 +150,7 @@ pub(crate) enum RegionErrorKind<'tcx> { pub(crate) struct ErrorConstraintInfo<'tcx> { // fr: outlived_fr pub(super) fr: RegionVid, - pub(super) fr_is_local: bool, pub(super) outlived_fr: RegionVid, - pub(super) outlived_fr_is_local: bool, // Category and span for best blame constraint pub(super) category: ConstraintCategory<'tcx>, @@ -185,6 +186,17 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } } + /// Map the regions in the type to named regions, where possible. + fn name_regions<T>(&self, tcx: TyCtxt<'tcx>, ty: T) -> T + where + T: TypeFoldable<TyCtxt<'tcx>>, + { + fold_regions(tcx, ty, |region, _| match *region { + ty::ReVar(vid) => self.to_error_region(vid).unwrap_or(region), + _ => region, + }) + } + /// Returns `true` if a closure is inferred to be an `FnMut` closure. fn is_closure_fn_mut(&self, fr: RegionVid) -> bool { if let Some(ty::ReLateParam(late_param)) = self.to_error_region(fr).as_deref() @@ -207,7 +219,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { lower_bound: RegionVid, ) { let mut suggestions = vec![]; - let hir = self.infcx.tcx.hir(); + let tcx = self.infcx.tcx; // find generic associated types in the given region 'lower_bound' let gat_id_and_generics = self @@ -216,12 +228,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { .map(|placeholder| { 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) = self - .infcx - .tcx - .parent_hir_node(self.infcx.tcx.parent_hir_id(gat_hir_id)) - .generics() + && let gat_hir_id = tcx.local_def_id_to_hir_id(placeholder_id) + && let Some(generics_impl) = + tcx.parent_hir_node(tcx.parent_hir_id(gat_hir_id)).generics() { Some((gat_hir_id, generics_impl)) } else { @@ -242,7 +251,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { }; if bound_generic_params .iter() - .rfind(|bgp| self.infcx.tcx.local_def_id_to_hir_id(bgp.def_id) == *gat_hir_id) + .rfind(|bgp| tcx.local_def_id_to_hir_id(bgp.def_id) == *gat_hir_id) .is_some() { for bound in *bounds { @@ -258,7 +267,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { return; }; diag.span_note(*trait_span, fluent::borrowck_limitations_implies_static); - let Some(generics_fn) = hir.get_generics(self.body.source.def_id().expect_local()) + let Some(generics_fn) = tcx.hir_get_generics(self.body.source.def_id().expect_local()) else { return; }; @@ -316,13 +325,16 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let type_test_span = type_test.span; if let Some(lower_bound_region) = lower_bound_region { - let generic_ty = type_test.generic_kind.to_ty(self.infcx.tcx); + let generic_ty = self.name_regions( + self.infcx.tcx, + type_test.generic_kind.to_ty(self.infcx.tcx), + ); let origin = RelateParamBound(type_test_span, generic_ty, None); self.buffer_error(self.infcx.err_ctxt().construct_generic_bound_failure( self.body.source.def_id().expect_local(), type_test_span, Some(origin), - type_test.generic_kind, + self.name_regions(self.infcx.tcx, type_test.generic_kind), lower_bound_region, )); } else { @@ -353,9 +365,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } RegionErrorKind::UnexpectedHiddenRegion { span, hidden_ty, key, member_region } => { - let named_ty = self.regioncx.name_regions(self.infcx.tcx, hidden_ty); - let named_key = self.regioncx.name_regions(self.infcx.tcx, key); - let named_region = self.regioncx.name_regions(self.infcx.tcx, member_region); + let named_ty = + self.regioncx.name_regions_for_member_constraint(self.infcx.tcx, hidden_ty); + let named_key = + self.regioncx.name_regions_for_member_constraint(self.infcx.tcx, key); + let named_region = self + .regioncx + .name_regions_for_member_constraint(self.infcx.tcx, member_region); let diag = unexpected_hidden_region_diagnostic( self.infcx, self.mir_def_id(), @@ -468,14 +484,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { fr_is_local, outlived_fr_is_local, category ); - let errci = ErrorConstraintInfo { - fr, - outlived_fr, - fr_is_local, - outlived_fr_is_local, - category, - span: cause.span, - }; + let errci = ErrorConstraintInfo { fr, outlived_fr, category, span: cause.span }; let mut diag = match (category, fr_is_local, outlived_fr_is_local) { (ConstraintCategory::Return(kind), true, false) if self.is_closure_fn_mut(fr) => { @@ -677,11 +686,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { && self.regioncx.universal_regions().defining_ty.is_fn_def()) || self.regioncx.universal_regions().defining_ty.is_const() { - return self.report_general_error(&ErrorConstraintInfo { - fr_is_local: true, - outlived_fr_is_local: false, - ..*errci - }); + return self.report_general_error(errci); } let mut diag = @@ -759,15 +764,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { /// ``` #[allow(rustc::diagnostic_outside_of_impl)] // FIXME fn report_general_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'infcx> { - let ErrorConstraintInfo { - fr, - fr_is_local, - outlived_fr, - outlived_fr_is_local, - span, - category, - .. - } = errci; + let ErrorConstraintInfo { fr, outlived_fr, span, category, .. } = errci; let mir_def_name = self.infcx.tcx.def_descr(self.mir_def_id().to_def_id()); @@ -786,19 +783,22 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let outlived_fr_name = self.give_region_a_name(*outlived_fr).unwrap(); outlived_fr_name.highlight_region_name(&mut diag); - let err_category = match (category, outlived_fr_is_local, fr_is_local) { - (ConstraintCategory::Return(_), true, _) => LifetimeReturnCategoryErr::WrongReturn { + let err_category = if matches!(category, ConstraintCategory::Return(_)) + && self.regioncx.universal_regions().is_local_free_region(*outlived_fr) + { + LifetimeReturnCategoryErr::WrongReturn { span: *span, mir_def_name, outlived_fr_name, fr_name: &fr_name, - }, - _ => LifetimeReturnCategoryErr::ShortReturn { + } + } else { + LifetimeReturnCategoryErr::ShortReturn { span: *span, category_desc: category.description(), free_region_name: &fr_name, outlived_fr_name, - }, + } }; diag.subdiagnostic(err_category); @@ -1159,7 +1159,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { if ocx.select_all_or_error().is_empty() && count > 0 { diag.span_suggestion_verbose( - tcx.hir().body(*body).value.peel_blocks().span.shrink_to_lo(), + tcx.hir_body(*body).value.peel_blocks().span.shrink_to_lo(), fluent::borrowck_dereference_suggestion, "*".repeat(count), Applicability::MachineApplicable, @@ -1169,8 +1169,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { #[allow(rustc::diagnostic_outside_of_impl)] fn suggest_move_on_borrowing_closure(&self, diag: &mut Diag<'_>) { - let map = self.infcx.tcx.hir(); - let body = map.body_owned_by(self.mir_def_id()); + let body = self.infcx.tcx.hir_body_owned_by(self.mir_def_id()); let expr = &body.value.peel_blocks(); let mut closure_span = None::<rustc_span::Span>; match expr.kind { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index ccd13badad7..be28f84debd 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -424,7 +424,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { &self, argument_index: usize, ) -> Option<&hir::Ty<'tcx>> { - let fn_decl = self.infcx.tcx.hir().fn_decl_by_hir_id(self.mir_hir_id())?; + let fn_decl = self.infcx.tcx.hir_fn_decl_by_hir_id(self.mir_hir_id())?; let argument_hir_ty: &hir::Ty<'_> = fn_decl.inputs.get(argument_index)?; match argument_hir_ty.kind { // This indicates a variable with no type annotation, like @@ -671,7 +671,6 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { #[instrument(level = "trace", skip(self))] fn give_name_if_anonymous_region_appears_in_output(&self, fr: RegionVid) -> Option<RegionName> { let tcx = self.infcx.tcx; - let hir = tcx.hir(); let return_ty = self.regioncx.universal_regions().unnormalized_output_ty; debug!("give_name_if_anonymous_region_appears_in_output: return_ty = {:?}", return_ty); @@ -682,7 +681,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { let mir_hir_id = self.mir_hir_id(); let (return_span, mir_description, hir_ty) = match tcx.hir_node(mir_hir_id) { - hir::Node::Expr(hir::Expr { + hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { fn_decl, kind, fn_decl_span, .. }), .. }) => { @@ -711,7 +710,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { hir::CoroutineSource::Fn, )) => { let parent_item = - tcx.hir_node_by_def_id(hir.get_parent_item(mir_hir_id).def_id); + tcx.hir_node_by_def_id(tcx.hir_get_parent_item(mir_hir_id).def_id); let output = &parent_item .fn_decl() .expect("coroutine lowered from async fn should be in fn") @@ -741,7 +740,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { hir::CoroutineSource::Fn, )) => { let parent_item = - tcx.hir_node_by_def_id(hir.get_parent_item(mir_hir_id).def_id); + tcx.hir_node_by_def_id(tcx.hir_get_parent_item(mir_hir_id).def_id); let output = &parent_item .fn_decl() .expect("coroutine lowered from gen fn should be in fn") @@ -768,7 +767,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { hir::CoroutineSource::Fn, )) => { let parent_item = - tcx.hir_node_by_def_id(hir.get_parent_item(mir_hir_id).def_id); + tcx.hir_node_by_def_id(tcx.hir_get_parent_item(mir_hir_id).def_id); let output = &parent_item .fn_decl() .expect("coroutine lowered from async gen fn should be in fn") @@ -874,7 +873,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { .name; let yield_span = match tcx.hir_node(self.mir_hir_id()) { - hir::Node::Expr(hir::Expr { + hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }), .. }) => tcx.sess.source_map().end_point(fn_decl_span), diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 53cf4f34ae7..a98984a4b4c 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -33,7 +33,6 @@ use rustc_index::{IndexSlice, IndexVec}; use rustc_infer::infer::{ InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, TyCtxtInferExt, }; -use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::*; use rustc_middle::query::Providers; use rustc_middle::ty::fold::fold_regions; @@ -188,7 +187,7 @@ fn do_mir_borrowck<'tcx>( .iterate_to_fixpoint(tcx, body, Some("borrowck")) .into_results_cursor(body); - let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(def).is_fn_or_closure(); + let locals_are_invalidated_at_exit = tcx.hir_body_owner_kind(def).is_fn_or_closure(); let borrow_set = BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &move_data); // Compute non-lexical lifetimes. diff --git a/compiler/rustc_borrowck/src/member_constraints.rs b/compiler/rustc_borrowck/src/member_constraints.rs index a0adf471fd3..bdd0f6fe11e 100644 --- a/compiler/rustc_borrowck/src/member_constraints.rs +++ b/compiler/rustc_borrowck/src/member_constraints.rs @@ -1,7 +1,6 @@ use std::hash::Hash; use std::ops::Index; -use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxIndexMap; use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::ty::{self, Ty}; @@ -147,9 +146,7 @@ impl<'tcx, R> MemberConstraintSet<'tcx, R> where R: Copy + Hash + Eq, { - pub(crate) fn all_indices( - &self, - ) -> impl Iterator<Item = NllMemberConstraintIndex> + Captures<'tcx> + '_ { + pub(crate) fn all_indices(&self) -> impl Iterator<Item = NllMemberConstraintIndex> { self.constraints.indices() } @@ -159,7 +156,7 @@ where pub(crate) fn indices( &self, member_region_vid: R, - ) -> impl Iterator<Item = NllMemberConstraintIndex> + Captures<'tcx> + '_ { + ) -> impl Iterator<Item = NllMemberConstraintIndex> { let mut next = self.first_constraints.get(&member_region_vid).cloned(); std::iter::from_fn(move || -> Option<NllMemberConstraintIndex> { if let Some(current) = next { diff --git a/compiler/rustc_borrowck/src/polonius/dump.rs b/compiler/rustc_borrowck/src/polonius/dump.rs index 5f9fa3612b8..aa64a7c4e2a 100644 --- a/compiler/rustc_borrowck/src/polonius/dump.rs +++ b/compiler/rustc_borrowck/src/polonius/dump.rs @@ -226,7 +226,7 @@ fn emit_polonius_mir<'tcx>( regioncx, closure_region_requirements, borrow_set, - pass_where.clone(), + pass_where, out, )?; diff --git a/compiler/rustc_borrowck/src/polonius/loan_liveness.rs b/compiler/rustc_borrowck/src/polonius/loan_liveness.rs index 768c12a97a6..5cd265e0db9 100644 --- a/compiler/rustc_borrowck/src/polonius/loan_liveness.rs +++ b/compiler/rustc_borrowck/src/polonius/loan_liveness.rs @@ -175,7 +175,7 @@ impl LocalizedConstraintGraph { } /// Returns the outgoing edges of a given node, not its transitive closure. - fn outgoing_edges(&self, node: LocalizedNode) -> impl Iterator<Item = LocalizedNode> + use<'_> { + fn outgoing_edges(&self, node: LocalizedNode) -> impl Iterator<Item = LocalizedNode> { // The outgoing edges are: // - the physical edges present at this node, // - the materialized logical edges that exist virtually at all points for this node's diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index d2268c4779d..a00fce08c9b 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -576,9 +576,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } /// Returns an iterator over all the outlives constraints. - pub(crate) fn outlives_constraints( - &self, - ) -> impl Iterator<Item = OutlivesConstraint<'tcx>> + '_ { + pub(crate) fn outlives_constraints(&self) -> impl Iterator<Item = OutlivesConstraint<'tcx>> { self.constraints.outlives().iter().copied() } @@ -615,10 +613,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.scc_values.region_value_str(scc) } - pub(crate) fn placeholders_contained_in<'a>( - &'a self, + pub(crate) fn placeholders_contained_in( + &self, r: RegionVid, - ) -> impl Iterator<Item = ty::PlaceholderRegion> + 'a { + ) -> impl Iterator<Item = ty::PlaceholderRegion> { let scc = self.constraint_sccs.scc(r); self.scc_values.placeholders_contained_in(scc) } @@ -1267,6 +1265,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { let sub_region_scc = self.constraint_sccs.scc(sub_region); let sup_region_scc = self.constraint_sccs.scc(sup_region); + if sub_region_scc == sup_region_scc { + debug!("{sup_region:?}: {sub_region:?} holds trivially; they are in the same SCC"); + return true; + } + // If we are checking that `'sup: 'sub`, and `'sub` contains // some placeholder that `'sup` cannot name, then this is only // true if `'sup` outlives static. diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 9c19f8b3ad8..54f9e82dbb8 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -204,7 +204,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// that the regions produced are in fact equal to the named region they are /// replaced with. This is fine because this function is only to improve the /// region names in error messages. - pub(crate) fn name_regions<T>(&self, tcx: TyCtxt<'tcx>, ty: T) -> T + /// + /// This differs from `MirBorrowckCtxt::name_regions` since it is particularly + /// lax with mapping region vids that are *shorter* than a universal region to + /// that universal region. This is useful for member region constraints since + /// we want to suggest a universal region name to capture even if it's technically + /// not equal to the error region. + pub(crate) fn name_regions_for_member_constraint<T>(&self, tcx: TyCtxt<'tcx>, ty: T) -> T where T: TypeFoldable<TyCtxt<'tcx>>, { diff --git a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs index d0cfe572d08..b2ed8a35827 100644 --- a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs +++ b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs @@ -20,10 +20,7 @@ pub(crate) struct ReverseSccGraph { impl ReverseSccGraph { /// Find all universal regions that are required to outlive the given SCC. - pub(super) fn upper_bounds<'a>( - &'a self, - scc0: ConstraintSccIndex, - ) -> impl Iterator<Item = RegionVid> + 'a { + pub(super) fn upper_bounds(&self, scc0: ConstraintSccIndex) -> impl Iterator<Item = RegionVid> { let mut duplicates = FxIndexSet::default(); graph::depth_first_search(&self.graph, scc0) .flat_map(move |scc1| { diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index f1bcb353dc6..d9ac5b5cb13 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -88,7 +88,7 @@ impl LivenessValues { } /// Iterate through each region that has a value in this set. - pub(crate) fn regions(&self) -> impl Iterator<Item = RegionVid> + '_ { + pub(crate) fn regions(&self) -> impl Iterator<Item = RegionVid> { self.points.as_ref().expect("use with_specific_points").rows() } @@ -96,7 +96,7 @@ impl LivenessValues { // We are passing query instability implications to the caller. #[rustc_lint_query_instability] #[allow(rustc::potential_query_instability)] - pub(crate) fn live_regions_unordered(&self) -> impl Iterator<Item = RegionVid> + '_ { + pub(crate) fn live_regions_unordered(&self) -> impl Iterator<Item = RegionVid> { self.live_regions.as_ref().unwrap().iter().copied() } @@ -143,7 +143,7 @@ impl LivenessValues { } /// Returns an iterator of all the points where `region` is live. - fn live_points(&self, region: RegionVid) -> impl Iterator<Item = PointIndex> + '_ { + fn live_points(&self, region: RegionVid) -> impl Iterator<Item = PointIndex> { let Some(points) = &self.points else { unreachable!( "Should be using LivenessValues::with_specific_points to ask whether live at a location" @@ -340,7 +340,7 @@ impl<N: Idx> RegionValues<N> { } /// Returns the locations contained within a given region `r`. - pub(crate) fn locations_outlived_by<'a>(&'a self, r: N) -> impl Iterator<Item = Location> + 'a { + pub(crate) fn locations_outlived_by(&self, r: N) -> impl Iterator<Item = Location> { self.points.row(r).into_iter().flat_map(move |set| { set.iter() .take_while(move |&p| self.location_map.point_in_range(p)) @@ -349,18 +349,15 @@ impl<N: Idx> RegionValues<N> { } /// Returns just the universal regions that are contained in a given region's value. - pub(crate) fn universal_regions_outlived_by<'a>( - &'a self, - r: N, - ) -> impl Iterator<Item = RegionVid> + 'a { + pub(crate) fn universal_regions_outlived_by(&self, r: N) -> impl Iterator<Item = RegionVid> { self.free_regions.row(r).into_iter().flat_map(|set| set.iter()) } /// Returns all the elements contained in a given region's value. - pub(crate) fn placeholders_contained_in<'a>( - &'a self, + pub(crate) fn placeholders_contained_in( + &self, r: N, - ) -> impl Iterator<Item = ty::PlaceholderRegion> + 'a { + ) -> impl Iterator<Item = ty::PlaceholderRegion> { self.placeholders .row(r) .into_iter() @@ -369,10 +366,7 @@ impl<N: Idx> RegionValues<N> { } /// Returns all the elements contained in a given region's value. - pub(crate) fn elements_contained_in<'a>( - &'a self, - r: N, - ) -> impl Iterator<Item = RegionElement> + 'a { + pub(crate) fn elements_contained_in(&self, r: N) -> impl Iterator<Item = RegionElement> { let points_iter = self.locations_outlived_by(r).map(RegionElement::Location); let free_regions_iter = diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index bffd9f38334..b3fa786a517 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -149,6 +149,18 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.normalize_with_category(value, location, ConstraintCategory::Boring) } + pub(super) fn deeply_normalize<T>(&mut self, value: T, location: impl NormalizeLocation) -> T + where + T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx, + { + let result: Result<_, ErrorGuaranteed> = self.fully_perform_op( + location.to_locations(), + ConstraintCategory::Boring, + self.infcx.param_env.and(type_op::normalize::DeeplyNormalize { value }), + ); + result.unwrap_or(value) + } + #[instrument(skip(self), level = "debug")] pub(super) fn normalize_with_category<T>( &mut self, diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index 4b7f5321388..3b48ca305c4 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -4,15 +4,12 @@ use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate}; use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound}; use rustc_infer::infer::{self, InferCtxt, SubregionOrigin}; +use rustc_infer::traits::query::type_op::DeeplyNormalize; use rustc_middle::bug; use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory}; -use rustc_middle::traits::ObligationCause; -use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::fold::fold_regions; use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt}; use rustc_span::Span; -use rustc_trait_selection::traits::ScrubbedTraitError; -use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp; use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput}; use tracing::{debug, instrument}; @@ -270,20 +267,8 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { ConstraintCategory<'tcx>, )>, ) -> Ty<'tcx> { - let result = CustomTypeOp::new( - |ocx| { - ocx.deeply_normalize( - &ObligationCause::dummy_with_span(self.span), - self.param_env, - ty, - ) - .map_err(|_: Vec<ScrubbedTraitError<'tcx>>| NoSolution) - }, - "normalize type outlives obligation", - ) - .fully_perform(self.infcx, self.span); - - match result { + match self.param_env.and(DeeplyNormalize { value: ty }).fully_perform(self.infcx, self.span) + { Ok(TypeOpOutput { output: ty, constraints, .. }) => { if let Some(QueryRegionConstraints { outlives }) = constraints { next_outlives_predicates.extend(outlives.iter().copied()); diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index edf612f4e97..eaac633b512 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -5,14 +5,11 @@ use rustc_infer::infer::canonical::QueryRegionConstraints; use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::region_constraints::GenericKind; use rustc_infer::infer::{InferCtxt, outlives}; -use rustc_infer::traits::ScrubbedTraitError; +use rustc_infer::traits::query::type_op::DeeplyNormalize; use rustc_middle::mir::ConstraintCategory; -use rustc_middle::traits::ObligationCause; use rustc_middle::traits::query::OutlivesBound; use rustc_middle::ty::{self, RegionVid, Ty, TypeVisitableExt}; use rustc_span::{ErrorGuaranteed, Span}; -use rustc_trait_selection::solve::NoSolution; -use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp; use rustc_trait_selection::traits::query::type_op::{self, TypeOp}; use tracing::{debug, instrument}; use type_op::TypeOpOutput; @@ -175,7 +172,7 @@ impl UniversalRegionRelations<'_> { } /// Returns the _non-transitive_ set of known `outlives` constraints between free regions. - pub(crate) fn known_outlives(&self) -> impl Iterator<Item = (RegionVid, RegionVid)> + '_ { + pub(crate) fn known_outlives(&self) -> impl Iterator<Item = (RegionVid, RegionVid)> { self.outlives.base_edges() } } @@ -267,7 +264,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { } let TypeOpOutput { output: norm_ty, constraints: constraints_normalize, .. } = param_env - .and(type_op::normalize::Normalize { value: ty }) + .and(DeeplyNormalize { value: ty }) .fully_perform(self.infcx, span) .unwrap_or_else(|guar| TypeOpOutput { output: Ty::new_error(self.infcx.tcx, guar), @@ -303,9 +300,8 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { // Add implied bounds from impl header. if matches!(tcx.def_kind(defining_ty_def_id), DefKind::AssocFn | DefKind::AssocConst) { for &(ty, _) in tcx.assumed_wf_types(tcx.local_parent(defining_ty_def_id)) { - let result: Result<_, ErrorGuaranteed> = param_env - .and(type_op::normalize::Normalize { value: ty }) - .fully_perform(self.infcx, span); + let result: Result<_, ErrorGuaranteed> = + param_env.and(DeeplyNormalize { value: ty }).fully_perform(self.infcx, span); let Ok(TypeOpOutput { output: norm_ty, constraints: c, .. }) = result else { continue; }; @@ -360,18 +356,10 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { output: normalized_outlives, constraints: constraints_normalize, error_info: _, - }) = CustomTypeOp::new( - |ocx| { - ocx.deeply_normalize( - &ObligationCause::dummy_with_span(span), - self.param_env, - outlives, - ) - .map_err(|_: Vec<ScrubbedTraitError<'tcx>>| NoSolution) - }, - "normalize type outlives obligation", - ) - .fully_perform(self.infcx, span) + }) = self + .param_env + .and(DeeplyNormalize { value: outlives }) + .fully_perform(self.infcx, span) else { self.infcx.dcx().delayed_bug(format!("could not normalize {outlives:?}")); return; diff --git a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs index 6182b68f6f4..9591da83708 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs @@ -54,7 +54,7 @@ rustc_index::newtype_index! { fn appearances_iter( first: Option<AppearanceIndex>, appearances: &Appearances, -) -> impl Iterator<Item = AppearanceIndex> + '_ { +) -> impl Iterator<Item = AppearanceIndex> { AppearancesIter { appearances, current: first } } @@ -107,17 +107,17 @@ impl LocalUseMap { local_use_map } - pub(crate) fn defs(&self, local: Local) -> impl Iterator<Item = PointIndex> + '_ { + pub(crate) fn defs(&self, local: Local) -> impl Iterator<Item = PointIndex> { appearances_iter(self.first_def_at[local], &self.appearances) .map(move |aa| self.appearances[aa].point_index) } - pub(crate) fn uses(&self, local: Local) -> impl Iterator<Item = PointIndex> + '_ { + pub(crate) fn uses(&self, local: Local) -> impl Iterator<Item = PointIndex> { appearances_iter(self.first_use_at[local], &self.appearances) .map(move |aa| self.appearances[aa].point_index) } - pub(crate) fn drops(&self, local: Local) -> impl Iterator<Item = PointIndex> + '_ { + pub(crate) fn drops(&self, local: Local) -> impl Iterator<Item = PointIndex> { appearances_iter(self.first_drop_at[local], &self.appearances) .map(move |aa| self.appearances[aa].point_index) } diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index 62d49a62744..dc35d5eb89c 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -3,7 +3,7 @@ use rustc_index::bit_set::DenseBitSet; use rustc_index::interval::IntervalSet; use rustc_infer::infer::canonical::QueryRegionConstraints; use rustc_infer::infer::outlives::for_liveness; -use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, Local, Location}; +use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, HasLocalDecls, Local, Location}; use rustc_middle::traits::query::DropckOutlivesResult; use rustc_middle::ty::relate::Relate; use rustc_middle::ty::{Ty, TyCtxt, TypeVisitable, TypeVisitableExt}; @@ -11,7 +11,10 @@ use rustc_mir_dataflow::ResultsCursor; use rustc_mir_dataflow::impls::MaybeInitializedPlaces; use rustc_mir_dataflow::move_paths::{HasMoveData, MoveData, MovePathIndex}; use rustc_mir_dataflow::points::{DenseLocationMap, PointIndex}; -use rustc_span::DUMMY_SP; +use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span}; +use rustc_trait_selection::error_reporting::InferCtxtErrorExt; +use rustc_trait_selection::traits::ObligationCtxt; +use rustc_trait_selection::traits::query::dropck_outlives; use rustc_trait_selection::traits::query::type_op::{DropckOutlives, TypeOp, TypeOpOutput}; use tracing::debug; @@ -162,9 +165,10 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> { fn dropck_boring_locals(&mut self, boring_locals: Vec<Local>) { for local in boring_locals { let local_ty = self.cx.body.local_decls[local].ty; + let local_span = self.cx.body.local_decls[local].source_info.span; let drop_data = self.cx.drop_data.entry(local_ty).or_insert_with({ let typeck = &self.cx.typeck; - move || LivenessContext::compute_drop_data(typeck, local_ty) + move || LivenessContext::compute_drop_data(typeck, local_ty, local_span) }); drop_data.dropck_result.report_overflows( @@ -522,9 +526,10 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { values::pretty_print_points(self.location_map, live_at.iter()), ); + let local_span = self.body.local_decls()[dropped_local].source_info.span; let drop_data = self.drop_data.entry(dropped_ty).or_insert_with({ let typeck = &self.typeck; - move || Self::compute_drop_data(typeck, dropped_ty) + move || Self::compute_drop_data(typeck, dropped_ty, local_span) }); if let Some(data) = &drop_data.region_constraint_data { @@ -589,19 +594,50 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { } } - fn compute_drop_data(typeck: &TypeChecker<'_, 'tcx>, dropped_ty: Ty<'tcx>) -> DropData<'tcx> { - debug!("compute_drop_data(dropped_ty={:?})", dropped_ty,); + fn compute_drop_data( + typeck: &TypeChecker<'_, 'tcx>, + dropped_ty: Ty<'tcx>, + span: Span, + ) -> DropData<'tcx> { + debug!("compute_drop_data(dropped_ty={:?})", dropped_ty); + + let op = typeck.infcx.param_env.and(DropckOutlives { dropped_ty }); - match typeck - .infcx - .param_env - .and(DropckOutlives { dropped_ty }) - .fully_perform(typeck.infcx, DUMMY_SP) - { + match op.fully_perform(typeck.infcx, DUMMY_SP) { Ok(TypeOpOutput { output, constraints, .. }) => { DropData { dropck_result: output, region_constraint_data: constraints } } - Err(_) => DropData { dropck_result: Default::default(), region_constraint_data: None }, + Err(ErrorGuaranteed { .. }) => { + // We don't run dropck on HIR, and dropck looks inside fields of + // types, so there's no guarantee that it succeeds. We also + // can't rely on the the `ErrorGuaranteed` from `fully_perform` here + // because it comes from delay_span_bug. + // + // Do this inside of a probe because we don't particularly care (or want) + // any region side-effects of this operation in our infcx. + typeck.infcx.probe(|_| { + let ocx = ObligationCtxt::new_with_diagnostics(&typeck.infcx); + let errors = match dropck_outlives::compute_dropck_outlives_with_errors( + &ocx, op, span, + ) { + Ok(_) => ocx.select_all_or_error(), + Err(e) => { + if e.is_empty() { + ocx.select_all_or_error() + } else { + e + } + } + }; + + // Could have no errors if a type lowering error, say, caused the query + // to fail. + if !errors.is_empty() { + typeck.infcx.err_ctxt().report_fulfillment_errors(errors); + } + }); + DropData { dropck_result: Default::default(), region_constraint_data: None } + } } } } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 26a5d438edb..bd0d98028ae 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -19,7 +19,6 @@ use rustc_infer::infer::{ BoundRegion, BoundRegionConversionTime, InferCtxt, NllRegionVariableOrigin, }; use rustc_infer::traits::PredicateObligations; -use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::traits::query::NoSolution; @@ -457,38 +456,38 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) { self.super_local_decl(local, local_decl); - if let Some(user_ty) = &local_decl.user_ty { - for (user_ty, span) in user_ty.projections_and_spans() { - let ty = if !local_decl.is_nonref_binding() { - // If we have a binding of the form `let ref x: T = ..` - // then remove the outermost reference so we can check the - // type annotation for the remaining type. - if let ty::Ref(_, rty, _) = local_decl.ty.kind() { - *rty - } else { - bug!("{:?} with ref binding has wrong type {}", local, local_decl.ty); - } - } else { - local_decl.ty - }; + for user_ty in + local_decl.user_ty.as_deref().into_iter().flat_map(UserTypeProjections::projections) + { + let span = self.typeck.user_type_annotations[user_ty.base].span; + + let ty = if local_decl.is_nonref_binding() { + local_decl.ty + } else if let &ty::Ref(_, rty, _) = local_decl.ty.kind() { + // If we have a binding of the form `let ref x: T = ..` + // then remove the outermost reference so we can check the + // type annotation for the remaining type. + rty + } else { + bug!("{:?} with ref binding has wrong type {}", local, local_decl.ty); + }; - if let Err(terr) = self.typeck.relate_type_and_user_type( - ty, - ty::Invariant, - user_ty, - Locations::All(*span), - ConstraintCategory::TypeAnnotation(AnnotationSource::Declaration), - ) { - span_mirbug!( - self, - local, - "bad user type on variable {:?}: {:?} != {:?} ({:?})", - local, - local_decl.ty, - local_decl.user_ty, - terr, - ); - } + if let Err(terr) = self.typeck.relate_type_and_user_type( + ty, + ty::Invariant, + user_ty, + Locations::All(span), + ConstraintCategory::TypeAnnotation(AnnotationSource::Declaration), + ) { + span_mirbug!( + self, + local, + "bad user type on variable {:?}: {:?} != {:?} ({:?})", + local, + local_decl.ty, + local_decl.user_ty, + terr, + ); } } } @@ -1116,7 +1115,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ConstraintCategory::Boring, ); - let sig = self.normalize(unnormalized_sig, term_location); + let sig = self.deeply_normalize(unnormalized_sig, term_location); // HACK(#114936): `WF(sig)` does not imply `WF(normalized(sig))` // with built-in `Fn` implementations, since the impl may not be // well-formed itself. diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index eb0079a3883..cfac9b36832 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -21,6 +21,7 @@ use std::iter; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::Diag; use rustc_hir::BodyOwnerKind; +use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; use rustc_index::IndexVec; @@ -125,6 +126,11 @@ pub(crate) enum DefiningTy<'tcx> { /// The MIR represents an inline const. The signature has no inputs and a /// single return value found via `InlineConstArgs::ty`. InlineConst(DefId, GenericArgsRef<'tcx>), + + // Fake body for a global asm. Not particularly useful or interesting, + // but we need it so we can properly store the typeck results of the asm + // operands, which aren't associated with a body otherwise. + GlobalAsm(DefId), } impl<'tcx> DefiningTy<'tcx> { @@ -137,9 +143,10 @@ impl<'tcx> DefiningTy<'tcx> { DefiningTy::Closure(_, args) => args.as_closure().upvar_tys(), DefiningTy::CoroutineClosure(_, args) => args.as_coroutine_closure().upvar_tys(), DefiningTy::Coroutine(_, args) => args.as_coroutine().upvar_tys(), - DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => { - ty::List::empty() - } + DefiningTy::FnDef(..) + | DefiningTy::Const(..) + | DefiningTy::InlineConst(..) + | DefiningTy::GlobalAsm(_) => ty::List::empty(), } } @@ -151,7 +158,10 @@ impl<'tcx> DefiningTy<'tcx> { DefiningTy::Closure(..) | DefiningTy::CoroutineClosure(..) | DefiningTy::Coroutine(..) => 1, - DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => 0, + DefiningTy::FnDef(..) + | DefiningTy::Const(..) + | DefiningTy::InlineConst(..) + | DefiningTy::GlobalAsm(_) => 0, } } @@ -170,7 +180,8 @@ impl<'tcx> DefiningTy<'tcx> { | DefiningTy::Coroutine(def_id, ..) | DefiningTy::FnDef(def_id, ..) | DefiningTy::Const(def_id, ..) - | DefiningTy::InlineConst(def_id, ..) => def_id, + | DefiningTy::InlineConst(def_id, ..) + | DefiningTy::GlobalAsm(def_id) => def_id, } } } @@ -307,7 +318,7 @@ impl<'tcx> UniversalRegions<'tcx> { /// Returns an iterator over all the RegionVids corresponding to /// universally quantified free regions. - pub(crate) fn universal_regions_iter(&self) -> impl Iterator<Item = RegionVid> { + pub(crate) fn universal_regions_iter(&self) -> impl Iterator<Item = RegionVid> + 'static { (FIRST_GLOBAL_INDEX..self.num_universals).map(RegionVid::from_usize) } @@ -331,9 +342,9 @@ impl<'tcx> UniversalRegions<'tcx> { } /// Gets an iterator over all the early-bound regions that have names. - pub(crate) fn named_universal_regions_iter<'s>( - &'s self, - ) -> impl Iterator<Item = (ty::Region<'tcx>, ty::RegionVid)> + 's { + pub(crate) fn named_universal_regions_iter( + &self, + ) -> impl Iterator<Item = (ty::Region<'tcx>, ty::RegionVid)> { self.indices.indices.iter().map(|(&r, &v)| (r, v)) } @@ -410,6 +421,7 @@ impl<'tcx> UniversalRegions<'tcx> { tcx.def_path_str_with_args(def_id, args), )); } + DefiningTy::GlobalAsm(_) => unreachable!(), } } @@ -576,7 +588,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let tcx = self.infcx.tcx; let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id()); - match tcx.hir().body_owner_kind(self.mir_def) { + match tcx.hir_body_owner_kind(self.mir_def) { BodyOwnerKind::Closure | BodyOwnerKind::Fn => { let defining_ty = tcx.type_of(self.mir_def).instantiate_identity(); @@ -603,7 +615,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(..) => { let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id); - if self.mir_def.to_def_id() == typeck_root_def_id { + if self.mir_def.to_def_id() == typeck_root_def_id + // Do not ICE when checking default_field_values consts with lifetimes (#135649) + && DefKind::Field != tcx.def_kind(tcx.parent(typeck_root_def_id)) + { let args = self.infcx.replace_free_regions_with_nll_infer_vars(FR, identity_args); DefiningTy::Const(self.mir_def.to_def_id(), args) @@ -629,6 +644,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { DefiningTy::InlineConst(self.mir_def.to_def_id(), args) } } + + BodyOwnerKind::GlobalAsm => DefiningTy::GlobalAsm(self.mir_def.to_def_id()), } } @@ -662,6 +679,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { } DefiningTy::FnDef(_, args) | DefiningTy::Const(_, args) => args, + + DefiningTy::GlobalAsm(_) => ty::List::empty(), }; let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static)); @@ -798,6 +817,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let ty = args.as_inline_const().ty(); ty::Binder::dummy(tcx.mk_type_list(&[ty])) } + + DefiningTy::GlobalAsm(def_id) => { + ty::Binder::dummy(tcx.mk_type_list(&[tcx.type_of(def_id).instantiate_identity()])) + } }; // FIXME(#129952): We probably want a more principled approach here. |
