From 5363f350887b1e5b5dd21a86f88c8af9d7fea6da Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:18:25 +0200 Subject: Merging upstream version 1.67.1+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_mir_build/src/thir/constant.rs | 19 ++++++- compiler/rustc_mir_build/src/thir/cx/expr.rs | 65 +++++++++++----------- compiler/rustc_mir_build/src/thir/cx/mod.rs | 11 +++- .../src/thir/pattern/check_match.rs | 40 +++++++------ .../src/thir/pattern/const_to_pat.rs | 3 +- .../src/thir/pattern/deconstruct_pat.rs | 30 +++++----- compiler/rustc_mir_build/src/thir/pattern/mod.rs | 14 +++-- .../rustc_mir_build/src/thir/pattern/usefulness.rs | 2 +- 8 files changed, 105 insertions(+), 79 deletions(-) (limited to 'compiler/rustc_mir_build/src/thir') diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index f626571b5..a9ed945d4 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -1,6 +1,7 @@ use rustc_ast as ast; use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; use rustc_middle::ty::{self, ParamEnv, ScalarInt, TyCtxt}; +use rustc_span::DUMMY_SP; pub(crate) fn lit_to_const<'tcx>( tcx: TyCtxt<'tcx>, @@ -10,7 +11,15 @@ pub(crate) fn lit_to_const<'tcx>( let trunc = |n| { let param_ty = ParamEnv::reveal_all().and(ty); - let width = tcx.layout_of(param_ty).map_err(|_| LitToConstError::Reported)?.size; + let width = tcx + .layout_of(param_ty) + .map_err(|_| { + LitToConstError::Reported(tcx.sess.delay_span_bug( + DUMMY_SP, + format!("couldn't compute width of literal: {:?}", lit_input.lit), + )) + })? + .size; trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits()); let result = width.truncate(n); trace!("trunc result: {}", result); @@ -44,9 +53,13 @@ pub(crate) fn lit_to_const<'tcx>( } (ast::LitKind::Bool(b), ty::Bool) => ty::ValTree::from_scalar_int((*b).into()), (ast::LitKind::Char(c), ty::Char) => ty::ValTree::from_scalar_int((*c).into()), - (ast::LitKind::Err, _) => return Err(LitToConstError::Reported), + (ast::LitKind::Err, _) => { + return Err(LitToConstError::Reported( + tcx.sess.delay_span_bug(DUMMY_SP, "encountered LitKind::Err during mir build"), + )); + } _ => return Err(LitToConstError::TypeError), }; - Ok(ty::Const::from_value(tcx, valtree, ty)) + Ok(tcx.mk_const(valtree, ty)) } diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index c7a7c3e3f..261b95ba9 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -14,11 +14,10 @@ use rustc_middle::thir::*; use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, PointerCast, }; -use rustc_middle::ty::subst::{InternalSubsts, SubstsRef}; +use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::{ self, AdtKind, InlineConstSubsts, InlineConstSubstsParts, ScalarInt, Ty, UpvarSubsts, UserType, }; -use rustc_span::def_id::DefId; use rustc_span::Span; use rustc_target::abi::VariantIdx; @@ -51,11 +50,17 @@ impl<'tcx> Cx<'tcx> { trace!(?expr.ty); // Now apply adjustments, if any. - for adjustment in self.typeck_results.expr_adjustments(hir_expr) { - trace!(?expr, ?adjustment); - let span = expr.span; - expr = - self.apply_adjustment(hir_expr, expr, adjustment, adjustment_span.unwrap_or(span)); + if self.apply_adjustments { + for adjustment in self.typeck_results.expr_adjustments(hir_expr) { + trace!(?expr, ?adjustment); + let span = expr.span; + expr = self.apply_adjustment( + hir_expr, + expr, + adjustment, + adjustment_span.unwrap_or(span), + ); + } } trace!(?expr.ty, "after adjustments"); @@ -481,7 +486,7 @@ impl<'tcx> Cx<'tcx> { substs, user_ty, fields: self.field_refs(fields), - base: base.as_ref().map(|base| FruInfo { + base: base.map(|base| FruInfo { base: self.mirror_expr(base), field_types: self.typeck_results().fru_field_types()[expr.hir_id] .iter() @@ -584,7 +589,7 @@ impl<'tcx> Cx<'tcx> { InlineAsmOperand::Out { reg, late, - expr: expr.as_ref().map(|expr| self.mirror_expr(expr)), + expr: expr.map(|expr| self.mirror_expr(expr)), } } hir::InlineAsmOperand::InOut { reg, late, ref expr } => { @@ -599,27 +604,25 @@ impl<'tcx> Cx<'tcx> { reg, late, in_expr: self.mirror_expr(in_expr), - out_expr: out_expr.as_ref().map(|expr| self.mirror_expr(expr)), + out_expr: out_expr.map(|expr| self.mirror_expr(expr)), }, hir::InlineAsmOperand::Const { ref anon_const } => { - let anon_const_def_id = tcx.hir().local_def_id(anon_const.hir_id); let value = mir::ConstantKind::from_anon_const( tcx, - anon_const_def_id, + anon_const.def_id, self.param_env, ); - let span = tcx.hir().span(anon_const.hir_id); + let span = tcx.def_span(anon_const.def_id); InlineAsmOperand::Const { value, span } } hir::InlineAsmOperand::SymFn { ref anon_const } => { - let anon_const_def_id = tcx.hir().local_def_id(anon_const.hir_id); let value = mir::ConstantKind::from_anon_const( tcx, - anon_const_def_id, + anon_const.def_id, self.param_env, ); - let span = tcx.hir().span(anon_const.hir_id); + let span = tcx.def_span(anon_const.def_id); InlineAsmOperand::SymFn { value, span } } @@ -634,7 +637,7 @@ impl<'tcx> Cx<'tcx> { hir::ExprKind::ConstBlock(ref anon_const) => { let ty = self.typeck_results().node_type(anon_const.hir_id); - let did = tcx.hir().local_def_id(anon_const.hir_id).to_def_id(); + let did = anon_const.def_id.to_def_id(); let typeck_root_def_id = tcx.typeck_root_def_id(did); let parent_substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, typeck_root_def_id)); @@ -653,13 +656,11 @@ impl<'tcx> Cx<'tcx> { ExprKind::Repeat { value: self.mirror_expr(v), count: *count } } - hir::ExprKind::Ret(ref v) => { - ExprKind::Return { value: v.as_ref().map(|v| self.mirror_expr(v)) } - } + hir::ExprKind::Ret(ref v) => ExprKind::Return { value: v.map(|v| self.mirror_expr(v)) }, hir::ExprKind::Break(dest, ref value) => match dest.target_id { Ok(target_id) => ExprKind::Break { label: region::Scope { id: target_id.local_id, data: region::ScopeData::Node }, - value: value.as_ref().map(|value| self.mirror_expr(value)), + value: value.map(|value| self.mirror_expr(value)), }, Err(err) => bug!("invalid loop id for break: {}", err), }, @@ -703,7 +704,7 @@ impl<'tcx> Cx<'tcx> { hir::ExprKind::Field(ref source, ..) => ExprKind::Field { lhs: self.mirror_expr(source), variant_index: VariantIdx::new(0), - name: Field::new(tcx.field_index(expr.hir_id, self.typeck_results)), + name: Field::new(self.typeck_results.field_index(expr.hir_id)), }, hir::ExprKind::Cast(ref source, ref cast_ty) => { // Check for a user-given type annotation on this `cast` @@ -802,12 +803,12 @@ impl<'tcx> Cx<'tcx> { &mut self, expr: &hir::Expr<'_>, span: Span, - overloaded_callee: Option<(DefId, SubstsRef<'tcx>)>, + overloaded_callee: Option>, ) -> Expr<'tcx> { let temp_lifetime = self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id); - let (def_id, substs, user_ty) = match overloaded_callee { - Some((def_id, substs)) => (def_id, substs, None), + let (ty, user_ty) = match overloaded_callee { + Some(fn_def) => (fn_def, None), None => { let (kind, def_id) = self.typeck_results().type_dependent_def(expr.hir_id).unwrap_or_else(|| { @@ -815,10 +816,12 @@ impl<'tcx> Cx<'tcx> { }); let user_ty = self.user_substs_applied_to_res(expr.hir_id, Res::Def(kind, def_id)); debug!("method_callee: user_ty={:?}", user_ty); - (def_id, self.typeck_results().node_substs(expr.hir_id), user_ty) + ( + self.tcx().mk_fn_def(def_id, self.typeck_results().node_substs(expr.hir_id)), + user_ty, + ) } }; - let ty = self.tcx().mk_fn_def(def_id, substs); Expr { temp_lifetime, ty, span, kind: ExprKind::ZstLiteral { user_ty } } } @@ -853,9 +856,7 @@ impl<'tcx> Cx<'tcx> { Res::Def(DefKind::ConstParam, def_id) => { let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); - let item_id = self.tcx.hir().get_parent_node(hir_id); - let item_def_id = self.tcx.hir().local_def_id(item_id); - let generics = self.tcx.generics_of(item_def_id); + let generics = self.tcx.generics_of(hir_id.owner); let index = generics.param_def_id_to_index[&def_id]; let name = self.tcx.hir().name(hir_id); let param = ty::ParamConst::new(index, name); @@ -955,7 +956,7 @@ impl<'tcx> Cx<'tcx> { &mut self, expr: &'tcx hir::Expr<'tcx>, place_ty: Ty<'tcx>, - overloaded_callee: Option<(DefId, SubstsRef<'tcx>)>, + overloaded_callee: Option>, args: Box<[ExprId]>, span: Span, ) -> ExprKind<'tcx> { @@ -1078,7 +1079,7 @@ impl<'tcx> Cx<'tcx> { fields .iter() .map(|field| FieldExpr { - name: Field::new(self.tcx.field_index(field.hir_id, self.typeck_results)), + name: Field::new(self.typeck_results.field_index(field.hir_id)), expr: self.mirror_expr(field.expr), }) .collect() diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 1d95d6b53..b5c4b7b13 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -80,6 +80,9 @@ struct Cx<'tcx> { /// for the receiver. adjustment_span: Option<(HirId, Span)>, + /// False to indicate that adjustments should not be applied. Only used for `custom_mir` + apply_adjustments: bool, + /// The `DefId` of the owner of this body. body_owner: DefId, } @@ -87,6 +90,8 @@ struct Cx<'tcx> { impl<'tcx> Cx<'tcx> { fn new(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam) -> Cx<'tcx> { let typeck_results = tcx.typeck_opt_const_arg(def); + let did = def.did; + let hir = tcx.hir(); Cx { tcx, thir: Thir::new(), @@ -94,8 +99,12 @@ impl<'tcx> Cx<'tcx> { region_scope_tree: tcx.region_scope_tree(def.did), typeck_results, rvalue_scopes: &typeck_results.rvalue_scopes, - body_owner: def.did.to_def_id(), + body_owner: did.to_def_id(), adjustment_span: None, + apply_adjustments: hir + .attrs(hir.local_def_id_to_hir_id(did)) + .iter() + .all(|attr| attr.name_or_empty() != rustc_span::sym::custom_mir), } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 858129c74..e369dba55 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -79,7 +79,10 @@ impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, '_, 'tcx> { intravisit::walk_local(self, loc); let els = loc.els; if let Some(init) = loc.init && els.is_some() { - self.check_let(&loc.pat, init, loc.span); + // Build a span without the else { ... } as we don't want to underline + // the entire else block in the IDE setting. + let span = loc.span.with_hi(init.span.hi()); + self.check_let(&loc.pat, init, span); } let (msg, sp) = match loc.source { @@ -507,7 +510,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { _ => "aren't", }, ), - " else { todo!() }".to_string(), + " else { todo!() }", Applicability::HasPlaceholders, ); } @@ -561,7 +564,7 @@ fn check_for_bindings_named_same_as_variants( && let ty::Adt(edef, _) = pat_ty.kind() && edef.is_enum() && edef.variants().iter().any(|variant| { - variant.ident(cx.tcx) == ident && variant.ctor_kind == CtorKind::Const + variant.ident(cx.tcx) == ident && variant.ctor_kind() == Some(CtorKind::Const) }) { let variant_count = edef.variants().len(); @@ -630,11 +633,6 @@ fn irrefutable_let_patterns( count: usize, span: Span, ) { - let span = match source { - LetSource::LetElse(span) => span, - _ => span, - }; - macro_rules! emit_diag { ( $lint:expr, @@ -680,7 +678,7 @@ fn irrefutable_let_patterns( "removing the guard and adding a `let` inside the match arm" ); } - LetSource::LetElse(..) => { + LetSource::LetElse => { emit_diag!( lint, "`let...else`", @@ -820,7 +818,7 @@ fn non_exhaustive_match<'p, 'tcx>( } } if let ty::Ref(_, sub_ty, _) = scrut_ty.kind() { - if cx.tcx.is_ty_uninhabited_from(cx.module, *sub_ty, cx.param_env) { + if !sub_ty.is_inhabited_from(cx.tcx, cx.module, cx.param_env) { err.note("references are always considered inhabited"); } } @@ -1046,11 +1044,19 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa name, typeck_results.node_type(pat.hir_id), ); - sess.struct_span_err(pat.span, "borrow of moved value") - .span_label(binding_span, format!("value moved into `{}` here", name)) + let mut err = sess.struct_span_err(pat.span, "borrow of moved value"); + err.span_label(binding_span, format!("value moved into `{}` here", name)) .span_label(binding_span, occurs_because) - .span_labels(conflicts_ref, "value borrowed here after move") - .emit(); + .span_labels(conflicts_ref, "value borrowed here after move"); + if pat.span.contains(binding_span) { + err.span_suggestion_verbose( + binding_span.shrink_to_lo(), + "borrow this binding in the pattern to avoid moving the value", + "ref ".to_string(), + Applicability::MachineApplicable, + ); + } + err.emit(); } return; } @@ -1127,7 +1133,7 @@ pub enum LetSource { GenericLet, IfLet, IfLetGuard, - LetElse(Span), + LetElse, WhileLet, } @@ -1156,8 +1162,8 @@ fn let_source_parent(tcx: TyCtxt<'_>, parent: HirId, pat_id: Option) -> L let parent_parent = hir.get_parent_node(parent); let parent_parent_node = hir.get(parent_parent); match parent_parent_node { - hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(_), span, .. }) => { - return LetSource::LetElse(*span); + hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(_), .. }) => { + return LetSource::LetElse; } hir::Node::Arm(hir::Arm { guard: Some(hir::Guard::If(_)), .. }) => { return LetSource::IfLetGuard; diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index ad12e0116..a21f6cd39 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -232,8 +232,7 @@ impl<'tcx> ConstToPat<'tcx> { ObligationCause::misc(self.span, self.id), partial_eq_trait_id, 0, - ty, - &[], + [ty, ty], ); // FIXME: should this call a `predicate_must_hold` variant instead? diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index 595abc8f6..d60e8722c 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -42,16 +42,17 @@ //! wildcards, see [`SplitWildcard`]; for integer ranges, see [`SplitIntRange`]; for slices, see //! [`SplitVarLenSlice`]. -use self::Constructor::*; -use self::SliceKind::*; +use std::cell::Cell; +use std::cmp::{self, max, min, Ordering}; +use std::fmt; +use std::iter::{once, IntoIterator}; +use std::ops::RangeInclusive; -use super::compare_const_vals; -use super::usefulness::{MatchCheckCtxt, PatCtxt}; +use smallvec::{smallvec, SmallVec}; use rustc_data_structures::captures::Captures; -use rustc_index::vec::Idx; - use rustc_hir::{HirId, RangeEnd}; +use rustc_index::vec::Idx; use rustc_middle::mir::{self, Field}; use rustc_middle::thir::{FieldPat, Pat, PatKind, PatRange}; use rustc_middle::ty::layout::IntegerExt; @@ -61,12 +62,11 @@ use rustc_session::lint; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::{Integer, Size, VariantIdx}; -use smallvec::{smallvec, SmallVec}; -use std::cell::Cell; -use std::cmp::{self, max, min, Ordering}; -use std::fmt; -use std::iter::{once, IntoIterator}; -use std::ops::RangeInclusive; +use self::Constructor::*; +use self::SliceKind::*; + +use super::compare_const_vals; +use super::usefulness::{MatchCheckCtxt, PatCtxt}; /// Recursively expand this pattern into its subpatterns. Only useful for or-patterns. fn expand_or_pat<'p, 'tcx>(pat: &'p Pat<'tcx>) -> Vec<&'p Pat<'tcx>> { @@ -147,11 +147,7 @@ impl IntRange { // straight to the result, after doing a bit of checking. (We // could remove this branch and just fall through, which // is more general but much slower.) - if let Ok(Ok(bits)) = scalar.to_bits_or_ptr_internal(target_size) { - return Some(bits); - } else { - return None; - } + return scalar.to_bits_or_ptr_internal(target_size).unwrap().left(); } mir::ConstantKind::Ty(c) => match c.kind() { ty::ConstKind::Value(_) => bug!( diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 2526522a2..48a231a6c 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -216,7 +216,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let lo = lo_expr.map(|e| self.lower_range_expr(e)); let hi = hi_expr.map(|e| self.lower_range_expr(e)); - let (lp, hp) = (lo.as_ref().map(|x| &x.0), hi.as_ref().map(|x| &x.0)); + let (lp, hp) = (lo.as_ref().map(|(x, _)| x), hi.as_ref().map(|(x, _)| x)); let mut kind = match self.normalize_range_pattern_ends(ty, lp, hp) { Some((lc, hc)) => self.lower_pattern_range(ty, lc, hc, end, lo_span), None => { @@ -321,7 +321,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let subpatterns = fields .iter() .map(|field| FieldPat { - field: Field::new(self.tcx.field_index(field.hir_id, self.typeck_results)), + field: Field::new(self.typeck_results.field_index(field.hir_id)), pattern: self.lower_pattern(&field.pat), }) .collect(); @@ -358,7 +358,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { &mut self, pat: &'tcx Option<&'tcx hir::Pat<'tcx>>, ) -> Option>> { - pat.as_ref().map(|p| self.lower_pattern(p)) + pat.map(|p| self.lower_pattern(p)) } fn slice_or_array_pattern( @@ -565,8 +565,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { id: hir::HirId, span: Span, ) -> PatKind<'tcx> { - let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id); - let value = mir::ConstantKind::from_inline_const(self.tcx, anon_const_def_id); + let value = mir::ConstantKind::from_inline_const(self.tcx, anon_const.def_id); // Evaluate early like we do in `lower_path`. let value = value.eval(self.tcx, self.param_env); @@ -577,6 +576,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { self.errors.push(PatternError::ConstParamInPattern(span)); return PatKind::Wild; } + ConstKind::Error(_) => { + return PatKind::Wild; + } _ => bug!("Expected ConstKind::Param"), }, mir::ConstantKind::Val(_, _) => self.const_to_pat(value, id, span, false).kind, @@ -614,7 +616,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { LitToConstInput { lit: &lit.node, ty: self.typeck_results.expr_ty(expr), neg }; match self.tcx.at(expr.span).lit_to_mir_constant(lit_input) { Ok(constant) => self.const_to_pat(constant, expr.hir_id, lit.span, false).kind, - Err(LitToConstError::Reported) => PatKind::Wild, + Err(LitToConstError::Reported(_)) => PatKind::Wild, Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"), } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs index 8dc9976ea..3e370a053 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs @@ -324,7 +324,7 @@ pub(crate) struct MatchCheckCtxt<'p, 'tcx> { impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> { pub(super) fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool { if self.tcx.features().exhaustive_patterns { - self.tcx.is_ty_uninhabited_from(self.module, ty, self.param_env) + !ty.is_inhabited_from(self.tcx, self.module, self.param_env) } else { false } -- cgit v1.2.3