diff options
| author | bors <bors@rust-lang.org> | 2023-04-28 23:13:42 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-04-28 23:13:42 +0000 |
| commit | 7a96158b53529c2dd03bb4a637d8589ac6f5376f (patch) | |
| tree | 9217d20a1cd88242c8c51eb0e117e78b3e906576 | |
| parent | f4956053816439a5884cb2ad1247835858f92218 (diff) | |
| parent | 34ef13b15b0c88bfbc89d4404c2e3ea1b24bbc38 (diff) | |
| download | rust-7a96158b53529c2dd03bb4a637d8589ac6f5376f.tar.gz rust-7a96158b53529c2dd03bb4a637d8589ac6f5376f.zip | |
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
48 files changed, 449 insertions, 342 deletions
diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index 345e058e113..236bdb99709 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -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; diff --git a/compiler/rustc_ast_pretty/src/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs index c93022308a3..7ab8c3eaba2 100644 --- a/compiler/rustc_ast_pretty/src/pp.rs +++ b/compiler/rustc_ast_pretty/src/pp.rs @@ -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 { diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 5db0f72919d..ac84188a35f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -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)); diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index b57b0c9e4ba..6900729d671 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -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); } } } diff --git a/compiler/rustc_borrowck/src/member_constraints.rs b/compiler/rustc_borrowck/src/member_constraints.rs index db5b8f464c8..842e9008058 100644 --- a/compiler/rustc_borrowck/src/member_constraints.rs +++ b/compiler/rustc_borrowck/src/member_constraints.rs @@ -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 => { diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 02e21e74fad..eecfe13bb3e 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -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 { diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index bfca58a15b3..814b67b46ec 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -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"); } diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index 4decfe863e6..7186148daf0 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -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(), diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 21b4a3370d3..e220a029339 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -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]>, diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index 421b3df2d53..6ab5556e951 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -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; diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 3928520153c..d50be47c915 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -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) { diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index db1f10f645f..43f40ada5ac 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -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)); diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index a52c94cb00c..e91ae4466eb 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -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` diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs index 2cca45de5e9..1f7e7ba9f5b 100644 --- a/compiler/rustc_hir_typeck/src/place_op.rs +++ b/compiler/rustc_hir_typeck/src/place_op.rs @@ -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` diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs index 94ca38c0e75..10712e14686 100644 --- a/compiler/rustc_middle/src/middle/region.rs +++ b/compiler/rustc_middle/src/middle/region.rs @@ -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, diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 02433026266..d69d42bb5d3 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -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 diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 30e488a9e47..6187fc43cf8 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -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, diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs index b7976ea3b1c..0f6e4b329b8 100644 --- a/compiler/rustc_serialize/src/opaque.rs +++ b/compiler/rustc_serialize/src/opaque.rs @@ -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) { @@ -115,28 +108,6 @@ impl Encoder for MemEncoder { } #[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); } @@ -481,28 +452,6 @@ impl Encoder for FileEncoder { } #[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); } @@ -556,39 +505,10 @@ impl<'a> MemDecoder<'a> { } #[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] @@ -682,38 +610,21 @@ impl<'a> Decoder for MemDecoder<'a> { } #[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)) } } diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs index a6d9c7b7d42..e1bc598736f 100644 --- a/compiler/rustc_serialize/src/serialize.rs +++ b/compiler/rustc_serialize/src/serialize.rs @@ -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; } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index d9f03fe1407..775fad1a365 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -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; diff --git a/src/tools/miri/src/operator.rs b/src/tools/miri/src/operator.rs index 79d5dfb5551..368aa2bacdc 100644 --- a/src/tools/miri/src/operator.rs +++ b/src/tools/miri/src/operator.rs @@ -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 => { diff --git a/tests/run-make/inaccessible-temp-dir/Makefile b/tests/run-make/inaccessible-temp-dir/Makefile index 25b7b87a15a..abdba4eb861 100644 --- a/tests/run-make/inaccessible-temp-dir/Makefile +++ b/tests/run-make/inaccessible-temp-dir/Makefile @@ -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 diff --git a/tests/ui/binop/eq-arr.rs b/tests/ui/binop/eq-arr.rs new file mode 100644 index 00000000000..a77c4c5aabc --- /dev/null +++ b/tests/ui/binop/eq-arr.rs @@ -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]` +} diff --git a/tests/ui/binop/eq-arr.stderr b/tests/ui/binop/eq-arr.stderr new file mode 100644 index 00000000000..a22f8e3ab0c --- /dev/null +++ b/tests/ui/binop/eq-arr.stderr @@ -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`. diff --git a/tests/ui/binop/eq-vec.rs b/tests/ui/binop/eq-vec.rs new file mode 100644 index 00000000000..17ce8df8564 --- /dev/null +++ b/tests/ui/binop/eq-vec.rs @@ -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>` +} diff --git a/tests/ui/binop/eq-vec.stderr b/tests/ui/binop/eq-vec.stderr new file mode 100644 index 00000000000..0a98cddfe05 --- /dev/null +++ b/tests/ui/binop/eq-vec.stderr @@ -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`. diff --git a/tests/ui/binop/issue-28837.stderr b/tests/ui/binop/issue-28837.stderr index bb9f3b8af0f..6c98edd3af8 100644 --- a/tests/ui/binop/issue-28837.stderr +++ b/tests/ui/binop/issue-28837.stderr @@ -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)] diff --git a/tests/ui/binop/issue-3820.stderr b/tests/ui/binop/issue-3820.stderr index c313ed6037f..cfa78a41dbf 100644 --- a/tests/ui/binop/issue-3820.stderr +++ b/tests/ui/binop/issue-3820.stderr @@ -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 diff --git a/tests/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr b/tests/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr index 9fc25f2ade4..e3b17431f89 100644 --- a/tests/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr +++ b/tests/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr @@ -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)]` | diff --git a/tests/ui/derives/derives-span-PartialEq-enum.stderr b/tests/ui/derives/derives-span-PartialEq-enum.stderr index f56e784478d..d1631732a34 100644 --- a/tests/ui/derives/derives-span-PartialEq-enum.stderr +++ b/tests/ui/derives/derives-span-PartialEq-enum.stderr @@ -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)]` | diff --git a/tests/ui/derives/derives-span-PartialEq-struct.stderr b/tests/ui/derives/derives-span-PartialEq-struct.stderr index 76c0b0104af..ab6c6951fc6 100644 --- a/tests/ui/derives/derives-span-PartialEq-struct.stderr +++ b/tests/ui/derives/derives-span-PartialEq-struct.stderr @@ -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)]` | diff --git a/tests/ui/derives/derives-span-PartialEq-tuple-struct.stderr b/tests/ui/derives/derives-span-PartialEq-tuple-struct.stderr index 7dae01dbb99..865ecad0e8e 100644 --- a/tests/ui/derives/derives-span-PartialEq-tuple-struct.stderr +++ b/tests/ui/derives/derives-span-PartialEq-tuple-struct.stderr @@ -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)]` | diff --git a/tests/ui/derives/deriving-no-inner-impl-error-message.stderr b/tests/ui/derives/deriving-no-inner-impl-error-message.stderr index 10af5d36ed9..ab99ba9fab5 100644 --- a/tests/ui/derives/deriving-no-inner-impl-error-message.stderr +++ b/tests/ui/derives/deriving-no-inner-impl-error-message.stderr @@ -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)]` | diff --git a/tests/ui/destructuring-assignment/note-unsupported.stderr b/tests/ui/destructuring-assignment/note-unsupported.stderr index 8a88332b73e..f556330070c 100644 --- a/tests/ui/destructuring-assignment/note-unsupported.stderr +++ b/tests/ui/destructuring-assignment/note-unsupported.stderr @@ -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 diff --git a/tests/ui/generator/issue-110929-generator-conflict-error-ice.rs b/tests/ui/generator/issue-110929-generator-conflict-error-ice.rs new file mode 100644 index 00000000000..9408acc15f9 --- /dev/null +++ b/tests/ui/generator/issue-110929-generator-conflict-error-ice.rs @@ -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 + }; +} diff --git a/tests/ui/generator/issue-110929-generator-conflict-error-ice.stderr b/tests/ui/generator/issue-110929-generator-conflict-error-ice.stderr new file mode 100644 index 00000000000..4d72ebe79eb --- /dev/null +++ b/tests/ui/generator/issue-110929-generator-conflict-error-ice.stderr @@ -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`. diff --git a/tests/ui/issues/issue-62375.stderr b/tests/ui/issues/issue-62375.stderr index a6fd3700edd..cd632e64fe5 100644 --- a/tests/ui/issues/issue-62375.stderr +++ b/tests/ui/issues/issue-62375.stderr @@ -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 diff --git a/tests/ui/lint/unused/lint-unused-mut-variables.rs b/tests/ui/lint/unused/lint-unused-mut-variables.rs index 67ec7facf17..5334ab5824d 100644 --- a/tests/ui/lint/unused/lint-unused-mut-variables.rs +++ b/tests/ui/lint/unused/lint-unused-mut-variables.rs @@ -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 +} diff --git a/tests/ui/lint/unused/lint-unused-mut-variables.stderr b/tests/ui/lint/unused/lint-unused-mut-variables.stderr index 805ed2b40bb..5f66c031581 100644 --- a/tests/ui/lint/unused/lint-unused-mut-variables.stderr +++ b/tests/ui/lint/unused/lint-unused-mut-variables.stderr @@ -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 diff --git a/tests/ui/mismatched_types/assignment-operator-unimplemented.stderr b/tests/ui/mismatched_types/assignment-operator-unimplemented.stderr index 2393791a9b2..66a85c4656a 100644 --- a/tests/ui/mismatched_types/assignment-operator-unimplemented.stderr +++ b/tests/ui/mismatched_types/assignment-operator-unimplemented.stderr @@ -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 diff --git a/tests/ui/or-patterns/or-patterns-syntactic-fail.stderr b/tests/ui/or-patterns/or-patterns-syntactic-fail.stderr index 10d42b7e3c0..604bba417e6 100644 --- a/tests/ui/or-patterns/or-patterns-syntactic-fail.stderr +++ b/tests/ui/or-patterns/or-patterns-syntactic-fail.stderr @@ -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 diff --git a/tests/ui/span/issue-39018.stderr b/tests/ui/span/issue-39018.stderr index 771f21c45da..bae93639271 100644 --- a/tests/ui/span/issue-39018.stderr +++ b/tests/ui/span/issue-39018.stderr @@ -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 diff --git a/tests/ui/suggestions/invalid-bin-op.stderr b/tests/ui/suggestions/invalid-bin-op.stderr index e291cedb835..570afcea643 100644 --- a/tests/ui/suggestions/invalid-bin-op.stderr +++ b/tests/ui/suggestions/invalid-bin-op.stderr @@ -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)] diff --git a/tests/ui/suggestions/restrict-type-not-param.stderr b/tests/ui/suggestions/restrict-type-not-param.stderr index 5434472ceec..3c7d42888d8 100644 --- a/tests/ui/suggestions/restrict-type-not-param.stderr +++ b/tests/ui/suggestions/restrict-type-not-param.stderr @@ -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 diff --git a/tests/ui/suggestions/suggest-mut-method-for-loop-hashmap.fixed b/tests/ui/suggestions/suggest-mut-method-for-loop-hashmap.fixed index b69bad98888..556c9543881 100644 --- a/tests/ui/suggestions/suggest-mut-method-for-loop-hashmap.fixed +++ b/tests/ui/suggestions/suggest-mut-method-for-loop-hashmap.fixed @@ -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; diff --git a/tests/ui/suggestions/suggest-mut-method-for-loop-hashmap.rs b/tests/ui/suggestions/suggest-mut-method-for-loop-hashmap.rs index 9284410dfa3..b9d49a074ea 100644 --- a/tests/ui/suggestions/suggest-mut-method-for-loop-hashmap.rs +++ b/tests/ui/suggestions/suggest-mut-method-for-loop-hashmap.rs @@ -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; diff --git a/tests/ui/suggestions/suggest-mut-method-for-loop-hashmap.stderr b/tests/ui/suggestions/suggest-mut-method-for-loop-hashmap.stderr index 74433daa6ac..c442ed6377a 100644 --- a/tests/ui/suggestions/suggest-mut-method-for-loop-hashmap.stderr +++ b/tests/ui/suggestions/suggest-mut-method-for-loop-hashmap.stderr @@ -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 diff --git a/tests/ui/type/type-unsatisfiable.usage.stderr b/tests/ui/type/type-unsatisfiable.usage.stderr index 56e2e30afac..0b76ba8eb7e 100644 --- a/tests/ui/type/type-unsatisfiable.usage.stderr +++ b/tests/ui/type/type-unsatisfiable.usage.stderr @@ -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> |
