From dc0db358abe19481e475e10c32149b53370f1a1c Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 30 May 2024 05:57:31 +0200 Subject: Merging upstream version 1.72.1+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_middle/src/mir/syntax.rs | 100 +++++++++++++++++++++++--------- 1 file changed, 72 insertions(+), 28 deletions(-) (limited to 'compiler/rustc_middle/src/mir/syntax.rs') diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 3e474c1d3..7f1d38203 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -7,7 +7,7 @@ use super::{BasicBlock, Constant, Local, SwitchTargets, UserTypeProjection}; use crate::mir::coverage::{CodeRegion, CoverageKind}; use crate::traits::Reveal; -use crate::ty::adjustment::PointerCast; +use crate::ty::adjustment::PointerCoercion; use crate::ty::subst::SubstsRef; use crate::ty::{self, List, Ty}; use crate::ty::{Region, UserTypeAnnotationIndex}; @@ -182,6 +182,16 @@ pub enum BorrowKind { /// We can also report errors with this kind of borrow differently. Shallow, + /// Data is mutable and not aliasable. + Mut { kind: MutBorrowKind }, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, TyEncodable, TyDecodable)] +#[derive(Hash, HashStable)] +pub enum MutBorrowKind { + Default, + /// This borrow arose from method-call auto-ref. (i.e., `adjustment::Adjust::Borrow`) + TwoPhaseBorrow, /// Data must be immutable but not aliasable. This kind of borrow /// cannot currently be expressed by the user and is used only in /// implicit closure bindings. It is needed when the closure is @@ -216,23 +226,14 @@ pub enum BorrowKind { /// user code, if awkward, but extra weird for closures, since the /// borrow is hidden. /// - /// So we introduce a "unique imm" borrow -- the referent is - /// immutable, but not aliasable. This solves the problem. For - /// simplicity, we don't give users the way to express this - /// borrow, it's just used when translating closures. + /// So we introduce a `ClosureCapture` borrow -- user will not have to mark the variable + /// containing the mutable reference as `mut`, as they didn't ever + /// intend to mutate the mutable reference itself. We still mutable capture it in order to + /// mutate the pointed value through it (but not mutating the reference itself). /// - // FIXME(#112072): This is wrong. Unique borrows are mutable borrows except - // that they do not require their pointee to be marked as a mutable. - // They should still be treated as mutable borrows in every other way, - // e.g. for variance or overlap checking. - Unique, - - /// Data is mutable and not aliasable. - Mut { - /// `true` if this borrow arose from method-call auto-ref - /// (i.e., `adjustment::Adjust::Borrow`). - allow_two_phase_borrow: bool, - }, + /// This solves the problem. For simplicity, we don't give users the way to express this + /// borrow, it's just used when translating closures. + ClosureCapture, } /////////////////////////////////////////////////////////////////////////// @@ -512,6 +513,31 @@ pub struct CopyNonOverlapping<'tcx> { pub count: Operand<'tcx>, } +/// Represents how a `TerminatorKind::Call` was constructed, used for diagnostics +#[derive(Clone, Copy, TyEncodable, TyDecodable, Debug, PartialEq, Hash, HashStable)] +#[derive(TypeFoldable, TypeVisitable)] +pub enum CallSource { + /// This came from something such as `a > b` or `a + b`. In THIR, if `from_hir_call` + /// is false then this is the desugaring. + OverloadedOperator, + /// This was from comparison generated by a match, used by const-eval for better errors + /// when the comparison cannot be done in compile time. + /// + /// (see ) + MatchCmp, + /// Other types of desugaring that did not come from the HIR, but we don't care about + /// for diagnostics (yet). + Misc, + /// Normal function call, no special source + Normal, +} + +impl CallSource { + pub fn from_hir_call(self) -> bool { + matches!(self, CallSource::Normal) + } +} + /////////////////////////////////////////////////////////////////////////// // Terminators @@ -638,11 +664,10 @@ pub enum TerminatorKind<'tcx> { target: Option, /// Action to be taken if the call unwinds. unwind: UnwindAction, - /// `true` if this is from a call in HIR rather than from an overloaded - /// operator. True for overloaded function call. - from_hir_call: bool, + /// Where this call came from in HIR/THIR. + call_source: CallSource, /// This `Span` is the span of the function, without the dot and receiver - /// (e.g. `foo(a, b)` in `x.foo(a, b)` + /// e.g. `foo(a, b)` in `x.foo(a, b)` fn_span: Span, }, @@ -801,7 +826,8 @@ pub enum UnwindAction { } /// Information about an assertion failure. -#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, TypeFoldable, TypeVisitable)] +#[derive(Clone, Hash, HashStable, PartialEq, Debug)] +#[derive(TyEncodable, TyDecodable, TypeFoldable, TypeVisitable)] pub enum AssertKind { BoundsCheck { len: O, index: O }, Overflow(BinOp, O, O), @@ -1204,9 +1230,9 @@ pub enum CastKind { /// An address-to-pointer cast that picks up an exposed provenance. /// See the docs on `from_exposed_addr` for more details. PointerFromExposedAddress, - /// All sorts of pointer-to-pointer casts. Note that reference-to-raw-ptr casts are + /// Pointer related casts that are done by coercions. Note that reference-to-raw-ptr casts are /// translated into `&raw mut/const *r`, i.e., they are not actually casts. - Pointer(PointerCast), + PointerCoercion(PointerCoercion), /// Cast into a dyn* object. DynStar, IntToInt, @@ -1266,19 +1292,30 @@ pub enum UnOp { pub enum BinOp { /// The `+` operator (addition) Add, + /// Like `Add`, but with UB on overflow. (Integers only.) + AddUnchecked, /// The `-` operator (subtraction) Sub, + /// Like `Sub`, but with UB on overflow. (Integers only.) + SubUnchecked, /// The `*` operator (multiplication) Mul, + /// Like `Mul`, but with UB on overflow. (Integers only.) + MulUnchecked, /// The `/` operator (division) /// - /// Division by zero is UB, because the compiler should have inserted checks - /// prior to this. + /// For integer types, division by zero is UB, as is `MIN / -1` for signed. + /// The compiler should have inserted checks prior to this. + /// + /// Floating-point division by zero is safe, and does not need guards. Div, /// The `%` operator (modulus) /// - /// Using zero as the modulus (second operand) is UB, because the compiler - /// should have inserted checks prior to this. + /// For integer types, using zero as the modulus (second operand) is UB, + /// as is `MIN % -1` for signed. + /// The compiler should have inserted checks prior to this. + /// + /// Floating-point remainder by zero is safe, and does not need guards. Rem, /// The `^` operator (bitwise xor) BitXor, @@ -1290,10 +1327,17 @@ pub enum BinOp { /// /// The offset is truncated to the size of the first operand before shifting. Shl, + /// Like `Shl`, but is UB if the RHS >= LHS::BITS + ShlUnchecked, /// The `>>` operator (shift right) /// /// The offset is truncated to the size of the first operand before shifting. + /// + /// This is an arithmetic shift if the LHS is signed + /// and a logical shift if the LHS is unsigned. Shr, + /// Like `Shl`, but is UB if the RHS >= LHS::BITS + ShrUnchecked, /// The `==` operator (equality) Eq, /// The `<` operator (less than) -- cgit v1.2.3