mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-16 17:03:35 +00:00
Auto merge of #110967 - matthiaskrgr:rollup-vfbl7gm, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #110877 (Provide better type hints when a type doesn't support a binary operator) - #110917 (only error combining +whole-archive and +bundle for rlibs) - #110921 (Use `NonNull::new_unchecked` and `NonNull::len` in `rustc_arena`.) - #110927 (Encoder/decoder cleanups) - #110944 (share BinOp::Offset between CTFE and Miri) - #110948 (run-make test: using single quotes to not trigger the shell) - #110957 (Fix an ICE in conflict error diagnostics) - #110960 (fix false negative for `unused_mut`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
7a96158b53
@ -74,7 +74,7 @@ impl<T> ArenaChunk<T> {
|
||||
#[inline]
|
||||
unsafe fn new(capacity: usize) -> ArenaChunk<T> {
|
||||
ArenaChunk {
|
||||
storage: NonNull::new(Box::into_raw(Box::new_uninit_slice(capacity))).unwrap(),
|
||||
storage: NonNull::new_unchecked(Box::into_raw(Box::new_uninit_slice(capacity))),
|
||||
entries: 0,
|
||||
}
|
||||
}
|
||||
@ -85,7 +85,7 @@ impl<T> ArenaChunk<T> {
|
||||
// The branch on needs_drop() is an -O1 performance optimization.
|
||||
// Without the branch, dropping TypedArena<u8> takes linear time.
|
||||
if mem::needs_drop::<T>() {
|
||||
let slice = &mut *(self.storage.as_mut());
|
||||
let slice = self.storage.as_mut();
|
||||
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(&mut slice[..len]));
|
||||
}
|
||||
}
|
||||
@ -104,7 +104,7 @@ impl<T> ArenaChunk<T> {
|
||||
// A pointer as large as possible for zero-sized elements.
|
||||
ptr::invalid_mut(!0)
|
||||
} else {
|
||||
self.start().add((*self.storage.as_ptr()).len())
|
||||
self.start().add(self.storage.len())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -288,7 +288,7 @@ impl<T> TypedArena<T> {
|
||||
// If the previous chunk's len is less than HUGE_PAGE
|
||||
// bytes, then this chunk will be least double the previous
|
||||
// chunk's size.
|
||||
new_cap = (*last_chunk.storage.as_ptr()).len().min(HUGE_PAGE / elem_size / 2);
|
||||
new_cap = last_chunk.storage.len().min(HUGE_PAGE / elem_size / 2);
|
||||
new_cap *= 2;
|
||||
} else {
|
||||
new_cap = PAGE / elem_size;
|
||||
@ -396,7 +396,7 @@ impl DroplessArena {
|
||||
// If the previous chunk's len is less than HUGE_PAGE
|
||||
// bytes, then this chunk will be least double the previous
|
||||
// chunk's size.
|
||||
new_cap = (*last_chunk.storage.as_ptr()).len().min(HUGE_PAGE / 2);
|
||||
new_cap = last_chunk.storage.len().min(HUGE_PAGE / 2);
|
||||
new_cap *= 2;
|
||||
} else {
|
||||
new_cap = PAGE;
|
||||
|
@ -360,7 +360,7 @@ impl Printer {
|
||||
|
||||
fn check_stack(&mut self, mut depth: usize) {
|
||||
while let Some(&index) = self.scan_stack.back() {
|
||||
let mut entry = &mut self.buf[index];
|
||||
let entry = &mut self.buf[index];
|
||||
match entry.token {
|
||||
Token::Begin(_) => {
|
||||
if depth == 0 {
|
||||
|
@ -1359,7 +1359,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
}
|
||||
|
||||
// Get closure's arguments
|
||||
let ty::Closure(_, substs) = typeck_results.expr_ty(closure_expr).kind() else { unreachable!() };
|
||||
let ty::Closure(_, substs) = typeck_results.expr_ty(closure_expr).kind() else { /* hir::Closure can be a generator too */ return };
|
||||
let sig = substs.as_closure().sig();
|
||||
let tupled_params =
|
||||
tcx.erase_late_bound_regions(sig.inputs().iter().next().unwrap().map_bound(|&b| b));
|
||||
|
@ -935,6 +935,7 @@ enum InitializationRequiringAction {
|
||||
PartialAssignment,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct RootPlace<'tcx> {
|
||||
place_local: Local,
|
||||
place_projection: &'tcx [PlaceElem<'tcx>],
|
||||
@ -1848,11 +1849,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
// is allowed, remove this match arm.
|
||||
ty::Adt(..) | ty::Tuple(..) => {
|
||||
check_parent_of_field(self, location, place_base, span, flow_state);
|
||||
|
||||
// rust-lang/rust#21232, #54499, #54986: during period where we reject
|
||||
// partial initialization, do not complain about unnecessary `mut` on
|
||||
// an attempt to do a partial initialization.
|
||||
self.used_mut.insert(place.local);
|
||||
}
|
||||
|
||||
_ => {}
|
||||
@ -1940,6 +1936,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
(prefix, base, span),
|
||||
mpi,
|
||||
);
|
||||
|
||||
// rust-lang/rust#21232, #54499, #54986: during period where we reject
|
||||
// partial initialization, do not complain about unnecessary `mut` on
|
||||
// an attempt to do a partial initialization.
|
||||
this.used_mut.insert(base.local);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -221,7 +221,7 @@ fn append_list(
|
||||
) {
|
||||
let mut p = target_list;
|
||||
loop {
|
||||
let mut r = &mut constraints[p];
|
||||
let r = &mut constraints[p];
|
||||
match r.next_constraint {
|
||||
Some(q) => p = q,
|
||||
None => {
|
||||
|
@ -349,7 +349,10 @@ fn link_rlib<'a>(
|
||||
let NativeLibKind::Static { bundle: None | Some(true), whole_archive } = lib.kind else {
|
||||
continue;
|
||||
};
|
||||
if whole_archive == Some(true) && !codegen_results.crate_info.feature_packed_bundled_libs {
|
||||
if whole_archive == Some(true)
|
||||
&& flavor == RlibFlavor::Normal
|
||||
&& !codegen_results.crate_info.feature_packed_bundled_libs
|
||||
{
|
||||
sess.emit_err(errors::IncompatibleLinkingModifiers);
|
||||
}
|
||||
if flavor == RlibFlavor::Normal && let Some(filename) = lib.filename {
|
||||
|
@ -559,20 +559,11 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
||||
}
|
||||
|
||||
fn binary_ptr_op(
|
||||
ecx: &InterpCx<'mir, 'tcx, Self>,
|
||||
bin_op: mir::BinOp,
|
||||
left: &ImmTy<'tcx>,
|
||||
right: &ImmTy<'tcx>,
|
||||
_ecx: &InterpCx<'mir, 'tcx, Self>,
|
||||
_bin_op: mir::BinOp,
|
||||
_left: &ImmTy<'tcx>,
|
||||
_right: &ImmTy<'tcx>,
|
||||
) -> InterpResult<'tcx, (Scalar, bool, Ty<'tcx>)> {
|
||||
if bin_op == mir::BinOp::Offset {
|
||||
let ptr = left.to_scalar().to_pointer(ecx)?;
|
||||
let offset_count = right.to_scalar().to_target_isize(ecx)?;
|
||||
let pointee_ty = left.layout.ty.builtin_deref(true).unwrap().ty;
|
||||
|
||||
let offset_ptr = ecx.ptr_offset_inbounds(ptr, pointee_ty, offset_count)?;
|
||||
return Ok((Scalar::from_maybe_pointer(offset_ptr, ecx), false, left.layout.ty));
|
||||
}
|
||||
|
||||
throw_unsup_format!("pointer arithmetic or comparison is not supported at compile-time");
|
||||
}
|
||||
|
||||
|
@ -299,6 +299,30 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
Ok((val, false, ty))
|
||||
}
|
||||
|
||||
fn binary_ptr_op(
|
||||
&self,
|
||||
bin_op: mir::BinOp,
|
||||
left: &ImmTy<'tcx, M::Provenance>,
|
||||
right: &ImmTy<'tcx, M::Provenance>,
|
||||
) -> InterpResult<'tcx, (Scalar<M::Provenance>, bool, Ty<'tcx>)> {
|
||||
use rustc_middle::mir::BinOp::*;
|
||||
|
||||
match bin_op {
|
||||
// Pointer ops that are always supported.
|
||||
Offset => {
|
||||
let ptr = left.to_scalar().to_pointer(self)?;
|
||||
let offset_count = right.to_scalar().to_target_isize(self)?;
|
||||
let pointee_ty = left.layout.ty.builtin_deref(true).unwrap().ty;
|
||||
|
||||
let offset_ptr = self.ptr_offset_inbounds(ptr, pointee_ty, offset_count)?;
|
||||
Ok((Scalar::from_maybe_pointer(offset_ptr, self), false, left.layout.ty))
|
||||
}
|
||||
|
||||
// Fall back to machine hook so Miri can support more pointer ops.
|
||||
_ => M::binary_ptr_op(self, bin_op, left, right),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the result of the specified operation, whether it overflowed, and
|
||||
/// the result type.
|
||||
pub fn overflowing_binary_op(
|
||||
@ -368,7 +392,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
right.layout.ty
|
||||
);
|
||||
|
||||
M::binary_ptr_op(self, bin_op, left, right)
|
||||
self.binary_ptr_op(bin_op, left, right)
|
||||
}
|
||||
_ => span_bug!(
|
||||
self.cur_span(),
|
||||
|
@ -26,7 +26,7 @@ use rustc_target::spec::abi::Abi;
|
||||
use smallvec::SmallVec;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug, Copy, Clone, Encodable, HashStable_Generic)]
|
||||
#[derive(Debug, Copy, Clone, HashStable_Generic)]
|
||||
pub struct Lifetime {
|
||||
pub hir_id: HirId,
|
||||
|
||||
@ -41,8 +41,7 @@ pub struct Lifetime {
|
||||
pub res: LifetimeName,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Encodable, Hash, Copy)]
|
||||
#[derive(HashStable_Generic)]
|
||||
#[derive(Debug, Copy, Clone, HashStable_Generic)]
|
||||
pub enum ParamName {
|
||||
/// Some user-given name like `T` or `'x`.
|
||||
Plain(Ident),
|
||||
@ -85,8 +84,7 @@ impl ParamName {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Encodable, Hash, Copy)]
|
||||
#[derive(HashStable_Generic)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)]
|
||||
pub enum LifetimeName {
|
||||
/// User-given names or fresh (synthetic) names.
|
||||
Param(LocalDefId),
|
||||
@ -243,13 +241,13 @@ impl<'hir> PathSegment<'hir> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Encodable, Clone, Copy, Debug, HashStable_Generic)]
|
||||
#[derive(Clone, Copy, Debug, HashStable_Generic)]
|
||||
pub struct ConstArg {
|
||||
pub value: AnonConst,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Encodable, Clone, Copy, Debug, HashStable_Generic)]
|
||||
#[derive(Clone, Copy, Debug, HashStable_Generic)]
|
||||
pub struct InferArg {
|
||||
pub hir_id: HirId,
|
||||
pub span: Span,
|
||||
@ -422,8 +420,7 @@ impl<'hir> GenericArgs<'hir> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Hash, Debug)]
|
||||
#[derive(HashStable_Generic)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable_Generic)]
|
||||
pub enum GenericArgsParentheses {
|
||||
No,
|
||||
/// Bounds for `feature(return_type_notation)`, like `T: Trait<method(..): Send>`,
|
||||
@ -435,8 +432,7 @@ pub enum GenericArgsParentheses {
|
||||
|
||||
/// A modifier on a bound, currently this is only used for `?Sized`, where the
|
||||
/// modifier is `Maybe`. Negative bounds should also be handled here.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Hash, Debug)]
|
||||
#[derive(HashStable_Generic)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
|
||||
pub enum TraitBoundModifier {
|
||||
None,
|
||||
Maybe,
|
||||
@ -474,7 +470,7 @@ impl GenericBound<'_> {
|
||||
|
||||
pub type GenericBounds<'hir> = &'hir [GenericBound<'hir>];
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStable_Generic)]
|
||||
#[derive(Copy, Clone, Debug, HashStable_Generic)]
|
||||
pub enum LifetimeParamKind {
|
||||
// Indicates that the lifetime definition was explicitly declared (e.g., in
|
||||
// `fn foo<'a>(x: &'a u8) -> &'a u8 { x }`).
|
||||
@ -539,7 +535,7 @@ impl<'hir> GenericParam<'hir> {
|
||||
/// early-bound (but can be a late-bound lifetime in functions, for example),
|
||||
/// or from a `for<...>` binder, in which case it's late-bound (and notably,
|
||||
/// does not show up in the parent item's generics).
|
||||
#[derive(Debug, HashStable_Generic, PartialEq, Eq, Copy, Clone)]
|
||||
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||
pub enum GenericParamSource {
|
||||
// Early or late-bound parameters defined on an item
|
||||
Generics,
|
||||
@ -1097,7 +1093,7 @@ pub struct PatField<'hir> {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
|
||||
#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
|
||||
pub enum RangeEnd {
|
||||
Included,
|
||||
Excluded,
|
||||
@ -1197,7 +1193,7 @@ pub enum PatKind<'hir> {
|
||||
Slice(&'hir [Pat<'hir>], Option<&'hir Pat<'hir>>, &'hir [Pat<'hir>]),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
|
||||
#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
|
||||
pub enum BinOpKind {
|
||||
/// The `+` operator (addition).
|
||||
Add,
|
||||
@ -1325,7 +1321,7 @@ impl Into<ast::BinOpKind> for BinOpKind {
|
||||
|
||||
pub type BinOp = Spanned<BinOpKind>;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
|
||||
#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
|
||||
pub enum UnOp {
|
||||
/// The `*` operator (dereferencing).
|
||||
Deref,
|
||||
@ -1450,19 +1446,19 @@ pub struct ExprField<'hir> {
|
||||
pub is_shorthand: bool,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
|
||||
#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
|
||||
pub enum BlockCheckMode {
|
||||
DefaultBlock,
|
||||
UnsafeBlock(UnsafeSource),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
|
||||
#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
|
||||
pub enum UnsafeSource {
|
||||
CompilerGenerated,
|
||||
UserProvided,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub struct BodyId {
|
||||
pub hir_id: HirId,
|
||||
}
|
||||
@ -1506,7 +1502,7 @@ impl<'hir> Body<'hir> {
|
||||
}
|
||||
|
||||
/// The type of source expression that caused this generator to be created.
|
||||
#[derive(Clone, PartialEq, PartialOrd, Eq, Hash, Debug, Copy)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash)]
|
||||
#[derive(HashStable_Generic, Encodable, Decodable)]
|
||||
pub enum GeneratorKind {
|
||||
/// An explicit `async` block or the body of an async function.
|
||||
@ -1539,7 +1535,7 @@ impl GeneratorKind {
|
||||
///
|
||||
/// This helps error messages but is also used to drive coercions in
|
||||
/// type-checking (see #60424).
|
||||
#[derive(Clone, PartialEq, PartialOrd, Eq, Hash, Debug, Copy)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Debug, Copy)]
|
||||
#[derive(HashStable_Generic, Encodable, Decodable)]
|
||||
pub enum AsyncGeneratorKind {
|
||||
/// An explicit `async` block written by the user.
|
||||
@ -1649,7 +1645,7 @@ impl fmt::Display for ConstContext {
|
||||
/// A literal.
|
||||
pub type Lit = Spanned<LitKind>;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStable_Generic)]
|
||||
#[derive(Copy, Clone, Debug, HashStable_Generic)]
|
||||
pub enum ArrayLen {
|
||||
Infer(HirId, Span),
|
||||
Body(AnonConst),
|
||||
@ -1671,7 +1667,7 @@ impl ArrayLen {
|
||||
///
|
||||
/// You can check if this anon const is a default in a const param
|
||||
/// `const N: usize = { ... }` with `tcx.hir().opt_const_param_default_param_def_id(..)`
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStable_Generic)]
|
||||
#[derive(Copy, Clone, Debug, HashStable_Generic)]
|
||||
pub struct AnonConst {
|
||||
pub hir_id: HirId,
|
||||
pub def_id: LocalDefId,
|
||||
@ -2105,7 +2101,7 @@ impl<'hir> QPath<'hir> {
|
||||
}
|
||||
|
||||
/// Hints at the original code for a let statement.
|
||||
#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
|
||||
#[derive(Copy, Clone, Debug, HashStable_Generic)]
|
||||
pub enum LocalSource {
|
||||
/// A `match _ { .. }`.
|
||||
Normal,
|
||||
@ -2158,7 +2154,7 @@ impl MatchSource {
|
||||
}
|
||||
|
||||
/// The loop type that yielded an `ExprKind::Loop`.
|
||||
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
|
||||
#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
|
||||
pub enum LoopSource {
|
||||
/// A `loop { .. }` loop.
|
||||
Loop,
|
||||
@ -2178,7 +2174,7 @@ impl LoopSource {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
|
||||
#[derive(Copy, Clone, Debug, HashStable_Generic)]
|
||||
pub enum LoopIdError {
|
||||
OutsideLoopScope,
|
||||
UnlabeledCfInWhileCondition,
|
||||
@ -2197,7 +2193,7 @@ impl fmt::Display for LoopIdError {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
|
||||
#[derive(Copy, Clone, Debug, HashStable_Generic)]
|
||||
pub struct Destination {
|
||||
/// This is `Some(_)` iff there is an explicit user-specified 'label
|
||||
pub label: Option<Label>,
|
||||
@ -2208,7 +2204,7 @@ pub struct Destination {
|
||||
}
|
||||
|
||||
/// The yield kind that caused an `ExprKind::Yield`.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
|
||||
#[derive(Copy, Clone, Debug, HashStable_Generic)]
|
||||
pub enum YieldSource {
|
||||
/// An `<expr>.await`.
|
||||
Await { expr: Option<HirId> },
|
||||
@ -2327,7 +2323,7 @@ impl<'hir> TraitItem<'hir> {
|
||||
}
|
||||
|
||||
/// Represents a trait method's body (or just argument names).
|
||||
#[derive(Encodable, Debug, Clone, Copy, HashStable_Generic)]
|
||||
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||
pub enum TraitFn<'hir> {
|
||||
/// No default body in the trait, just a signature.
|
||||
Required(&'hir [Ident]),
|
||||
@ -2658,7 +2654,7 @@ pub struct OpaqueTy<'hir> {
|
||||
}
|
||||
|
||||
/// From whence the opaque type came.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable_Generic)]
|
||||
pub enum OpaqueTyOrigin {
|
||||
/// `-> impl Trait`
|
||||
FnReturn(LocalDefId),
|
||||
@ -2818,7 +2814,7 @@ impl ImplicitSelfKind {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
|
||||
#[derive(HashStable_Generic)]
|
||||
pub enum IsAsync {
|
||||
Async,
|
||||
@ -2831,7 +2827,7 @@ impl IsAsync {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Encodable, Decodable, HashStable_Generic)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
|
||||
pub enum Defaultness {
|
||||
Default { has_value: bool },
|
||||
Final,
|
||||
@ -2887,13 +2883,13 @@ pub enum ClosureBinder {
|
||||
For { span: Span },
|
||||
}
|
||||
|
||||
#[derive(Encodable, Debug, Clone, Copy, HashStable_Generic)]
|
||||
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||
pub struct Mod<'hir> {
|
||||
pub spans: ModSpans,
|
||||
pub item_ids: &'hir [ItemId],
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, HashStable_Generic, Encodable)]
|
||||
#[derive(Copy, Clone, Debug, HashStable_Generic)]
|
||||
pub struct ModSpans {
|
||||
/// A span from the first token past `{` to the last token until `}`.
|
||||
/// For `mod foo;`, the inner span ranges from the first token
|
||||
@ -2922,7 +2918,7 @@ pub struct Variant<'hir> {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
|
||||
#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
|
||||
pub enum UseKind {
|
||||
/// One import, e.g., `use foo::bar` or `use foo::bar as baz`.
|
||||
/// Also produced for each element of a list `use`, e.g.
|
||||
@ -3233,7 +3229,7 @@ impl fmt::Display for Unsafety {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
#[derive(Encodable, Decodable, HashStable_Generic)]
|
||||
pub enum Constness {
|
||||
Const,
|
||||
@ -3249,7 +3245,7 @@ impl fmt::Display for Constness {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
|
||||
#[derive(Copy, Clone, Debug, HashStable_Generic)]
|
||||
pub struct FnHeader {
|
||||
pub unsafety: Unsafety,
|
||||
pub constness: Constness,
|
||||
@ -3381,7 +3377,7 @@ impl ItemKind<'_> {
|
||||
/// type or method, and whether it is public). This allows other
|
||||
/// passes to find the impl they want without loading the ID (which
|
||||
/// means fewer edges in the incremental compilation graph).
|
||||
#[derive(Encodable, Debug, Clone, Copy, HashStable_Generic)]
|
||||
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||
pub struct TraitItemRef {
|
||||
pub id: TraitItemId,
|
||||
pub ident: Ident,
|
||||
@ -3405,7 +3401,7 @@ pub struct ImplItemRef {
|
||||
pub trait_item_def_id: Option<DefId>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
|
||||
#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
|
||||
pub enum AssocItemKind {
|
||||
Const,
|
||||
Fn { has_self: bool },
|
||||
@ -3474,7 +3470,7 @@ pub enum ForeignItemKind<'hir> {
|
||||
}
|
||||
|
||||
/// A variable captured by a closure.
|
||||
#[derive(Debug, Copy, Clone, Encodable, HashStable_Generic)]
|
||||
#[derive(Debug, Copy, Clone, HashStable_Generic)]
|
||||
pub struct Upvar {
|
||||
/// First span where it is accessed (there can be multiple).
|
||||
pub span: Span,
|
||||
@ -3483,7 +3479,7 @@ pub struct Upvar {
|
||||
// The TraitCandidate's import_ids is empty if the trait is defined in the same module, and
|
||||
// has length > 0 if the trait is found through an chain of imports, starting with the
|
||||
// import/use statement in the scope where the trait is used.
|
||||
#[derive(Encodable, Decodable, Debug, Clone, HashStable_Generic)]
|
||||
#[derive(Debug, Clone, HashStable_Generic)]
|
||||
pub struct TraitCandidate {
|
||||
pub def_id: DefId,
|
||||
pub import_ids: SmallVec<[LocalDefId; 1]>,
|
||||
|
@ -421,7 +421,7 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
|
||||
let target_scopes = visitor.fixup_scopes.drain(start_point..);
|
||||
|
||||
for scope in target_scopes {
|
||||
let mut yield_data =
|
||||
let yield_data =
|
||||
visitor.scope_tree.yield_in_scope.get_mut(&scope).unwrap().last_mut().unwrap();
|
||||
let count = yield_data.expr_and_pat_count;
|
||||
let span = yield_data.span;
|
||||
|
@ -455,15 +455,9 @@ fn fatally_break_rust(sess: &Session) {
|
||||
));
|
||||
}
|
||||
|
||||
fn has_expected_num_generic_args(
|
||||
tcx: TyCtxt<'_>,
|
||||
trait_did: Option<DefId>,
|
||||
expected: usize,
|
||||
) -> bool {
|
||||
trait_did.map_or(true, |trait_did| {
|
||||
let generics = tcx.generics_of(trait_did);
|
||||
generics.count() == expected + if generics.has_self { 1 } else { 0 }
|
||||
})
|
||||
fn has_expected_num_generic_args(tcx: TyCtxt<'_>, trait_did: DefId, expected: usize) -> bool {
|
||||
let generics = tcx.generics_of(trait_did);
|
||||
generics.count() == expected + if generics.has_self { 1 } else { 0 }
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
|
@ -27,8 +27,8 @@ use rustc_middle::traits::util::supertraits;
|
||||
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
|
||||
use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
|
||||
use rustc_middle::ty::print::{with_crate_prefix, with_forced_trimmed_paths};
|
||||
use rustc_middle::ty::IsSuggestable;
|
||||
use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_middle::ty::{IsSuggestable, ToPolyTraitRef};
|
||||
use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::Symbol;
|
||||
use rustc_span::{edit_distance, source_map, ExpnKind, FileName, MacroKind, Span};
|
||||
@ -2068,7 +2068,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let mut derives = Vec::<(String, Span, Symbol)>::new();
|
||||
let mut traits = Vec::new();
|
||||
for (pred, _, _) in unsatisfied_predicates {
|
||||
let ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) = pred.kind().skip_binder() else { continue };
|
||||
let Some(ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred))) =
|
||||
pred.kind().no_bound_vars()
|
||||
else {
|
||||
continue
|
||||
};
|
||||
let adt = match trait_pred.self_ty().ty_adt_def() {
|
||||
Some(adt) if adt.did().is_local() => adt,
|
||||
_ => continue,
|
||||
@ -2085,22 +2089,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
| sym::Hash
|
||||
| sym::Debug => true,
|
||||
_ => false,
|
||||
} && match trait_pred.trait_ref.substs.as_slice() {
|
||||
// Only suggest deriving if lhs == rhs...
|
||||
[lhs, rhs] => {
|
||||
if let Some(lhs) = lhs.as_type()
|
||||
&& let Some(rhs) = rhs.as_type()
|
||||
{
|
||||
self.can_eq(self.param_env, lhs, rhs)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
},
|
||||
// Unary ops can always be derived
|
||||
[_] => true,
|
||||
_ => false,
|
||||
};
|
||||
if can_derive {
|
||||
let self_name = trait_pred.self_ty().to_string();
|
||||
let self_span = self.tcx.def_span(adt.did());
|
||||
if let Some(poly_trait_ref) = pred.to_opt_poly_trait_pred() {
|
||||
for super_trait in supertraits(self.tcx, poly_trait_ref.to_poly_trait_ref())
|
||||
for super_trait in
|
||||
supertraits(self.tcx, ty::Binder::dummy(trait_pred.trait_ref))
|
||||
{
|
||||
if let Some(parent_diagnostic_name) =
|
||||
self.tcx.get_diagnostic_name(super_trait.def_id())
|
||||
{
|
||||
if let Some(parent_diagnostic_name) =
|
||||
self.tcx.get_diagnostic_name(super_trait.def_id())
|
||||
{
|
||||
derives.push((
|
||||
self_name.clone(),
|
||||
self_span,
|
||||
parent_diagnostic_name,
|
||||
));
|
||||
}
|
||||
derives.push((self_name.clone(), self_span, parent_diagnostic_name));
|
||||
}
|
||||
}
|
||||
derives.push((self_name, self_span, diagnostic_name));
|
||||
|
@ -408,7 +408,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
};
|
||||
|
||||
let is_compatible = |lhs_ty, rhs_ty| {
|
||||
let is_compatible_after_call = |lhs_ty, rhs_ty| {
|
||||
self.lookup_op_method(
|
||||
lhs_ty,
|
||||
Some((rhs_expr, rhs_ty)),
|
||||
@ -416,6 +416,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
expected,
|
||||
)
|
||||
.is_ok()
|
||||
// Suggest calling even if, after calling, the types don't
|
||||
// implement the operator, since it'll lead to better
|
||||
// diagnostics later.
|
||||
|| self.can_eq(self.param_env, lhs_ty, rhs_ty)
|
||||
};
|
||||
|
||||
// We should suggest `a + b` => `*a + b` if `a` is copy, and suggest
|
||||
@ -436,16 +440,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
suggest_deref_binop(*lhs_deref_ty);
|
||||
}
|
||||
} else if self.suggest_fn_call(&mut err, lhs_expr, lhs_ty, |lhs_ty| {
|
||||
is_compatible(lhs_ty, rhs_ty)
|
||||
is_compatible_after_call(lhs_ty, rhs_ty)
|
||||
}) || self.suggest_fn_call(&mut err, rhs_expr, rhs_ty, |rhs_ty| {
|
||||
is_compatible(lhs_ty, rhs_ty)
|
||||
is_compatible_after_call(lhs_ty, rhs_ty)
|
||||
}) || self.suggest_two_fn_call(
|
||||
&mut err,
|
||||
rhs_expr,
|
||||
rhs_ty,
|
||||
lhs_expr,
|
||||
lhs_ty,
|
||||
|lhs_ty, rhs_ty| is_compatible(lhs_ty, rhs_ty),
|
||||
|lhs_ty, rhs_ty| is_compatible_after_call(lhs_ty, rhs_ty),
|
||||
) {
|
||||
// Cool
|
||||
}
|
||||
@ -719,7 +723,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
Op::Binary(op, _) => op.span,
|
||||
Op::Unary(_, span) => span,
|
||||
};
|
||||
let (opname, trait_did) = lang_item_for_op(self.tcx, op, span);
|
||||
let (opname, Some(trait_did)) = lang_item_for_op(self.tcx, op, span) else {
|
||||
// Bail if the operator trait is not defined.
|
||||
return Err(vec![]);
|
||||
};
|
||||
|
||||
debug!(
|
||||
"lookup_op_method(lhs_ty={:?}, op={:?}, opname={:?}, trait_did={:?})",
|
||||
@ -759,18 +766,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
},
|
||||
);
|
||||
|
||||
let method = trait_did.and_then(|trait_did| {
|
||||
self.lookup_method_in_trait(cause.clone(), opname, trait_did, lhs_ty, Some(input_types))
|
||||
});
|
||||
|
||||
match (method, trait_did) {
|
||||
(Some(ok), _) => {
|
||||
let method = self.lookup_method_in_trait(
|
||||
cause.clone(),
|
||||
opname,
|
||||
trait_did,
|
||||
lhs_ty,
|
||||
Some(input_types),
|
||||
);
|
||||
match method {
|
||||
Some(ok) => {
|
||||
let method = self.register_infer_ok_obligations(ok);
|
||||
self.select_obligations_where_possible(|_| {});
|
||||
Ok(method)
|
||||
}
|
||||
(None, None) => Err(vec![]),
|
||||
(None, Some(trait_did)) => {
|
||||
None => {
|
||||
// This path may do some inference, so make sure we've really
|
||||
// doomed compilation so as to not accidentally stabilize new
|
||||
// inference or something here...
|
||||
self.tcx.sess.delay_span_bug(span, "this path really should be doomed...");
|
||||
// Guide inference for the RHS expression if it's provided --
|
||||
// this will allow us to better error reporting, at the expense
|
||||
// of making some error messages a bit more specific.
|
||||
if let Some((rhs_expr, rhs_ty)) = opt_rhs
|
||||
&& rhs_ty.is_ty_var()
|
||||
{
|
||||
self.check_expr_coercible_to_type(rhs_expr, rhs_ty, None);
|
||||
}
|
||||
|
||||
let (obligation, _) =
|
||||
self.obligation_for_method(cause, trait_did, lhs_ty, Some(input_types));
|
||||
// FIXME: This should potentially just add the obligation to the `FnCtxt`
|
||||
|
@ -200,9 +200,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
|
||||
debug!("try_overloaded_place_op({:?},{:?},{:?})", span, base_ty, op);
|
||||
|
||||
let (imm_tr, imm_op) = match op {
|
||||
let (Some(imm_tr), imm_op) = (match op {
|
||||
PlaceOp::Deref => (self.tcx.lang_items().deref_trait(), sym::deref),
|
||||
PlaceOp::Index => (self.tcx.lang_items().index_trait(), sym::index),
|
||||
}) else {
|
||||
// Bail if `Deref` or `Index` isn't defined.
|
||||
return None;
|
||||
};
|
||||
|
||||
// If the lang item was declared incorrectly, stop here so that we don't
|
||||
@ -219,15 +222,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
return None;
|
||||
}
|
||||
|
||||
imm_tr.and_then(|trait_did| {
|
||||
self.lookup_method_in_trait(
|
||||
self.misc(span),
|
||||
Ident::with_dummy_span(imm_op),
|
||||
trait_did,
|
||||
base_ty,
|
||||
Some(arg_tys),
|
||||
)
|
||||
})
|
||||
self.lookup_method_in_trait(
|
||||
self.misc(span),
|
||||
Ident::with_dummy_span(imm_op),
|
||||
imm_tr,
|
||||
base_ty,
|
||||
Some(arg_tys),
|
||||
)
|
||||
}
|
||||
|
||||
fn try_mutable_overloaded_place_op(
|
||||
@ -239,9 +240,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
|
||||
debug!("try_mutable_overloaded_place_op({:?},{:?},{:?})", span, base_ty, op);
|
||||
|
||||
let (mut_tr, mut_op) = match op {
|
||||
let (Some(mut_tr), mut_op) = (match op {
|
||||
PlaceOp::Deref => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
|
||||
PlaceOp::Index => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
|
||||
}) else {
|
||||
// Bail if `DerefMut` or `IndexMut` isn't defined.
|
||||
return None;
|
||||
};
|
||||
|
||||
// If the lang item was declared incorrectly, stop here so that we don't
|
||||
@ -258,15 +262,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
return None;
|
||||
}
|
||||
|
||||
mut_tr.and_then(|trait_did| {
|
||||
self.lookup_method_in_trait(
|
||||
self.misc(span),
|
||||
Ident::with_dummy_span(mut_op),
|
||||
trait_did,
|
||||
base_ty,
|
||||
Some(arg_tys),
|
||||
)
|
||||
})
|
||||
self.lookup_method_in_trait(
|
||||
self.misc(span),
|
||||
Ident::with_dummy_span(mut_op),
|
||||
mut_tr,
|
||||
base_ty,
|
||||
Some(arg_tys),
|
||||
)
|
||||
}
|
||||
|
||||
/// Convert auto-derefs, indices, etc of an expression from `Deref` and `Index`
|
||||
|
@ -203,7 +203,7 @@ impl Scope {
|
||||
pub type ScopeDepth = u32;
|
||||
|
||||
/// The region scope tree encodes information about region relationships.
|
||||
#[derive(TyEncodable, TyDecodable, Default, Debug)]
|
||||
#[derive(Default, Debug)]
|
||||
pub struct ScopeTree {
|
||||
/// If not empty, this body is the root of this region hierarchy.
|
||||
pub root_body: Option<hir::HirId>,
|
||||
@ -317,13 +317,13 @@ pub struct ScopeTree {
|
||||
/// candidates in general). In constants, the `lifetime` field is None
|
||||
/// to indicate that certain expressions escape into 'static and
|
||||
/// should have no local cleanup scope.
|
||||
#[derive(Debug, Copy, Clone, TyEncodable, TyDecodable, HashStable)]
|
||||
#[derive(Debug, Copy, Clone, HashStable)]
|
||||
pub enum RvalueCandidateType {
|
||||
Borrow { target: hir::ItemLocalId, lifetime: Option<Scope> },
|
||||
Pattern { target: hir::ItemLocalId, lifetime: Option<Scope> },
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, TyEncodable, TyDecodable, HashStable)]
|
||||
#[derive(Debug, Copy, Clone, HashStable)]
|
||||
pub struct YieldData {
|
||||
/// The `Span` of the yield.
|
||||
pub span: Span,
|
||||
|
@ -199,7 +199,7 @@ impl<'tcx> ObligationCause<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift, HashStable, TyEncodable, TyDecodable)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Lift, HashStable, TyEncodable, TyDecodable)]
|
||||
#[derive(TypeVisitable, TypeFoldable)]
|
||||
pub struct UnifyReceiverContext<'tcx> {
|
||||
pub assoc_item: ty::AssocItem,
|
||||
@ -207,7 +207,7 @@ pub struct UnifyReceiverContext<'tcx> {
|
||||
pub substs: SubstsRef<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Lift, Default, HashStable)]
|
||||
#[derive(Clone, PartialEq, Eq, Lift, Default, HashStable)]
|
||||
#[derive(TypeVisitable, TypeFoldable, TyEncodable, TyDecodable)]
|
||||
pub struct InternedObligationCauseCode<'tcx> {
|
||||
/// `None` for `ObligationCauseCode::MiscObligation` (a common case, occurs ~60% of
|
||||
@ -243,7 +243,7 @@ impl<'tcx> std::ops::Deref for InternedObligationCauseCode<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift, HashStable, TyEncodable, TyDecodable)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Lift, HashStable, TyEncodable, TyDecodable)]
|
||||
#[derive(TypeVisitable, TypeFoldable)]
|
||||
pub enum ObligationCauseCode<'tcx> {
|
||||
/// Not well classified or should be obvious from the span.
|
||||
@ -468,7 +468,7 @@ pub enum WellFormedLoc {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift, HashStable, TyEncodable, TyDecodable)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Lift, HashStable, TyEncodable, TyDecodable)]
|
||||
#[derive(TypeVisitable, TypeFoldable)]
|
||||
pub struct ImplDerivedObligationCause<'tcx> {
|
||||
pub derived: DerivedObligationCause<'tcx>,
|
||||
@ -529,7 +529,7 @@ impl<'tcx> ty::Lift<'tcx> for StatementAsExpression {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift, HashStable, TyEncodable, TyDecodable)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Lift, HashStable, TyEncodable, TyDecodable)]
|
||||
#[derive(TypeVisitable, TypeFoldable)]
|
||||
pub struct MatchExpressionArmCause<'tcx> {
|
||||
pub arm_block_id: Option<hir::HirId>,
|
||||
@ -545,7 +545,7 @@ pub struct MatchExpressionArmCause<'tcx> {
|
||||
pub opt_suggest_box_span: Option<Span>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Lift, TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)]
|
||||
pub struct IfExpressionCause<'tcx> {
|
||||
pub then_id: hir::HirId,
|
||||
@ -556,7 +556,7 @@ pub struct IfExpressionCause<'tcx> {
|
||||
pub opt_suggest_box_span: Option<Span>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift, HashStable, TyEncodable, TyDecodable)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Lift, HashStable, TyEncodable, TyDecodable)]
|
||||
#[derive(TypeVisitable, TypeFoldable)]
|
||||
pub struct DerivedObligationCause<'tcx> {
|
||||
/// The trait predicate of the parent obligation that led to the
|
||||
|
@ -188,7 +188,7 @@ impl<'tcx> AdtDef<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, HashStable, TyEncodable, TyDecodable)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable, TyEncodable, TyDecodable)]
|
||||
pub enum AdtKind {
|
||||
Struct,
|
||||
Union,
|
||||
|
@ -51,13 +51,6 @@ macro_rules! write_leb128 {
|
||||
}};
|
||||
}
|
||||
|
||||
/// A byte that [cannot occur in UTF8 sequences][utf8]. Used to mark the end of a string.
|
||||
/// This way we can skip validation and still be relatively sure that deserialization
|
||||
/// did not desynchronize.
|
||||
///
|
||||
/// [utf8]: https://en.wikipedia.org/w/index.php?title=UTF-8&oldid=1058865525#Codepage_layout
|
||||
const STR_SENTINEL: u8 = 0xC1;
|
||||
|
||||
impl Encoder for MemEncoder {
|
||||
#[inline]
|
||||
fn emit_usize(&mut self, v: usize) {
|
||||
@ -114,28 +107,6 @@ impl Encoder for MemEncoder {
|
||||
self.data.extend_from_slice(&v.to_le_bytes());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn emit_i8(&mut self, v: i8) {
|
||||
self.emit_u8(v as u8);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn emit_bool(&mut self, v: bool) {
|
||||
self.emit_u8(if v { 1 } else { 0 });
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn emit_char(&mut self, v: char) {
|
||||
self.emit_u32(v as u32);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn emit_str(&mut self, v: &str) {
|
||||
self.emit_usize(v.len());
|
||||
self.emit_raw_bytes(v.as_bytes());
|
||||
self.emit_u8(STR_SENTINEL);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn emit_raw_bytes(&mut self, s: &[u8]) {
|
||||
self.data.extend_from_slice(s);
|
||||
@ -480,28 +451,6 @@ impl Encoder for FileEncoder {
|
||||
self.write_all(&v.to_le_bytes());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn emit_i8(&mut self, v: i8) {
|
||||
self.emit_u8(v as u8);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn emit_bool(&mut self, v: bool) {
|
||||
self.emit_u8(if v { 1 } else { 0 });
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn emit_char(&mut self, v: char) {
|
||||
self.emit_u32(v as u32);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn emit_str(&mut self, v: &str) {
|
||||
self.emit_usize(v.len());
|
||||
self.emit_raw_bytes(v.as_bytes());
|
||||
self.emit_u8(STR_SENTINEL);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn emit_raw_bytes(&mut self, s: &[u8]) {
|
||||
self.write_all(s);
|
||||
@ -555,40 +504,11 @@ impl<'a> MemDecoder<'a> {
|
||||
panic!("MemDecoder exhausted")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_byte(&mut self) -> u8 {
|
||||
if self.current == self.end {
|
||||
Self::decoder_exhausted();
|
||||
}
|
||||
// SAFETY: This type guarantees current <= end, and we just checked current == end.
|
||||
unsafe {
|
||||
let byte = *self.current;
|
||||
self.current = self.current.add(1);
|
||||
byte
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_array<const N: usize>(&mut self) -> [u8; N] {
|
||||
self.read_raw_bytes(N).try_into().unwrap()
|
||||
}
|
||||
|
||||
// The trait method doesn't have a lifetime parameter, and we need a version of this
|
||||
// that definitely returns a slice based on the underlying storage as opposed to
|
||||
// the Decoder itself in order to implement read_str efficiently.
|
||||
#[inline]
|
||||
fn read_raw_bytes_inherent(&mut self, bytes: usize) -> &'a [u8] {
|
||||
if bytes > self.remaining() {
|
||||
Self::decoder_exhausted();
|
||||
}
|
||||
// SAFETY: We just checked if this range is in-bounds above.
|
||||
unsafe {
|
||||
let slice = std::slice::from_raw_parts(self.current, bytes);
|
||||
self.current = self.current.add(bytes);
|
||||
slice
|
||||
}
|
||||
}
|
||||
|
||||
/// While we could manually expose manipulation of the decoder position,
|
||||
/// all current users of that method would need to reset the position later,
|
||||
/// incurring the bounds check of set_position twice.
|
||||
@ -653,7 +573,15 @@ impl<'a> Decoder for MemDecoder<'a> {
|
||||
|
||||
#[inline]
|
||||
fn read_u8(&mut self) -> u8 {
|
||||
self.read_byte()
|
||||
if self.current == self.end {
|
||||
Self::decoder_exhausted();
|
||||
}
|
||||
// SAFETY: This type guarantees current <= end, and we just checked current == end.
|
||||
unsafe {
|
||||
let byte = *self.current;
|
||||
self.current = self.current.add(1);
|
||||
byte
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -681,39 +609,22 @@ impl<'a> Decoder for MemDecoder<'a> {
|
||||
i16::from_le_bytes(self.read_array())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_i8(&mut self) -> i8 {
|
||||
self.read_byte() as i8
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_isize(&mut self) -> isize {
|
||||
read_leb128!(self, read_isize_leb128)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_bool(&mut self) -> bool {
|
||||
let value = self.read_u8();
|
||||
value != 0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_char(&mut self) -> char {
|
||||
let bits = self.read_u32();
|
||||
std::char::from_u32(bits).unwrap()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_str(&mut self) -> &str {
|
||||
let len = self.read_usize();
|
||||
let bytes = self.read_raw_bytes_inherent(len + 1);
|
||||
assert!(bytes[len] == STR_SENTINEL);
|
||||
unsafe { std::str::from_utf8_unchecked(&bytes[..len]) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_raw_bytes(&mut self, bytes: usize) -> &[u8] {
|
||||
self.read_raw_bytes_inherent(bytes)
|
||||
fn read_raw_bytes(&mut self, bytes: usize) -> &'a [u8] {
|
||||
if bytes > self.remaining() {
|
||||
Self::decoder_exhausted();
|
||||
}
|
||||
// SAFETY: We just checked if this range is in-bounds above.
|
||||
unsafe {
|
||||
let slice = std::slice::from_raw_parts(self.current, bytes);
|
||||
self.current = self.current.add(bytes);
|
||||
slice
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -787,12 +698,7 @@ impl Encodable<FileEncoder> for IntEncodedWithFixedSize {
|
||||
impl<'a> Decodable<MemDecoder<'a>> for IntEncodedWithFixedSize {
|
||||
#[inline]
|
||||
fn decode(decoder: &mut MemDecoder<'a>) -> IntEncodedWithFixedSize {
|
||||
let _start_pos = decoder.position();
|
||||
let bytes = decoder.read_raw_bytes(IntEncodedWithFixedSize::ENCODED_SIZE);
|
||||
let value = u64::from_le_bytes(bytes.try_into().unwrap());
|
||||
let _end_pos = decoder.position();
|
||||
debug_assert_eq!((_end_pos - _start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
|
||||
|
||||
IntEncodedWithFixedSize(value)
|
||||
let bytes = decoder.read_array::<{ IntEncodedWithFixedSize::ENCODED_SIZE }>();
|
||||
IntEncodedWithFixedSize(u64::from_le_bytes(bytes))
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,13 @@ use std::path;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// A byte that [cannot occur in UTF8 sequences][utf8]. Used to mark the end of a string.
|
||||
/// This way we can skip validation and still be relatively sure that deserialization
|
||||
/// did not desynchronize.
|
||||
///
|
||||
/// [utf8]: https://en.wikipedia.org/w/index.php?title=UTF-8&oldid=1058865525#Codepage_layout
|
||||
const STR_SENTINEL: u8 = 0xC1;
|
||||
|
||||
/// A note about error handling.
|
||||
///
|
||||
/// Encoders may be fallible, but in practice failure is rare and there are so
|
||||
@ -40,10 +47,29 @@ pub trait Encoder {
|
||||
fn emit_i64(&mut self, v: i64);
|
||||
fn emit_i32(&mut self, v: i32);
|
||||
fn emit_i16(&mut self, v: i16);
|
||||
fn emit_i8(&mut self, v: i8);
|
||||
fn emit_bool(&mut self, v: bool);
|
||||
fn emit_char(&mut self, v: char);
|
||||
fn emit_str(&mut self, v: &str);
|
||||
|
||||
#[inline]
|
||||
fn emit_i8(&mut self, v: i8) {
|
||||
self.emit_u8(v as u8);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn emit_bool(&mut self, v: bool) {
|
||||
self.emit_u8(if v { 1 } else { 0 });
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn emit_char(&mut self, v: char) {
|
||||
self.emit_u32(v as u32);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn emit_str(&mut self, v: &str) {
|
||||
self.emit_usize(v.len());
|
||||
self.emit_raw_bytes(v.as_bytes());
|
||||
self.emit_u8(STR_SENTINEL);
|
||||
}
|
||||
|
||||
fn emit_raw_bytes(&mut self, s: &[u8]);
|
||||
|
||||
fn emit_enum_variant<F>(&mut self, v_id: usize, f: F)
|
||||
@ -79,11 +105,38 @@ pub trait Decoder {
|
||||
fn read_i64(&mut self) -> i64;
|
||||
fn read_i32(&mut self) -> i32;
|
||||
fn read_i16(&mut self) -> i16;
|
||||
fn read_i8(&mut self) -> i8;
|
||||
fn read_bool(&mut self) -> bool;
|
||||
fn read_char(&mut self) -> char;
|
||||
fn read_str(&mut self) -> &str;
|
||||
|
||||
#[inline]
|
||||
fn read_i8(&mut self) -> i8 {
|
||||
self.read_u8() as i8
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_bool(&mut self) -> bool {
|
||||
let value = self.read_u8();
|
||||
value != 0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_char(&mut self) -> char {
|
||||
let bits = self.read_u32();
|
||||
std::char::from_u32(bits).unwrap()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_str(&mut self) -> &str {
|
||||
let len = self.read_usize();
|
||||
let bytes = self.read_raw_bytes(len + 1);
|
||||
assert!(bytes[len] == STR_SENTINEL);
|
||||
unsafe { std::str::from_utf8_unchecked(&bytes[..len]) }
|
||||
}
|
||||
|
||||
fn read_raw_bytes(&mut self, len: usize) -> &[u8];
|
||||
|
||||
// Although there is an `emit_enum_variant` method in `Encoder`, the code
|
||||
// patterns in decoding are different enough to encoding that there is no
|
||||
// need for a corresponding `read_enum_variant` method here.
|
||||
|
||||
fn peek_byte(&self) -> u8;
|
||||
fn position(&self) -> usize;
|
||||
}
|
||||
|
@ -917,7 +917,7 @@ mod parse {
|
||||
}
|
||||
}
|
||||
|
||||
let mut options = slot.get_or_insert_default();
|
||||
let options = slot.get_or_insert_default();
|
||||
let mut seen_always = false;
|
||||
let mut seen_never = false;
|
||||
let mut seen_ignore_loops = false;
|
||||
|
@ -53,17 +53,6 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriInterpCx<'mir, 'tcx> {
|
||||
(Scalar::from_bool(res), false, self.tcx.types.bool)
|
||||
}
|
||||
|
||||
Offset => {
|
||||
assert!(left.layout.ty.is_unsafe_ptr());
|
||||
let ptr = left.to_scalar().to_pointer(self)?;
|
||||
let offset = right.to_scalar().to_target_isize(self)?;
|
||||
|
||||
let pointee_ty =
|
||||
left.layout.ty.builtin_deref(true).expect("Offset called on non-ptr type").ty;
|
||||
let ptr = self.ptr_offset_inbounds(ptr, pointee_ty, offset)?;
|
||||
(Scalar::from_maybe_pointer(ptr, self), false, left.layout.ty)
|
||||
}
|
||||
|
||||
// Some more operations are possible with atomics.
|
||||
// The return value always has the provenance of the *left* operand.
|
||||
Add | Sub | BitOr | BitAnd | BitXor => {
|
||||
|
@ -25,7 +25,7 @@ all:
|
||||
# Run rustc with `-Ztemps-dir` set to a directory
|
||||
# *inside* the inaccessible one, so that it can't create it
|
||||
$(RUSTC) program.rs -Ztemps-dir=$(TMPDIR)/inaccessible/tmp 2>&1 \
|
||||
| $(CGREP) "failed to find or create the directory specified by `--temps-dir`"
|
||||
| $(CGREP) 'failed to find or create the directory specified by `--temps-dir`'
|
||||
|
||||
# Make the inaccessible directory accessible,
|
||||
# so that compiletest can delete the temp dir
|
||||
|
7
tests/ui/binop/eq-arr.rs
Normal file
7
tests/ui/binop/eq-arr.rs
Normal file
@ -0,0 +1,7 @@
|
||||
fn main() {
|
||||
struct X;
|
||||
//~^ HELP consider annotating `X` with `#[derive(PartialEq)]`
|
||||
let xs = [X, X, X];
|
||||
let eq = xs == [X, X, X];
|
||||
//~^ ERROR binary operation `==` cannot be applied to type `[X; 3]`
|
||||
}
|
22
tests/ui/binop/eq-arr.stderr
Normal file
22
tests/ui/binop/eq-arr.stderr
Normal file
@ -0,0 +1,22 @@
|
||||
error[E0369]: binary operation `==` cannot be applied to type `[X; 3]`
|
||||
--> $DIR/eq-arr.rs:5:17
|
||||
|
|
||||
LL | let eq = xs == [X, X, X];
|
||||
| -- ^^ --------- [X; 3]
|
||||
| |
|
||||
| [X; 3]
|
||||
|
|
||||
note: an implementation of `PartialEq` might be missing for `X`
|
||||
--> $DIR/eq-arr.rs:2:5
|
||||
|
|
||||
LL | struct X;
|
||||
| ^^^^^^^^ must implement `PartialEq`
|
||||
help: consider annotating `X` with `#[derive(PartialEq)]`
|
||||
|
|
||||
LL + #[derive(PartialEq)]
|
||||
LL | struct X;
|
||||
|
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0369`.
|
13
tests/ui/binop/eq-vec.rs
Normal file
13
tests/ui/binop/eq-vec.rs
Normal file
@ -0,0 +1,13 @@
|
||||
fn main() {
|
||||
#[derive(Debug)]
|
||||
enum Foo {
|
||||
//~^ HELP consider annotating `Foo` with `#[derive(PartialEq)]`
|
||||
Bar,
|
||||
Qux,
|
||||
}
|
||||
|
||||
let vec1 = vec![Foo::Bar, Foo::Qux];
|
||||
let vec2 = vec![Foo::Bar, Foo::Qux];
|
||||
assert_eq!(vec1, vec2);
|
||||
//~^ ERROR binary operation `==` cannot be applied to type `Vec<Foo>`
|
||||
}
|
24
tests/ui/binop/eq-vec.stderr
Normal file
24
tests/ui/binop/eq-vec.stderr
Normal file
@ -0,0 +1,24 @@
|
||||
error[E0369]: binary operation `==` cannot be applied to type `Vec<Foo>`
|
||||
--> $DIR/eq-vec.rs:11:5
|
||||
|
|
||||
LL | assert_eq!(vec1, vec2);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| Vec<Foo>
|
||||
| Vec<Foo>
|
||||
|
|
||||
note: an implementation of `PartialEq` might be missing for `Foo`
|
||||
--> $DIR/eq-vec.rs:3:5
|
||||
|
|
||||
LL | enum Foo {
|
||||
| ^^^^^^^^ must implement `PartialEq`
|
||||
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider annotating `Foo` with `#[derive(PartialEq)]`
|
||||
|
|
||||
LL + #[derive(PartialEq)]
|
||||
LL | enum Foo {
|
||||
|
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0369`.
|
@ -6,11 +6,11 @@ LL | a + a;
|
||||
| |
|
||||
| A
|
||||
|
|
||||
note: an implementation of `Add<_>` might be missing for `A`
|
||||
note: an implementation of `Add` might be missing for `A`
|
||||
--> $DIR/issue-28837.rs:1:1
|
||||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^ must implement `Add<_>`
|
||||
| ^^^^^^^^ must implement `Add`
|
||||
note: the trait `Add` must be implemented
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
||||
@ -22,11 +22,11 @@ LL | a - a;
|
||||
| |
|
||||
| A
|
||||
|
|
||||
note: an implementation of `Sub<_>` might be missing for `A`
|
||||
note: an implementation of `Sub` might be missing for `A`
|
||||
--> $DIR/issue-28837.rs:1:1
|
||||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^ must implement `Sub<_>`
|
||||
| ^^^^^^^^ must implement `Sub`
|
||||
note: the trait `Sub` must be implemented
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
||||
@ -38,11 +38,11 @@ LL | a * a;
|
||||
| |
|
||||
| A
|
||||
|
|
||||
note: an implementation of `Mul<_>` might be missing for `A`
|
||||
note: an implementation of `Mul` might be missing for `A`
|
||||
--> $DIR/issue-28837.rs:1:1
|
||||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^ must implement `Mul<_>`
|
||||
| ^^^^^^^^ must implement `Mul`
|
||||
note: the trait `Mul` must be implemented
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
||||
@ -54,11 +54,11 @@ LL | a / a;
|
||||
| |
|
||||
| A
|
||||
|
|
||||
note: an implementation of `Div<_>` might be missing for `A`
|
||||
note: an implementation of `Div` might be missing for `A`
|
||||
--> $DIR/issue-28837.rs:1:1
|
||||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^ must implement `Div<_>`
|
||||
| ^^^^^^^^ must implement `Div`
|
||||
note: the trait `Div` must be implemented
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
||||
@ -70,11 +70,11 @@ LL | a % a;
|
||||
| |
|
||||
| A
|
||||
|
|
||||
note: an implementation of `Rem<_>` might be missing for `A`
|
||||
note: an implementation of `Rem` might be missing for `A`
|
||||
--> $DIR/issue-28837.rs:1:1
|
||||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^ must implement `Rem<_>`
|
||||
| ^^^^^^^^ must implement `Rem`
|
||||
note: the trait `Rem` must be implemented
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
||||
@ -86,11 +86,11 @@ LL | a & a;
|
||||
| |
|
||||
| A
|
||||
|
|
||||
note: an implementation of `BitAnd<_>` might be missing for `A`
|
||||
note: an implementation of `BitAnd` might be missing for `A`
|
||||
--> $DIR/issue-28837.rs:1:1
|
||||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^ must implement `BitAnd<_>`
|
||||
| ^^^^^^^^ must implement `BitAnd`
|
||||
note: the trait `BitAnd` must be implemented
|
||||
--> $SRC_DIR/core/src/ops/bit.rs:LL:COL
|
||||
|
||||
@ -102,11 +102,11 @@ LL | a | a;
|
||||
| |
|
||||
| A
|
||||
|
|
||||
note: an implementation of `BitOr<_>` might be missing for `A`
|
||||
note: an implementation of `BitOr` might be missing for `A`
|
||||
--> $DIR/issue-28837.rs:1:1
|
||||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^ must implement `BitOr<_>`
|
||||
| ^^^^^^^^ must implement `BitOr`
|
||||
note: the trait `BitOr` must be implemented
|
||||
--> $SRC_DIR/core/src/ops/bit.rs:LL:COL
|
||||
|
||||
@ -118,11 +118,11 @@ LL | a << a;
|
||||
| |
|
||||
| A
|
||||
|
|
||||
note: an implementation of `Shl<_>` might be missing for `A`
|
||||
note: an implementation of `Shl` might be missing for `A`
|
||||
--> $DIR/issue-28837.rs:1:1
|
||||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^ must implement `Shl<_>`
|
||||
| ^^^^^^^^ must implement `Shl`
|
||||
note: the trait `Shl` must be implemented
|
||||
--> $SRC_DIR/core/src/ops/bit.rs:LL:COL
|
||||
|
||||
@ -134,11 +134,11 @@ LL | a >> a;
|
||||
| |
|
||||
| A
|
||||
|
|
||||
note: an implementation of `Shr<_>` might be missing for `A`
|
||||
note: an implementation of `Shr` might be missing for `A`
|
||||
--> $DIR/issue-28837.rs:1:1
|
||||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^ must implement `Shr<_>`
|
||||
| ^^^^^^^^ must implement `Shr`
|
||||
note: the trait `Shr` must be implemented
|
||||
--> $SRC_DIR/core/src/ops/bit.rs:LL:COL
|
||||
|
||||
@ -150,11 +150,11 @@ LL | a == a;
|
||||
| |
|
||||
| A
|
||||
|
|
||||
note: an implementation of `PartialEq<_>` might be missing for `A`
|
||||
note: an implementation of `PartialEq` might be missing for `A`
|
||||
--> $DIR/issue-28837.rs:1:1
|
||||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^ must implement `PartialEq<_>`
|
||||
| ^^^^^^^^ must implement `PartialEq`
|
||||
help: consider annotating `A` with `#[derive(PartialEq)]`
|
||||
|
|
||||
LL + #[derive(PartialEq)]
|
||||
@ -169,11 +169,11 @@ LL | a != a;
|
||||
| |
|
||||
| A
|
||||
|
|
||||
note: an implementation of `PartialEq<_>` might be missing for `A`
|
||||
note: an implementation of `PartialEq` might be missing for `A`
|
||||
--> $DIR/issue-28837.rs:1:1
|
||||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^ must implement `PartialEq<_>`
|
||||
| ^^^^^^^^ must implement `PartialEq`
|
||||
help: consider annotating `A` with `#[derive(PartialEq)]`
|
||||
|
|
||||
LL + #[derive(PartialEq)]
|
||||
@ -188,11 +188,11 @@ LL | a < a;
|
||||
| |
|
||||
| A
|
||||
|
|
||||
note: an implementation of `PartialOrd<_>` might be missing for `A`
|
||||
note: an implementation of `PartialOrd` might be missing for `A`
|
||||
--> $DIR/issue-28837.rs:1:1
|
||||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^ must implement `PartialOrd<_>`
|
||||
| ^^^^^^^^ must implement `PartialOrd`
|
||||
help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]`
|
||||
|
|
||||
LL + #[derive(PartialEq, PartialOrd)]
|
||||
@ -207,11 +207,11 @@ LL | a <= a;
|
||||
| |
|
||||
| A
|
||||
|
|
||||
note: an implementation of `PartialOrd<_>` might be missing for `A`
|
||||
note: an implementation of `PartialOrd` might be missing for `A`
|
||||
--> $DIR/issue-28837.rs:1:1
|
||||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^ must implement `PartialOrd<_>`
|
||||
| ^^^^^^^^ must implement `PartialOrd`
|
||||
help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]`
|
||||
|
|
||||
LL + #[derive(PartialEq, PartialOrd)]
|
||||
@ -226,11 +226,11 @@ LL | a > a;
|
||||
| |
|
||||
| A
|
||||
|
|
||||
note: an implementation of `PartialOrd<_>` might be missing for `A`
|
||||
note: an implementation of `PartialOrd` might be missing for `A`
|
||||
--> $DIR/issue-28837.rs:1:1
|
||||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^ must implement `PartialOrd<_>`
|
||||
| ^^^^^^^^ must implement `PartialOrd`
|
||||
help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]`
|
||||
|
|
||||
LL + #[derive(PartialEq, PartialOrd)]
|
||||
@ -245,11 +245,11 @@ LL | a >= a;
|
||||
| |
|
||||
| A
|
||||
|
|
||||
note: an implementation of `PartialOrd<_>` might be missing for `A`
|
||||
note: an implementation of `PartialOrd` might be missing for `A`
|
||||
--> $DIR/issue-28837.rs:1:1
|
||||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^ must implement `PartialOrd<_>`
|
||||
| ^^^^^^^^ must implement `PartialOrd`
|
||||
help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]`
|
||||
|
|
||||
LL + #[derive(PartialEq, PartialOrd)]
|
||||
|
@ -6,11 +6,11 @@ LL | let w = u * 3;
|
||||
| |
|
||||
| Thing
|
||||
|
|
||||
note: an implementation of `Mul<_>` might be missing for `Thing`
|
||||
note: an implementation of `Mul<{integer}>` might be missing for `Thing`
|
||||
--> $DIR/issue-3820.rs:1:1
|
||||
|
|
||||
LL | struct Thing {
|
||||
| ^^^^^^^^^^^^ must implement `Mul<_>`
|
||||
| ^^^^^^^^^^^^ must implement `Mul<{integer}>`
|
||||
note: the trait `Mul` must be implemented
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
||||
|
@ -7,11 +7,11 @@ LL | #[derive(PartialEq)]
|
||||
LL | x: Error
|
||||
| ^^^^^^^^
|
||||
|
|
||||
note: an implementation of `PartialEq<_>` might be missing for `Error`
|
||||
note: an implementation of `PartialEq` might be missing for `Error`
|
||||
--> $DIR/derives-span-PartialEq-enum-struct-variant.rs:4:1
|
||||
|
|
||||
LL | struct Error;
|
||||
| ^^^^^^^^^^^^ must implement `PartialEq<_>`
|
||||
| ^^^^^^^^^^^^ must implement `PartialEq`
|
||||
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider annotating `Error` with `#[derive(PartialEq)]`
|
||||
|
|
||||
|
@ -7,11 +7,11 @@ LL | #[derive(PartialEq)]
|
||||
LL | Error
|
||||
| ^^^^^
|
||||
|
|
||||
note: an implementation of `PartialEq<_>` might be missing for `Error`
|
||||
note: an implementation of `PartialEq` might be missing for `Error`
|
||||
--> $DIR/derives-span-PartialEq-enum.rs:4:1
|
||||
|
|
||||
LL | struct Error;
|
||||
| ^^^^^^^^^^^^ must implement `PartialEq<_>`
|
||||
| ^^^^^^^^^^^^ must implement `PartialEq`
|
||||
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider annotating `Error` with `#[derive(PartialEq)]`
|
||||
|
|
||||
|
@ -7,11 +7,11 @@ LL | struct Struct {
|
||||
LL | x: Error
|
||||
| ^^^^^^^^
|
||||
|
|
||||
note: an implementation of `PartialEq<_>` might be missing for `Error`
|
||||
note: an implementation of `PartialEq` might be missing for `Error`
|
||||
--> $DIR/derives-span-PartialEq-struct.rs:4:1
|
||||
|
|
||||
LL | struct Error;
|
||||
| ^^^^^^^^^^^^ must implement `PartialEq<_>`
|
||||
| ^^^^^^^^^^^^ must implement `PartialEq`
|
||||
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider annotating `Error` with `#[derive(PartialEq)]`
|
||||
|
|
||||
|
@ -7,11 +7,11 @@ LL | struct Struct(
|
||||
LL | Error
|
||||
| ^^^^^
|
||||
|
|
||||
note: an implementation of `PartialEq<_>` might be missing for `Error`
|
||||
note: an implementation of `PartialEq` might be missing for `Error`
|
||||
--> $DIR/derives-span-PartialEq-tuple-struct.rs:4:1
|
||||
|
|
||||
LL | struct Error;
|
||||
| ^^^^^^^^^^^^ must implement `PartialEq<_>`
|
||||
| ^^^^^^^^^^^^ must implement `PartialEq`
|
||||
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider annotating `Error` with `#[derive(PartialEq)]`
|
||||
|
|
||||
|
@ -7,11 +7,11 @@ LL | struct E {
|
||||
LL | x: NoCloneOrEq
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
note: an implementation of `PartialEq<_>` might be missing for `NoCloneOrEq`
|
||||
note: an implementation of `PartialEq` might be missing for `NoCloneOrEq`
|
||||
--> $DIR/deriving-no-inner-impl-error-message.rs:1:1
|
||||
|
|
||||
LL | struct NoCloneOrEq;
|
||||
| ^^^^^^^^^^^^^^^^^^ must implement `PartialEq<_>`
|
||||
| ^^^^^^^^^^^^^^^^^^ must implement `PartialEq`
|
||||
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider annotating `NoCloneOrEq` with `#[derive(PartialEq)]`
|
||||
|
|
||||
|
@ -44,11 +44,11 @@ LL | S { x: a, y: b } += s;
|
||||
| |
|
||||
| cannot use `+=` on type `S`
|
||||
|
|
||||
note: an implementation of `AddAssign<_>` might be missing for `S`
|
||||
note: an implementation of `AddAssign` might be missing for `S`
|
||||
--> $DIR/note-unsupported.rs:1:1
|
||||
|
|
||||
LL | struct S { x: u8, y: u8 }
|
||||
| ^^^^^^^^ must implement `AddAssign<_>`
|
||||
| ^^^^^^^^ must implement `AddAssign`
|
||||
note: the trait `AddAssign` must be implemented
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
||||
|
@ -0,0 +1,12 @@
|
||||
// edition:2021
|
||||
// compile-flags: -Zdrop-tracking-mir=yes
|
||||
#![feature(generators)]
|
||||
|
||||
fn main() {
|
||||
let x = &mut ();
|
||||
|| {
|
||||
let _c = || yield *&mut *x;
|
||||
|| _ = &mut *x;
|
||||
//~^ cannot borrow `*x` as mutable more than once at a time
|
||||
};
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
error[E0499]: cannot borrow `*x` as mutable more than once at a time
|
||||
--> $DIR/issue-110929-generator-conflict-error-ice.rs:9:9
|
||||
|
|
||||
LL | let _c = || yield *&mut *x;
|
||||
| -- -- first borrow occurs due to use of `*x` in generator
|
||||
| |
|
||||
| first mutable borrow occurs here
|
||||
LL | || _ = &mut *x;
|
||||
| ^^ -- second borrow occurs due to use of `*x` in closure
|
||||
| |
|
||||
| second mutable borrow occurs here
|
||||
LL |
|
||||
LL | };
|
||||
| - first borrow might be used here, when `_c` is dropped and runs the destructor for generator
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0499`.
|
@ -6,16 +6,17 @@ LL | a == A::Value;
|
||||
| |
|
||||
| A
|
||||
|
|
||||
note: an implementation of `PartialEq<_>` might be missing for `A`
|
||||
note: an implementation of `PartialEq<fn(()) -> A {A::Value}>` might be missing for `A`
|
||||
--> $DIR/issue-62375.rs:1:1
|
||||
|
|
||||
LL | enum A {
|
||||
| ^^^^^^ must implement `PartialEq<_>`
|
||||
help: consider annotating `A` with `#[derive(PartialEq)]`
|
||||
|
|
||||
LL + #[derive(PartialEq)]
|
||||
LL | enum A {
|
||||
| ^^^^^^ must implement `PartialEq<fn(()) -> A {A::Value}>`
|
||||
note: the trait `PartialEq` must be implemented
|
||||
--> $SRC_DIR/core/src/cmp.rs:LL:COL
|
||||
help: use parentheses to construct this tuple variant
|
||||
|
|
||||
LL | a == A::Value(/* () */);
|
||||
| ++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -205,3 +205,11 @@ fn bar() {
|
||||
let mut b = vec![2]; //~ ERROR: variable does not need to be mutable
|
||||
|
||||
}
|
||||
|
||||
struct Arg(i32);
|
||||
|
||||
// Regression test for https://github.com/rust-lang/rust/issues/110849
|
||||
fn write_through_reference(mut arg: &mut Arg) {
|
||||
//~^ WARN: variable does not need to be mutable
|
||||
arg.0 = 1
|
||||
}
|
||||
|
@ -218,5 +218,13 @@ note: the lint level is defined here
|
||||
LL | #[deny(unused_mut)]
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error; 25 warnings emitted
|
||||
warning: variable does not need to be mutable
|
||||
--> $DIR/lint-unused-mut-variables.rs:212:28
|
||||
|
|
||||
LL | fn write_through_reference(mut arg: &mut Arg) {
|
||||
| ----^^^
|
||||
| |
|
||||
| help: remove this `mut`
|
||||
|
||||
error: aborting due to previous error; 26 warnings emitted
|
||||
|
||||
|
@ -6,11 +6,11 @@ LL | a += *b;
|
||||
| |
|
||||
| cannot use `+=` on type `Foo`
|
||||
|
|
||||
note: an implementation of `AddAssign<_>` might be missing for `Foo`
|
||||
note: an implementation of `AddAssign` might be missing for `Foo`
|
||||
--> $DIR/assignment-operator-unimplemented.rs:1:1
|
||||
|
|
||||
LL | struct Foo;
|
||||
| ^^^^^^^^^^ must implement `AddAssign<_>`
|
||||
| ^^^^^^^^^^ must implement `AddAssign`
|
||||
note: the trait `AddAssign` must be implemented
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
||||
|
@ -30,11 +30,11 @@ LL | let _ = |A | B: E| ();
|
||||
| |
|
||||
| E
|
||||
|
|
||||
note: an implementation of `BitOr<_>` might be missing for `E`
|
||||
note: an implementation of `BitOr<()>` might be missing for `E`
|
||||
--> $DIR/or-patterns-syntactic-fail.rs:6:1
|
||||
|
|
||||
LL | enum E { A, B }
|
||||
| ^^^^^^ must implement `BitOr<_>`
|
||||
| ^^^^^^ must implement `BitOr<()>`
|
||||
note: the trait `BitOr` must be implemented
|
||||
--> $SRC_DIR/core/src/ops/bit.rs:LL:COL
|
||||
|
||||
|
@ -21,11 +21,11 @@ LL | let y = World::Hello + World::Goodbye;
|
||||
| |
|
||||
| World
|
||||
|
|
||||
note: an implementation of `Add<_>` might be missing for `World`
|
||||
note: an implementation of `Add` might be missing for `World`
|
||||
--> $DIR/issue-39018.rs:15:1
|
||||
|
|
||||
LL | enum World {
|
||||
| ^^^^^^^^^^ must implement `Add<_>`
|
||||
| ^^^^^^^^^^ must implement `Add`
|
||||
note: the trait `Add` must be implemented
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
||||
|
@ -6,11 +6,11 @@ LL | let _ = s == t;
|
||||
| |
|
||||
| S<T>
|
||||
|
|
||||
note: an implementation of `PartialEq<_>` might be missing for `S<T>`
|
||||
note: an implementation of `PartialEq` might be missing for `S<T>`
|
||||
--> $DIR/invalid-bin-op.rs:5:1
|
||||
|
|
||||
LL | struct S<T>(T);
|
||||
| ^^^^^^^^^^^ must implement `PartialEq<_>`
|
||||
| ^^^^^^^^^^^ must implement `PartialEq`
|
||||
help: consider annotating `S<T>` with `#[derive(PartialEq)]`
|
||||
|
|
||||
LL + #[derive(PartialEq)]
|
||||
|
@ -6,11 +6,11 @@ LL | a + b
|
||||
| |
|
||||
| Wrapper<T>
|
||||
|
|
||||
note: an implementation of `Add<_>` might be missing for `Wrapper<T>`
|
||||
note: an implementation of `Add<T>` might be missing for `Wrapper<T>`
|
||||
--> $DIR/restrict-type-not-param.rs:3:1
|
||||
|
|
||||
LL | struct Wrapper<T>(T);
|
||||
| ^^^^^^^^^^^^^^^^^ must implement `Add<_>`
|
||||
| ^^^^^^^^^^^^^^^^^ must implement `Add<T>`
|
||||
note: the trait `Add` must be implemented
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
||||
|
@ -11,7 +11,7 @@ fn main() {
|
||||
let mut map = HashMap::new();
|
||||
map.insert("a", Test { v: 0 });
|
||||
|
||||
for (_k, mut v) in map.iter_mut() {
|
||||
for (_k, v) in map.iter_mut() {
|
||||
//~^ HELP use mutable method
|
||||
//~| NOTE this iterator yields `&` references
|
||||
v.v += 1;
|
||||
|
@ -11,7 +11,7 @@ fn main() {
|
||||
let mut map = HashMap::new();
|
||||
map.insert("a", Test { v: 0 });
|
||||
|
||||
for (_k, mut v) in map.iter() {
|
||||
for (_k, v) in map.iter() {
|
||||
//~^ HELP use mutable method
|
||||
//~| NOTE this iterator yields `&` references
|
||||
v.v += 1;
|
||||
|
@ -1,11 +1,11 @@
|
||||
error[E0594]: cannot assign to `v.v`, which is behind a `&` reference
|
||||
--> $DIR/suggest-mut-method-for-loop-hashmap.rs:17:9
|
||||
|
|
||||
LL | for (_k, mut v) in map.iter() {
|
||||
| ----------
|
||||
| | |
|
||||
| | help: use mutable method: `iter_mut()`
|
||||
| this iterator yields `&` references
|
||||
LL | for (_k, v) in map.iter() {
|
||||
| ----------
|
||||
| | |
|
||||
| | help: use mutable method: `iter_mut()`
|
||||
| this iterator yields `&` references
|
||||
...
|
||||
LL | v.v += 1;
|
||||
| ^^^^^^^^ `v` is a `&` reference, so the data it refers to cannot be written
|
||||
|
@ -1,8 +1,8 @@
|
||||
error[E0369]: cannot subtract `(dyn Vector2<ScalarType = i32> + 'static)` from `dyn Vector2<ScalarType = i32>`
|
||||
error[E0369]: cannot subtract `dyn Vector2<ScalarType = i32>` from `dyn Vector2<ScalarType = i32>`
|
||||
--> $DIR/type-unsatisfiable.rs:57:20
|
||||
|
|
||||
LL | let bar = *hey - *word;
|
||||
| ---- ^ ----- (dyn Vector2<ScalarType = i32> + 'static)
|
||||
| ---- ^ ----- dyn Vector2<ScalarType = i32>
|
||||
| |
|
||||
| dyn Vector2<ScalarType = i32>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user