diff options
Diffstat (limited to 'compiler/rustc_passes/src/liveness.rs')
-rw-r--r-- | compiler/rustc_passes/src/liveness.rs | 50 |
1 files changed, 27 insertions, 23 deletions
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index c6fe40f72..1f65cc8b6 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -87,6 +87,7 @@ use self::VarKind::*; use rustc_ast::InlineAsmOptions; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::Applicability; +use rustc_errors::Diagnostic; use rustc_hir as hir; use rustc_hir::def::*; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -412,7 +413,7 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> { } intravisit::walk_expr(self, expr); } - hir::ExprKind::Closure { .. } => { + hir::ExprKind::Closure(closure) => { // Interesting control flow (for loops can contain labeled // breaks or continues) self.add_live_node_for_node(expr.hir_id, ExprNode(expr.span, expr.hir_id)); @@ -422,8 +423,7 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> { // in better error messages than just pointing at the closure // construction site. let mut call_caps = Vec::new(); - let closure_def_id = self.tcx.hir().local_def_id(expr.hir_id); - if let Some(upvars) = self.tcx.upvars_mentioned(closure_def_id) { + if let Some(upvars) = self.tcx.upvars_mentioned(closure.def_id) { call_caps.extend(upvars.keys().map(|var_id| { let upvar = upvars[var_id]; let upvar_ln = self.add_live_node(UpvarNode(upvar.span)); @@ -922,8 +922,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // v v // ( succ ) // - let else_ln = - self.propagate_through_opt_expr(else_opt.as_ref().map(|e| &**e), succ); + let else_ln = self.propagate_through_opt_expr(else_opt.as_deref(), succ); let then_ln = self.propagate_through_expr(&then, succ); let ln = self.live_node(expr.hir_id, expr.span); self.init_from_succ(ln, else_ln); @@ -966,7 +965,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { hir::ExprKind::Ret(ref o_e) => { // Ignore succ and subst exit_ln. - self.propagate_through_opt_expr(o_e.as_ref().map(|e| &**e), self.exit_ln) + self.propagate_through_opt_expr(o_e.as_deref(), self.exit_ln) } hir::ExprKind::Break(label, ref opt_expr) => { @@ -981,7 +980,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // look it up in the break loop nodes table match target { - Some(b) => self.propagate_through_opt_expr(opt_expr.as_ref().map(|e| &**e), b), + Some(b) => self.propagate_through_opt_expr(opt_expr.as_deref(), b), None => span_bug!(expr.span, "`break` to unknown label"), } } @@ -1026,7 +1025,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { hir::ExprKind::Array(ref exprs) => self.propagate_through_exprs(exprs, succ), hir::ExprKind::Struct(_, ref fields, ref with_expr) => { - let succ = self.propagate_through_opt_expr(with_expr.as_ref().map(|e| &**e), succ); + let succ = self.propagate_through_opt_expr(with_expr.as_deref(), succ); fields .iter() .rev() @@ -1284,20 +1283,19 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { fn check_is_ty_uninhabited(&mut self, expr: &Expr<'_>, succ: LiveNode) -> LiveNode { let ty = self.typeck_results.expr_ty(expr); let m = self.ir.tcx.parent_module(expr.hir_id).to_def_id(); - if self.ir.tcx.is_ty_uninhabited_from(m, ty, self.param_env) { - match self.ir.lnks[succ] { - LiveNodeKind::ExprNode(succ_span, succ_id) => { - self.warn_about_unreachable(expr.span, ty, succ_span, succ_id, "expression"); - } - LiveNodeKind::VarDefNode(succ_span, succ_id) => { - self.warn_about_unreachable(expr.span, ty, succ_span, succ_id, "definition"); - } - _ => {} - }; - self.exit_ln - } else { - succ + if ty.is_inhabited_from(self.ir.tcx, m, self.param_env) { + return succ; } + match self.ir.lnks[succ] { + LiveNodeKind::ExprNode(succ_span, succ_id) => { + self.warn_about_unreachable(expr.span, ty, succ_span, succ_id, "expression"); + } + LiveNodeKind::VarDefNode(succ_span, succ_id) => { + self.warn_about_unreachable(expr.span, ty, succ_span, succ_id, "definition"); + } + _ => {} + }; + self.exit_ln } fn warn_about_unreachable( @@ -1550,7 +1548,13 @@ impl<'tcx> Liveness<'_, 'tcx> { .or_insert_with(|| (ln, var, vec![id_and_sp])); }); - let can_remove = matches!(&pat.kind, hir::PatKind::Struct(_, _, true)); + let can_remove = match pat.kind { + hir::PatKind::Struct(_, fields, true) => { + // if all fields are shorthand, remove the struct field, otherwise, mark with _ as prefix + fields.iter().all(|f| f.is_shorthand) + } + _ => false, + }; for (_, (ln, var, hir_ids_and_spans)) in vars { if self.used_on_entry(ln, var) { @@ -1690,7 +1694,7 @@ impl<'tcx> Liveness<'_, 'tcx> { &self, name: &str, opt_body: Option<&hir::Body<'_>>, - err: &mut rustc_errors::DiagnosticBuilder<'_, ()>, + err: &mut Diagnostic, ) -> bool { let mut has_litstring = false; let Some(opt_body) = opt_body else {return false;}; |