diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index cc523fe7d08f5..c4442b34fe42b 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -139,13 +139,13 @@ impl<'hir> LoweringContext<'_, 'hir> { ExprKind::Cast(expr, ty) => { let expr = self.lower_expr(expr); let ty = - self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); + self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Cast)); hir::ExprKind::Cast(expr, ty) } ExprKind::Type(expr, ty) => { let expr = self.lower_expr(expr); let ty = - self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); + self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Cast)); hir::ExprKind::Type(expr, ty) } ExprKind::AddrOf(k, m, ohs) => { diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 2865082bd7a47..6bafbfbc14c73 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -378,8 +378,10 @@ impl<'hir> LoweringContext<'_, 'hir> { ) }); - let lowered_ty = this - .lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); + let lowered_ty = this.lower_ty( + ty, + &ImplTraitContext::Disallowed(ImplTraitPosition::ImplSelf), + ); (trait_ref, lowered_ty) }); @@ -458,7 +460,7 @@ impl<'hir> LoweringContext<'_, 'hir> { span: Span, body: Option<&Expr>, ) -> (&'hir hir::Ty<'hir>, hir::BodyId) { - let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); + let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); (ty, self.lower_const_body(span, body)) } @@ -608,8 +610,8 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ForeignItemKind::Fn(fn_dec, fn_args, generics) } ForeignItemKind::Static(t, m, _) => { - let ty = - self.lower_ty(t, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); + let ty = self + .lower_ty(t, &ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy)); hir::ForeignItemKind::Static(ty, *m) } ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type, @@ -679,11 +681,11 @@ impl<'hir> LoweringContext<'_, 'hir> { qself, path, ParamMode::ExplicitNamed, // no `'_` in declarations (Issue #61124) - &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + &ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy), ); self.arena.alloc(t) } else { - self.lower_ty(&f.ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)) + self.lower_ty(&f.ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy)) }; let hir_id = self.lower_node_id(f.id); self.lower_attrs(hir_id, &f.attrs); @@ -708,7 +710,8 @@ impl<'hir> LoweringContext<'_, 'hir> { let (generics, kind, has_default) = match &i.kind { AssocItemKind::Const(_, ty, default) => { - let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); + let ty = + self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x))); (hir::Generics::empty(), hir::TraitItemKind::Const(ty, body), body.is_some()) } @@ -746,7 +749,10 @@ impl<'hir> LoweringContext<'_, 'hir> { &ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { let ty = ty.as_ref().map(|x| { - this.lower_ty(x, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)) + this.lower_ty( + x, + &ImplTraitContext::Disallowed(ImplTraitPosition::AssocTy), + ) }); hir::TraitItemKind::Type( this.lower_param_bounds( @@ -805,7 +811,8 @@ impl<'hir> LoweringContext<'_, 'hir> { let (generics, kind) = match &i.kind { AssocItemKind::Const(_, ty, expr) => { - let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); + let ty = + self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); ( hir::Generics::empty(), hir::ImplItemKind::Const(ty, self.lower_const_body(i.span, expr.as_deref())), @@ -1441,7 +1448,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir_id: self.next_id(), bound_generic_params: self.lower_generic_params(bound_generic_params), bounded_ty: self - .lower_ty(bounded_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)), + .lower_ty(bounded_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Bound)), bounds: self.arena.alloc_from_iter(bounds.iter().map(|bound| { self.lower_param_bound( bound, @@ -1465,9 +1472,9 @@ impl<'hir> LoweringContext<'_, 'hir> { WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, span }) => { hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { lhs_ty: self - .lower_ty(lhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)), + .lower_ty(lhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Bound)), rhs_ty: self - .lower_ty(rhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)), + .lower_ty(rhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Bound)), span: self.lower_span(*span), }) } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index a04a259529310..b543be3be5083 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -253,7 +253,6 @@ enum ImplTraitContext { enum ImplTraitPosition { Path, Variable, - Type, Trait, AsyncBlock, Bound, @@ -270,6 +269,13 @@ enum ImplTraitPosition { FnTraitReturn, TraitReturn, ImplReturn, + GenericDefault, + ConstTy, + StaticTy, + AssocTy, + FieldTy, + Cast, + ImplSelf, } impl std::fmt::Display for ImplTraitPosition { @@ -277,7 +283,6 @@ impl std::fmt::Display for ImplTraitPosition { let name = match self { ImplTraitPosition::Path => "path", ImplTraitPosition::Variable => "variable binding", - ImplTraitPosition::Type => "type", ImplTraitPosition::Trait => "trait", ImplTraitPosition::AsyncBlock => "async block", ImplTraitPosition::Bound => "bound", @@ -294,6 +299,13 @@ impl std::fmt::Display for ImplTraitPosition { ImplTraitPosition::FnTraitReturn => "`Fn` trait return", ImplTraitPosition::TraitReturn => "trait method return", ImplTraitPosition::ImplReturn => "`impl` method return", + ImplTraitPosition::GenericDefault => "generic parameter default", + ImplTraitPosition::ConstTy => "const type", + ImplTraitPosition::StaticTy => "static type", + ImplTraitPosition::AssocTy => "associated type", + ImplTraitPosition::FieldTy => "field type", + ImplTraitPosition::Cast => "cast type", + ImplTraitPosition::ImplSelf => "impl header", }; write!(f, "{name}") @@ -2166,7 +2178,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { GenericParamKind::Type { default, .. } => { let kind = hir::GenericParamKind::Type { default: default.as_ref().map(|x| { - self.lower_ty(x, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)) + self.lower_ty( + x, + &ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault), + ) }), synthetic: false, }; @@ -2174,7 +2189,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { (hir::ParamName::Plain(self.lower_ident(param.ident)), kind) } GenericParamKind::Const { ty, kw_span: _, default } => { - let ty = self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); + let ty = self.lower_ty( + &ty, + &ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault), + ); let default = default.as_ref().map(|def| self.lower_anon_const(def)); ( hir::ParamName::Plain(self.lower_ident(param.ident)), diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index a89643fcfd484..c4e4e0517ece3 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1144,7 +1144,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { LateBoundRegionConversionTime::FnCall, tcx.fn_sig(method_did).subst(tcx, method_substs).input(0), ) - && infcx.can_eq(self.param_env, ty, self_ty).is_ok() + && infcx.can_eq(self.param_env, ty, self_ty) { err.span_suggestion_verbose( fn_call_span.shrink_to_lo(), diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index b4a49e1df610c..45f7c75605584 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -186,7 +186,7 @@ pub(super) fn op_to_const<'tcx>( 0, ), }; - let len = b.to_machine_usize(ecx).unwrap(); + let len = b.to_target_usize(ecx).unwrap(); let start = start.try_into().unwrap(); let len: usize = len.try_into().unwrap(); ConstValue::Slice { data, start, end: start + len } diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index d865d5bc974e0..a44f70ed05906 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -244,7 +244,7 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> { assert_eq!(args.len(), 2); let ptr = self.read_pointer(&args[0])?; - let target_align = self.read_scalar(&args[1])?.to_machine_usize(self)?; + let target_align = self.read_scalar(&args[1])?.to_target_usize(self)?; if !target_align.is_power_of_two() { throw_ub_format!("`align_offset` called with non-power-of-two align: {}", target_align); @@ -276,7 +276,7 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> { Ok(ControlFlow::Break(())) } else { // Not alignable in const, return `usize::MAX`. - let usize_max = Scalar::from_machine_usize(self.machine_usize_max(), self); + let usize_max = Scalar::from_target_usize(self.target_usize_max(), self); self.write_scalar(usize_max, dest)?; self.return_to_block(ret)?; Ok(ControlFlow::Break(())) @@ -470,8 +470,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, ecx.write_scalar(Scalar::from_u8(cmp), dest)?; } sym::const_allocate => { - let size = ecx.read_scalar(&args[0])?.to_machine_usize(ecx)?; - let align = ecx.read_scalar(&args[1])?.to_machine_usize(ecx)?; + let size = ecx.read_scalar(&args[0])?.to_target_usize(ecx)?; + let align = ecx.read_scalar(&args[1])?.to_target_usize(ecx)?; let align = match Align::from_bytes(align) { Ok(a) => a, @@ -487,8 +487,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, } sym::const_deallocate => { let ptr = ecx.read_pointer(&args[0])?; - let size = ecx.read_scalar(&args[1])?.to_machine_usize(ecx)?; - let align = ecx.read_scalar(&args[2])?.to_machine_usize(ecx)?; + let size = ecx.read_scalar(&args[1])?.to_target_usize(ecx)?; + let align = ecx.read_scalar(&args[2])?.to_target_usize(ecx)?; let size = Size::from_bytes(size); let align = match Align::from_bytes(align) { diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 3bd586c81b0bd..3cdf1e6e30c99 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -155,7 +155,7 @@ pub(crate) fn deref_mir_constant<'tcx>( // In case of unsized types, figure out the real type behind. MemPlaceMeta::Meta(scalar) => match mplace.layout.ty.kind() { ty::Str => bug!("there's no sized equivalent of a `str`"), - ty::Slice(elem_ty) => tcx.mk_array(*elem_ty, scalar.to_machine_usize(&tcx).unwrap()), + ty::Slice(elem_ty) => tcx.mk_array(*elem_ty, scalar.to_target_usize(&tcx).unwrap()), _ => bug!( "type {} should not have metadata, but had {:?}", mplace.layout.ty, diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index fc546e4de0ef6..a73f778d4db20 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -239,7 +239,7 @@ fn create_pointee_place<'tcx>( MPlaceTy::from_aligned_ptr_with_meta( ptr.into(), layout, - MemPlaceMeta::Meta(Scalar::from_machine_usize(num_elems as u64, &tcx)), + MemPlaceMeta::Meta(Scalar::from_target_usize(num_elems as u64, &tcx)), ) } else { create_mplace_from_layout(ecx, ty) @@ -355,7 +355,7 @@ fn valtree_into_mplace<'tcx>( let imm = match inner_ty.kind() { ty::Slice(_) | ty::Str => { let len = valtree.unwrap_branch().len(); - let len_scalar = Scalar::from_machine_usize(len as u64, &tcx); + let len_scalar = Scalar::from_target_usize(len as u64, &tcx); Immediate::ScalarPair( Scalar::from_maybe_pointer((*pointee_place).ptr, &tcx), @@ -426,7 +426,7 @@ fn valtree_into_mplace<'tcx>( place .offset_with_meta( offset, - MemPlaceMeta::Meta(Scalar::from_machine_usize( + MemPlaceMeta::Meta(Scalar::from_target_usize( num_elems as u64, &tcx, )), diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 9d00e338d453c..68a91eabda7b9 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -231,7 +231,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // First cast to usize. let scalar = src.to_scalar(); let addr = self.cast_from_int_like(scalar, src.layout, self.tcx.types.usize)?; - let addr = addr.to_machine_usize(self)?; + let addr = addr.to_target_usize(self)?; // Then turn address into pointer. let ptr = M::ptr_from_addr_cast(&self, addr)?; diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index d13fed7a9c263..c8bf769cfd8b7 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -639,7 +639,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } ty::Slice(_) | ty::Str => { - let len = metadata.unwrap_meta().to_machine_usize(self)?; + let len = metadata.unwrap_meta().to_target_usize(self)?; let elem = layout.field(self, 0); // Make sure the slice is not too big. diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 14cb83eb709be..8877bb479d488 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -71,7 +71,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>( sym::pref_align_of => { // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough. let layout = tcx.layout_of(param_env.and(tp_ty)).map_err(|e| err_inval!(Layout(e)))?; - ConstValue::from_machine_usize(layout.align.pref.bytes(), &tcx) + ConstValue::from_target_usize(layout.align.pref.bytes(), &tcx) } sym::type_id => { ensure_monomorphic_enough(tcx, tp_ty)?; @@ -79,7 +79,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>( } sym::variant_count => match tp_ty.kind() { // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough. - ty::Adt(adt, _) => ConstValue::from_machine_usize(adt.variants().len() as u64, &tcx), + ty::Adt(adt, _) => ConstValue::from_target_usize(adt.variants().len() as u64, &tcx), ty::Alias(..) | ty::Param(_) | ty::Placeholder(_) | ty::Infer(_) => { throw_inval!(TooGeneric) } @@ -104,7 +104,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>( | ty::GeneratorWitnessMIR(_, _) | ty::Never | ty::Tuple(_) - | ty::Error(_) => ConstValue::from_machine_usize(0u64, &tcx), + | ty::Error(_) => ConstValue::from_target_usize(0u64, &tcx), }, other => bug!("`{}` is not a zero arg intrinsic", other), }) @@ -156,7 +156,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { _ => bug!(), }; - self.write_scalar(Scalar::from_machine_usize(result, self), dest)?; + self.write_scalar(Scalar::from_target_usize(result, self), dest)?; } sym::pref_align_of @@ -302,7 +302,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } sym::offset => { let ptr = self.read_pointer(&args[0])?; - let offset_count = self.read_machine_isize(&args[1])?; + let offset_count = self.read_target_isize(&args[1])?; let pointee_ty = substs.type_at(0); let offset_ptr = self.ptr_offset_inbounds(ptr, pointee_ty, offset_count)?; @@ -310,7 +310,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } sym::arith_offset => { let ptr = self.read_pointer(&args[0])?; - let offset_count = self.read_machine_isize(&args[1])?; + let offset_count = self.read_target_isize(&args[1])?; let pointee_ty = substs.type_at(0); let pointee_size = i64::try_from(self.layout_of(pointee_ty)?.size.bytes()).unwrap(); @@ -376,7 +376,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // The signed form of the intrinsic allows this. If we interpret the // difference as isize, we'll get the proper signed difference. If that // seems *positive*, they were more than isize::MAX apart. - let dist = val.to_machine_isize(self)?; + let dist = val.to_target_isize(self)?; if dist >= 0 { throw_ub_format!( "`{}` called when first pointer is too far before second", @@ -386,7 +386,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { dist } else { // b >= a - let dist = val.to_machine_isize(self)?; + let dist = val.to_target_isize(self)?; // If converting to isize produced a *negative* result, we had an overflow // because they were more than isize::MAX apart. if dist < 0 { @@ -411,10 +411,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Perform division by size to compute return value. let ret_layout = if intrinsic_name == sym::ptr_offset_from_unsigned { - assert!(0 <= dist && dist <= self.machine_isize_max()); + assert!(0 <= dist && dist <= self.target_isize_max()); usize_layout } else { - assert!(self.machine_isize_min() <= dist && dist <= self.machine_isize_max()); + assert!(self.target_isize_min() <= dist && dist <= self.target_isize_max()); isize_layout }; let pointee_layout = self.layout_of(substs.type_at(0))?; @@ -531,12 +531,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { sym::vtable_size => { let ptr = self.read_pointer(&args[0])?; let (size, _align) = self.get_vtable_size_and_align(ptr)?; - self.write_scalar(Scalar::from_machine_usize(size.bytes(), self), dest)?; + self.write_scalar(Scalar::from_target_usize(size.bytes(), self), dest)?; } sym::vtable_align => { let ptr = self.read_pointer(&args[0])?; let (_size, align) = self.get_vtable_size_and_align(ptr)?; - self.write_scalar(Scalar::from_machine_usize(align.bytes(), self), dest)?; + self.write_scalar(Scalar::from_target_usize(align.bytes(), self), dest)?; } _ => return Ok(false), @@ -675,10 +675,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { count: &OpTy<'tcx, >::Provenance>, nonoverlapping: bool, ) -> InterpResult<'tcx> { - let count = self.read_machine_usize(&count)?; + let count = self.read_target_usize(&count)?; let layout = self.layout_of(src.layout.ty.builtin_deref(true).unwrap().ty)?; let (size, align) = (layout.size, layout.align.abi); - // `checked_mul` enforces a too small bound (the correct one would probably be machine_isize_max), + // `checked_mul` enforces a too small bound (the correct one would probably be target_isize_max), // but no actual allocation can be big enough for the difference to be noticeable. let size = size.checked_mul(count, self).ok_or_else(|| { err_ub_format!( @@ -703,9 +703,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let dst = self.read_pointer(&dst)?; let byte = self.read_scalar(&byte)?.to_u8()?; - let count = self.read_machine_usize(&count)?; + let count = self.read_target_usize(&count)?; - // `checked_mul` enforces a too small bound (the correct one would probably be machine_isize_max), + // `checked_mul` enforces a too small bound (the correct one would probably be target_isize_max), // but no actual allocation can be big enough for the difference to be noticeable. let len = layout .size diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index cfad930b1e52e..635987d039e09 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -425,7 +425,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { throw_ub!(PointerOutOfBounds { alloc_id, alloc_size, - ptr_offset: self.machine_usize_to_isize(offset.bytes()), + ptr_offset: self.target_usize_to_isize(offset.bytes()), ptr_size: size, msg, }) diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 52613d5ca1f9b..ba41019aa938c 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -52,7 +52,7 @@ impl Immediate { } pub fn new_slice(val: Scalar, len: u64, cx: &impl HasDataLayout) -> Self { - Immediate::ScalarPair(val, Scalar::from_machine_usize(len, cx)) + Immediate::ScalarPair(val, Scalar::from_target_usize(len, cx)) } pub fn new_dyn_trait( @@ -414,12 +414,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.read_scalar(op)?.to_pointer(self) } /// Read a pointer-sized unsigned integer from a place. - pub fn read_machine_usize(&self, op: &OpTy<'tcx, M::Provenance>) -> InterpResult<'tcx, u64> { - self.read_scalar(op)?.to_machine_usize(self) + pub fn read_target_usize(&self, op: &OpTy<'tcx, M::Provenance>) -> InterpResult<'tcx, u64> { + self.read_scalar(op)?.to_target_usize(self) } /// Read a pointer-sized signed integer from a place. - pub fn read_machine_isize(&self, op: &OpTy<'tcx, M::Provenance>) -> InterpResult<'tcx, i64> { - self.read_scalar(op)?.to_machine_isize(self) + pub fn read_target_isize(&self, op: &OpTy<'tcx, M::Provenance>) -> InterpResult<'tcx, i64> { + self.read_scalar(op)?.to_target_isize(self) } /// Turn the wide MPlace into a string (must already be dereferenced!) diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index f83e5ba59dc3e..88485c06ed86c 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -229,7 +229,7 @@ impl<'tcx, Prov: Provenance> MPlaceTy<'tcx, Prov> { if self.layout.is_unsized() { // We need to consult `meta` metadata match self.layout.ty.kind() { - ty::Slice(..) | ty::Str => self.mplace.meta.unwrap_meta().to_machine_usize(cx), + ty::Slice(..) | ty::Str => self.mplace.meta.unwrap_meta().to_target_usize(cx), _ => bug!("len not supported on unsized type {:?}", self.layout.ty), } } else { @@ -756,7 +756,7 @@ where mutbl: Mutability, ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> { let ptr = self.allocate_bytes_ptr(str.as_bytes(), Align::ONE, kind, mutbl)?; - let meta = Scalar::from_machine_usize(u64::try_from(str.len()).unwrap(), self); + let meta = Scalar::from_target_usize(u64::try_from(str.len()).unwrap(), self); let mplace = MemPlace { ptr: ptr.into(), meta: MemPlaceMeta::Meta(meta) }; let ty = self.tcx.mk_ref( diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index 291464ab58ae2..91da930db4fbf 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -319,7 +319,7 @@ where // implement this. ty::Array(inner, _) => (MemPlaceMeta::None, self.tcx.mk_array(*inner, inner_len)), ty::Slice(..) => { - let len = Scalar::from_machine_usize(inner_len, self); + let len = Scalar::from_target_usize(inner_len, self); (MemPlaceMeta::Meta(len), base.layout.ty) } _ => { @@ -363,7 +363,7 @@ where Index(local) => { let layout = self.layout_of(self.tcx.types.usize)?; let n = self.local_to_op(self.frame(), local, Some(layout))?; - let n = self.read_machine_usize(&n)?; + let n = self.read_target_usize(&n)?; self.place_index(base, n)? } ConstantIndex { offset, min_length, from_end } => { @@ -392,7 +392,7 @@ where Index(local) => { let layout = self.layout_of(self.tcx.types.usize)?; let n = self.local_to_op(self.frame(), local, Some(layout))?; - let n = self.read_machine_usize(&n)?; + let n = self.read_target_usize(&n)?; self.operand_index(base, n)? } ConstantIndex { offset, min_length, from_end } => { diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 7d9a98da08a9a..8252e73c5d937 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -242,7 +242,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let src = self.eval_place(place)?; let op = self.place_to_op(&src)?; let len = op.len(self)?; - self.write_scalar(Scalar::from_machine_usize(len, self), &dest)?; + self.write_scalar(Scalar::from_target_usize(len, self), &dest)?; } Ref(_, borrow_kind, place) => { @@ -297,7 +297,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { mir::NullOp::SizeOf => layout.size.bytes(), mir::NullOp::AlignOf => layout.align.abi.bytes(), }; - self.write_scalar(Scalar::from_machine_usize(val, self), &dest)?; + self.write_scalar(Scalar::from_target_usize(val, self), &dest)?; } ShallowInitBox(ref operand, _) => { diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index aa539516d5e50..820ee32047424 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -348,7 +348,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' // FIXME: check if the type/trait match what ty::Dynamic says? } ty::Slice(..) | ty::Str => { - let _len = meta.unwrap_meta().to_machine_usize(self.ecx)?; + let _len = meta.unwrap_meta().to_target_usize(self.ecx)?; // We do not check that `len * elem_size <= isize::MAX`: // that is only required for references, and there it falls out of the // "dereferenceable" check performed by Stacked Borrows. diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index bcc1d9002dfde..c5b2b6c2d7357 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -140,6 +140,18 @@ infer_lifetime_param_suggestion_elided = each elided lifetime in input position infer_region_explanation = {$pref_kind -> *[should_not_happen] [{$pref_kind}] + [ref_valid_for] ...the reference is valid for + [content_valid_for] ...but the borrowed content is only valid for + [type_obj_valid_for] object type is valid for + [source_pointer_valid_for] source pointer is only valid for + [type_satisfy] type must satisfy + [type_outlive] type must outlive + [lf_param_instantiated_with] lifetime parameter instantiated with + [lf_param_must_outlive] but lifetime parameter must outlive + [lf_instantiated_with] lifetime instantiated with + [lf_must_outlive] but lifetime must outlive + [pointer_valid_for] the pointer is valid for + [data_valid_for] but the referenced data is only valid for [empty] {""} }{$pref_kind -> [empty] {""} @@ -148,7 +160,6 @@ infer_region_explanation = {$pref_kind -> *[should_not_happen] [{$desc_kind}] [restatic] the static lifetime [revar] lifetime {$desc_arg} - [as_defined] the lifetime `{$desc_arg}` as defined here [as_defined_anon] the anonymous lifetime as defined here [defined_here] the anonymous lifetime defined here @@ -158,8 +169,16 @@ infer_region_explanation = {$pref_kind -> *[should_not_happen] [{$suff_kind}] [empty]{""} [continues] ... + [req_by_binding] {" "}as required by this binding } +infer_outlives_content = lifetime of reference outlives lifetime of borrowed content... +infer_outlives_bound = lifetime of the source pointer does not outlive lifetime bound of the object type +infer_fullfill_req_lifetime = the type `{$ty}` does not fulfill the required lifetime +infer_lf_bound_not_satisfied = lifetime bound not satisfied +infer_borrowed_too_long = a value of type `{$ty}` is borrowed for too long +infer_ref_longer_than_data = in type `{$ty}`, reference has a longer lifetime than the data it references + infer_mismatched_static_lifetime = incompatible lifetime on type infer_does_not_outlive_static_from_impl = ...does not necessarily outlive the static lifetime introduced by the compatible `impl` infer_implicit_static_lifetime_note = this has an implicit `'static` lifetime requirement @@ -308,3 +327,21 @@ infer_ril_introduced_here = `'static` requirement introduced here infer_ril_introduced_by = requirement introduced by this return type infer_ril_because_of = because of this returned expression infer_ril_static_introduced_by = "`'static` lifetime requirement introduced by the return type + +infer_where_remove = remove the `where` clause +infer_where_copy_predicates = copy the `where` clause predicates from the trait + +infer_srs_remove_and_box = consider removing this semicolon and boxing the expressions +infer_srs_remove = consider removing this semicolon +infer_srs_add = consider returning the local binding `{$ident}` +infer_srs_add_one = consider returning one of these bindings + +infer_await_both_futures = consider `await`ing on both `Future`s +infer_await_future = consider `await`ing on the `Future` +infer_await_note = calling an async function returns a future + +infer_prlf_defined_with_sub = the lifetime `{$sub_symbol}` defined here... +infer_prlf_defined_without_sub = the lifetime defined here... +infer_prlf_must_oultive_with_sup = ...must outlive the lifetime `{$sup_symbol}` defined here +infer_prlf_must_oultive_without_sup = ...must outlive the lifetime defined here +infer_prlf_known_limitation = this is a known limitation that will be removed in the future (see issue #100013 for more information) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 8c753a99a09f0..0a243b47b5c71 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -2232,7 +2232,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx.erase_regions(impl_.self_ty()), tcx.erase_regions(qself_ty), ) - .is_ok() }) && tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative }) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 50f9bbc022e7c..6b0eade2d3266 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1106,7 +1106,7 @@ fn compare_self_type<'tcx>( let infcx = tcx.infer_ctxt().build(); let self_arg_ty = tcx.liberate_late_bound_regions(method.def_id, self_arg_ty); - let can_eq_self = |ty| infcx.can_eq(param_env, untransformed_self_ty, ty).is_ok(); + let can_eq_self = |ty| infcx.can_eq(param_env, untransformed_self_ty, ty); match ExplicitSelf::determine(self_arg_ty, can_eq_self) { ExplicitSelf::ByValue => "self".to_owned(), ExplicitSelf::ByReference(_, hir::Mutability::Not) => "&self".to_owned(), diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 16e7dcd0060da..c64d507f82848 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1716,7 +1716,7 @@ fn receiver_is_valid<'tcx>( let cause = ObligationCause::new(span, wfcx.body_def_id, traits::ObligationCauseCode::MethodReceiver); - let can_eq_self = |ty| infcx.can_eq(wfcx.param_env, self_ty, ty).is_ok(); + let can_eq_self = |ty| infcx.can_eq(wfcx.param_env, self_ty, ty); // `self: Self` is always valid. if can_eq_self(receiver_ty) { diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index ae00042eae73d..149c7dbef22f5 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -321,7 +321,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut param_args = FxHashMap::default(); let mut param_expected = FxHashMap::default(); let mut param_found = FxHashMap::default(); - if self.can_eq(self.param_env, ty, found).is_ok() { + if self.can_eq(self.param_env, ty, found) { // We only point at the first place where the found type was inferred. for (i, param_ty) in sig.inputs().skip_binder().iter().skip(1).enumerate() { if def_self_ty.contains(*param_ty) && let ty::Param(_) = param_ty.kind() { @@ -369,7 +369,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for (param, (arg, arg_ty)) in param_args.iter() { let Some(expected) = param_expected.get(param) else { continue; }; let Some(found) = param_found.get(param) else { continue; }; - if self.can_eq(self.param_env, *arg_ty, *found).is_err() { continue; } + if !self.can_eq(self.param_env, *arg_ty, *found) { continue; } self.emit_coerce_suggestions(err, arg, *found, *expected, None, None); } @@ -379,7 +379,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } if ty != prev && param_args.is_empty() - && self.can_eq(self.param_env, ty, found).is_ok() + && self.can_eq(self.param_env, ty, found) { // We only point at the first place where the found type was inferred. if !segment.ident.span.overlaps(mismatch_span) { @@ -401,7 +401,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } if ty != prev && let Some(span) = prev_span - && self.can_eq(self.param_env, ty, found).is_ok() + && self.can_eq(self.param_env, ty, found) { // We only point at the first place where the found type was inferred. // We use the *previous* span because if the type is known *here* it means @@ -764,7 +764,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let ty::Adt(expected_adt, substs) = expected.kind() { if let hir::ExprKind::Field(base, ident) = expr.kind { let base_ty = self.typeck_results.borrow().expr_ty(base); - if self.can_eq(self.param_env, base_ty, expected).is_ok() + if self.can_eq(self.param_env, base_ty, expected) && let Some(base_span) = base.span.find_ancestor_inside(expr.span) { err.span_suggestion_verbose( @@ -1357,7 +1357,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, ref expr), _, &ty::Ref(_, checked, _), - ) if self.can_sub(self.param_env, checked, expected).is_ok() => { + ) if self.can_sub(self.param_env, checked, expected) => { // We have `&T`, check if what was expected was `T`. If so, // we may want to suggest removing a `&`. if sm.is_imported(expr.span) { @@ -2003,7 +2003,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let hir::StmtKind::Semi(tail_expr) = stmt.kind else { return; }; let Some(ty) = self.node_ty_opt(tail_expr.hir_id) else { return; }; - if self.can_eq(self.param_env, expected_ty, ty).is_ok() { + if self.can_eq(self.param_env, expected_ty, ty) { err.span_suggestion_short( stmt.span.with_lo(tail_expr.span.hi()), "remove this semicolon", diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index eaad57d8c2e9f..7ce721e94cb23 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1015,7 +1015,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let expr_inner_ty = substs.type_at(0); let expected_inner_ty = expected_substs.type_at(0); if let ty::Ref(_, ty, hir::Mutability::Not) = expr_inner_ty.kind() - && self.can_eq(self.param_env, *ty, expected_inner_ty).is_ok() + && self.can_eq(self.param_env, *ty, expected_inner_ty) { let def_path = self.tcx.def_path_str(adt_def.did()); if self.type_is_copy_modulo_regions(self.param_env, *ty, expr.span) { @@ -1054,7 +1054,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(result_did) = self.tcx.get_diagnostic_item(sym::Result) && adt_def.did() == result_did // Check that the error types are equal - && self.can_eq(self.param_env, substs.type_at(1), expected_substs.type_at(1)).is_ok() + && self.can_eq(self.param_env, substs.type_at(1), expected_substs.type_at(1)) { return suggest_copied_or_cloned(); } else if let Some(option_did) = self.tcx.get_diagnostic_item(sym::Option) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index b5e6727bfbadf..287a5bf0067c3 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -936,7 +936,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { return false; } } - self.can_sub(self.param_env, fty.output(), expected).is_ok() + self.can_sub(self.param_env, fty.output(), expected) }), _ => false, } diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index e909511346dce..3881efe87db5c 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -90,7 +90,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual)?; if let Some(expr) = ti.origin_expr { self.suggest_fn_call(&mut diag, expr, expected, |output| { - self.can_eq(self.param_env, output, actual).is_ok() + self.can_eq(self.param_env, output, actual) }); } Some(diag) @@ -675,7 +675,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { match (expected.kind(), actual.kind(), ba) { (ty::Ref(_, inner_ty, _), _, hir::BindingAnnotation::NONE) - if self.can_eq(self.param_env, *inner_ty, actual).is_ok() => + if self.can_eq(self.param_env, *inner_ty, actual) => { err.span_suggestion_verbose( span.shrink_to_lo(), @@ -685,7 +685,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } (_, ty::Ref(_, inner_ty, _), hir::BindingAnnotation::REF) - if self.can_eq(self.param_env, expected, *inner_ty).is_ok() => + if self.can_eq(self.param_env, expected, *inner_ty) => { err.span_suggestion_verbose( span.with_hi(span.lo() + BytePos(4)), diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 8bf3a160abbb4..0c2713fb1a7c8 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -933,3 +933,216 @@ pub struct ButNeedsToSatisfy { pub has_lifetime: bool, pub lifetime: String, } + +#[derive(Diagnostic)] +#[diag(infer_outlives_content, code = "E0312")] +pub struct OutlivesContent<'a> { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub notes: Vec>, +} + +#[derive(Diagnostic)] +#[diag(infer_outlives_bound, code = "E0476")] +pub struct OutlivesBound<'a> { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub notes: Vec>, +} + +#[derive(Diagnostic)] +#[diag(infer_fullfill_req_lifetime, code = "E0477")] +pub struct FullfillReqLifetime<'a> { + #[primary_span] + pub span: Span, + pub ty: Ty<'a>, + #[subdiagnostic] + pub note: Option>, +} + +#[derive(Diagnostic)] +#[diag(infer_lf_bound_not_satisfied, code = "E0478")] +pub struct LfBoundNotSatisfied<'a> { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub notes: Vec>, +} + +#[derive(Diagnostic)] +#[diag(infer_ref_longer_than_data, code = "E0491")] +pub struct RefLongerThanData<'a> { + #[primary_span] + pub span: Span, + pub ty: Ty<'a>, + #[subdiagnostic] + pub notes: Vec>, +} + +#[derive(Subdiagnostic)] +pub enum WhereClauseSuggestions { + #[suggestion( + infer_where_remove, + code = "", + applicability = "machine-applicable", + style = "verbose" + )] + Remove { + #[primary_span] + span: Span, + }, + #[suggestion( + infer_where_copy_predicates, + code = "{space}where {trait_predicates}", + applicability = "machine-applicable", + style = "verbose" + )] + CopyPredicates { + #[primary_span] + span: Span, + space: &'static str, + trait_predicates: String, + }, +} + +#[derive(Subdiagnostic)] +pub enum SuggestRemoveSemiOrReturnBinding { + #[multipart_suggestion(infer_srs_remove_and_box, applicability = "machine-applicable")] + RemoveAndBox { + #[suggestion_part(code = "Box::new(")] + first_lo: Span, + #[suggestion_part(code = ")")] + first_hi: Span, + #[suggestion_part(code = "Box::new(")] + second_lo: Span, + #[suggestion_part(code = ")")] + second_hi: Span, + #[suggestion_part(code = "")] + sp: Span, + }, + #[suggestion( + infer_srs_remove, + style = "short", + code = "", + applicability = "machine-applicable" + )] + Remove { + #[primary_span] + sp: Span, + }, + #[suggestion( + infer_srs_add, + style = "verbose", + code = "{code}", + applicability = "maybe-incorrect" + )] + Add { + #[primary_span] + sp: Span, + code: String, + ident: Ident, + }, + #[note(infer_srs_add_one)] + AddOne { + #[primary_span] + spans: MultiSpan, + }, +} + +#[derive(Subdiagnostic)] +pub enum ConsiderAddingAwait { + #[help(infer_await_both_futures)] + BothFuturesHelp, + #[multipart_suggestion(infer_await_both_futures, applicability = "maybe-incorrect")] + BothFuturesSugg { + #[suggestion_part(code = ".await")] + first: Span, + #[suggestion_part(code = ".await")] + second: Span, + }, + #[suggestion( + infer_await_future, + code = ".await", + style = "verbose", + applicability = "maybe-incorrect" + )] + FutureSugg { + #[primary_span] + span: Span, + }, + #[note(infer_await_note)] + FutureSuggNote { + #[primary_span] + span: Span, + }, + #[multipart_suggestion( + infer_await_future, + style = "verbose", + applicability = "maybe-incorrect" + )] + FutureSuggMultiple { + #[suggestion_part(code = ".await")] + spans: Vec, + }, +} + +#[derive(Diagnostic)] +pub enum PlaceholderRelationLfNotSatisfied { + #[diag(infer_lf_bound_not_satisfied)] + HasBoth { + #[primary_span] + span: Span, + #[note(infer_prlf_defined_with_sub)] + sub_span: Span, + #[note(infer_prlf_must_oultive_with_sup)] + sup_span: Span, + sub_symbol: Symbol, + sup_symbol: Symbol, + #[note(infer_prlf_known_limitation)] + note: (), + }, + #[diag(infer_lf_bound_not_satisfied)] + HasSub { + #[primary_span] + span: Span, + #[note(infer_prlf_defined_with_sub)] + sub_span: Span, + #[note(infer_prlf_must_oultive_without_sup)] + sup_span: Span, + sub_symbol: Symbol, + #[note(infer_prlf_known_limitation)] + note: (), + }, + #[diag(infer_lf_bound_not_satisfied)] + HasSup { + #[primary_span] + span: Span, + #[note(infer_prlf_defined_without_sub)] + sub_span: Span, + #[note(infer_prlf_must_oultive_with_sup)] + sup_span: Span, + sup_symbol: Symbol, + #[note(infer_prlf_known_limitation)] + note: (), + }, + #[diag(infer_lf_bound_not_satisfied)] + HasNone { + #[primary_span] + span: Span, + #[note(infer_prlf_defined_without_sub)] + sub_span: Span, + #[note(infer_prlf_must_oultive_without_sup)] + sup_span: Span, + #[note(infer_prlf_known_limitation)] + note: (), + }, + #[diag(infer_lf_bound_not_satisfied)] + OnlyPrimarySpan { + #[primary_span] + span: Span, + #[note(infer_prlf_known_limitation)] + note: (), + }, +} diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs index 5d861a78af800..cb96aeec5f34f 100644 --- a/compiler/rustc_infer/src/errors/note_and_explain.rs +++ b/compiler/rustc_infer/src/errors/note_and_explain.rs @@ -121,16 +121,42 @@ impl<'a> DescriptionCtx<'a> { pub enum PrefixKind { Empty, + RefValidFor, + ContentValidFor, + TypeObjValidFor, + SourcePointerValidFor, + TypeSatisfy, + TypeOutlive, + LfParamInstantiatedWith, + LfParamMustOutlive, + LfInstantiatedWith, + LfMustOutlive, + PointerValidFor, + DataValidFor, } pub enum SuffixKind { + Empty, Continues, + ReqByBinding, } impl IntoDiagnosticArg for PrefixKind { fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { let kind = match self { Self::Empty => "empty", + Self::RefValidFor => "ref_valid_for", + Self::ContentValidFor => "content_valid_for", + Self::TypeObjValidFor => "type_obj_valid_for", + Self::SourcePointerValidFor => "source_pointer_valid_for", + Self::TypeSatisfy => "type_satisfy", + Self::TypeOutlive => "type_outlive", + Self::LfParamInstantiatedWith => "lf_param_instantiated_with", + Self::LfParamMustOutlive => "lf_param_must_outlive", + Self::LfInstantiatedWith => "lf_instantiated_with", + Self::LfMustOutlive => "lf_must_outlive", + Self::PointerValidFor => "pointer_valid_for", + Self::DataValidFor => "data_valid_for", } .into(); rustc_errors::DiagnosticArgValue::Str(kind) @@ -140,7 +166,9 @@ impl IntoDiagnosticArg for PrefixKind { impl IntoDiagnosticArg for SuffixKind { fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { let kind = match self { + Self::Empty => "empty", Self::Continues => "continues", + Self::ReqByBinding => "req_by_binding", } .into(); rustc_errors::DiagnosticArgValue::Str(kind) @@ -166,17 +194,19 @@ impl RegionExplanation<'_> { } impl AddToDiagnostic for RegionExplanation<'_> { - fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) + fn add_to_diagnostic_with(self, diag: &mut Diagnostic, f: F) where F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, { - if let Some(span) = self.desc.span { - diag.span_note(span, fluent::infer_region_explanation); - } else { - diag.note(fluent::infer_region_explanation); - } - self.desc.add_to(diag); diag.set_arg("pref_kind", self.prefix); diag.set_arg("suff_kind", self.suffix); + let desc_span = self.desc.span; + self.desc.add_to(diag); + let msg = f(diag, fluent::infer_region_explanation.into()); + if let Some(span) = desc_span { + diag.span_note(span, msg); + } else { + diag.note(msg); + } } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 1d3fcf7571ebc..bb7947e3141ba 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -751,15 +751,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }; let msg = "`match` arms have incompatible types"; err.span_label(outer, msg); - self.suggest_remove_semi_or_return_binding( - err, + if let Some(subdiag) = self.suggest_remove_semi_or_return_binding( prior_arm_block_id, prior_arm_ty, prior_arm_span, arm_block_id, arm_ty, arm_span, - ); + ) { + err.subdiagnostic(subdiag); + } if let Some(ret_sp) = opt_suggest_box_span { // Get return type span and point to it. self.suggest_boxing_for_return_impl_trait( @@ -784,15 +785,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if let Some(sp) = outer_span { err.span_label(sp, "`if` and `else` have incompatible types"); } - self.suggest_remove_semi_or_return_binding( - err, + if let Some(subdiag) = self.suggest_remove_semi_or_return_binding( Some(then_id), then_ty, then_span, Some(else_id), else_ty, else_span, - ); + ) { + err.subdiagnostic(subdiag); + } if let Some(ret_sp) = opt_suggest_box_span { self.suggest_boxing_for_return_impl_trait( err, diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs index 9534bce54ef0e..e8d94f0c04eaa 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs @@ -1,5 +1,8 @@ -use crate::infer::{ - error_reporting::nice_region_error::NiceRegionError, RegionResolutionError, SubregionOrigin, +use crate::{ + errors::PlaceholderRelationLfNotSatisfied, + infer::{ + error_reporting::nice_region_error::NiceRegionError, RegionResolutionError, SubregionOrigin, + }, }; use rustc_data_structures::intern::Interned; use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed}; @@ -16,8 +19,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { Region(Interned(RePlaceholder(ty::Placeholder { name: sub_name, .. }), _)), Region(Interned(RePlaceholder(ty::Placeholder { name: sup_name, .. }), _)), )) => { - let msg = "lifetime bound not satisfied"; - let mut err = self.tcx().sess.struct_span_err(*span, msg); + let span = *span; let (sub_span, sub_symbol) = match sub_name { ty::BrNamed(def_id, symbol) => { (Some(self.tcx().def_span(def_id)), Some(symbol)) @@ -32,41 +34,47 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { ty::BrAnon(_, span) => (*span, None), ty::BrEnv => (None, None), }; - match (sub_span, sup_span, sub_symbol, sup_symbol) { - (Some(sub_span), Some(sup_span), Some(sub_symbol), Some(sup_symbol)) => { - err.span_note( + let diag = match (sub_span, sup_span, sub_symbol, sup_symbol) { + (Some(sub_span), Some(sup_span), Some(&sub_symbol), Some(&sup_symbol)) => { + PlaceholderRelationLfNotSatisfied::HasBoth { + span, sub_span, - format!("the lifetime `{sub_symbol}` defined here..."), - ); - err.span_note( sup_span, - format!("...must outlive the lifetime `{sup_symbol}` defined here"), - ); + sub_symbol, + sup_symbol, + note: (), + } } - (Some(sub_span), Some(sup_span), _, Some(sup_symbol)) => { - err.span_note(sub_span, "the lifetime defined here..."); - err.span_note( + (Some(sub_span), Some(sup_span), _, Some(&sup_symbol)) => { + PlaceholderRelationLfNotSatisfied::HasSup { + span, + sub_span, sup_span, - format!("...must outlive the lifetime `{sup_symbol}` defined here"), - ); + sup_symbol, + note: (), + } } - (Some(sub_span), Some(sup_span), Some(sub_symbol), _) => { - err.span_note( + (Some(sub_span), Some(sup_span), Some(&sub_symbol), _) => { + PlaceholderRelationLfNotSatisfied::HasSub { + span, sub_span, - format!("the lifetime `{sub_symbol}` defined here..."), - ); - err.span_note(sup_span, "...must outlive the lifetime defined here"); + sup_span, + sub_symbol, + note: (), + } } (Some(sub_span), Some(sup_span), _, _) => { - err.span_note(sub_span, "the lifetime defined here..."); - err.span_note(sup_span, "...must outlive the lifetime defined here"); + PlaceholderRelationLfNotSatisfied::HasNone { + span, + sub_span, + sup_span, + note: (), + } } - _ => {} - } - err.note("this is a known limitation that will be removed in the future (see issue #100013 for more information)"); - Some(err) + _ => PlaceholderRelationLfNotSatisfied::OnlyPrimarySpan { span, note: () }, + }; + Some(self.tcx().sess.create_err(diag)) } - _ => None, } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index bdd09a995dc23..e0e89158a5838 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -1,9 +1,11 @@ -use crate::errors::RegionOriginNote; +use crate::errors::{ + note_and_explain, FullfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, OutlivesContent, + RefLongerThanData, RegionOriginNote, WhereClauseSuggestions, +}; use crate::infer::error_reporting::{note_and_explain_region, TypeErrCtxt}; use crate::infer::{self, SubregionOrigin}; use rustc_errors::{ - fluent, struct_span_err, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, - ErrorGuaranteed, + fluent, AddToDiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, }; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::traits::ObligationCauseCode; @@ -119,130 +121,105 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err } infer::Reborrow(span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0312, - "lifetime of reference outlives lifetime of borrowed content..." - ); - note_and_explain_region( + let reference_valid = note_and_explain::RegionExplanation::new( self.tcx, - &mut err, - "...the reference is valid for ", sub, - "...", None, + note_and_explain::PrefixKind::RefValidFor, + note_and_explain::SuffixKind::Continues, ); - note_and_explain_region( + let content_valid = note_and_explain::RegionExplanation::new( self.tcx, - &mut err, - "...but the borrowed content is only valid for ", sup, - "", None, + note_and_explain::PrefixKind::ContentValidFor, + note_and_explain::SuffixKind::Empty, ); - err + OutlivesContent { + span, + notes: reference_valid.into_iter().chain(content_valid).collect(), + } + .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) } infer::RelateObjectBound(span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0476, - "lifetime of the source pointer does not outlive lifetime bound of the \ - object type" - ); - note_and_explain_region( + let object_valid = note_and_explain::RegionExplanation::new( self.tcx, - &mut err, - "object type is valid for ", sub, - "", None, + note_and_explain::PrefixKind::TypeObjValidFor, + note_and_explain::SuffixKind::Empty, ); - note_and_explain_region( + let pointer_valid = note_and_explain::RegionExplanation::new( self.tcx, - &mut err, - "source pointer is only valid for ", sup, - "", None, + note_and_explain::PrefixKind::SourcePointerValidFor, + note_and_explain::SuffixKind::Empty, ); - err + OutlivesBound { + span, + notes: object_valid.into_iter().chain(pointer_valid).collect(), + } + .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) } infer::RelateParamBound(span, ty, opt_span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0477, - "the type `{}` does not fulfill the required lifetime", - self.ty_to_string(ty) + let prefix = match *sub { + ty::ReStatic => note_and_explain::PrefixKind::TypeSatisfy, + _ => note_and_explain::PrefixKind::TypeOutlive, + }; + let suffix = if opt_span.is_some() { + note_and_explain::SuffixKind::ReqByBinding + } else { + note_and_explain::SuffixKind::Empty + }; + let note = note_and_explain::RegionExplanation::new( + self.tcx, sub, opt_span, prefix, suffix, ); - match *sub { - ty::ReStatic => note_and_explain_region( - self.tcx, - &mut err, - "type must satisfy ", - sub, - if opt_span.is_some() { " as required by this binding" } else { "" }, - opt_span, - ), - _ => note_and_explain_region( - self.tcx, - &mut err, - "type must outlive ", - sub, - if opt_span.is_some() { " as required by this binding" } else { "" }, - opt_span, - ), - } - err + FullfillReqLifetime { span, ty: self.resolve_vars_if_possible(ty), note } + .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) } infer::RelateRegionParamBound(span) => { - let mut err = - struct_span_err!(self.tcx.sess, span, E0478, "lifetime bound not satisfied"); - note_and_explain_region( + let param_instantiated = note_and_explain::RegionExplanation::new( self.tcx, - &mut err, - "lifetime parameter instantiated with ", sup, - "", None, + note_and_explain::PrefixKind::LfParamInstantiatedWith, + note_and_explain::SuffixKind::Empty, ); - note_and_explain_region( + let param_must_outlive = note_and_explain::RegionExplanation::new( self.tcx, - &mut err, - "but lifetime parameter must outlive ", sub, - "", None, + note_and_explain::PrefixKind::LfParamMustOutlive, + note_and_explain::SuffixKind::Empty, ); - err + LfBoundNotSatisfied { + span, + notes: param_instantiated.into_iter().chain(param_must_outlive).collect(), + } + .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) } infer::ReferenceOutlivesReferent(ty, span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0491, - "in type `{}`, reference has a longer lifetime than the data it references", - self.ty_to_string(ty) - ); - note_and_explain_region( + let pointer_valid = note_and_explain::RegionExplanation::new( self.tcx, - &mut err, - "the pointer is valid for ", sub, - "", None, + note_and_explain::PrefixKind::PointerValidFor, + note_and_explain::SuffixKind::Empty, ); - note_and_explain_region( + let data_valid = note_and_explain::RegionExplanation::new( self.tcx, - &mut err, - "but the referenced data is only valid for ", sup, - "", None, + note_and_explain::PrefixKind::DataValidFor, + note_and_explain::SuffixKind::Empty, ); - err + RefLongerThanData { + span, + ty: self.resolve_vars_if_possible(ty), + notes: pointer_valid.into_iter().chain(data_valid).collect(), + } + .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) } infer::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id } => { let mut err = self.report_extra_impl_obligation( @@ -279,25 +256,25 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err } infer::AscribeUserTypeProvePredicate(span) => { - let mut err = - struct_span_err!(self.tcx.sess, span, E0478, "lifetime bound not satisfied"); - note_and_explain_region( + let instantiated = note_and_explain::RegionExplanation::new( self.tcx, - &mut err, - "lifetime instantiated with ", sup, - "", None, + note_and_explain::PrefixKind::LfInstantiatedWith, + note_and_explain::SuffixKind::Empty, ); - note_and_explain_region( + let must_outlive = note_and_explain::RegionExplanation::new( self.tcx, - &mut err, - "but lifetime must outlive ", sub, - "", None, + note_and_explain::PrefixKind::LfMustOutlive, + note_and_explain::SuffixKind::Empty, ); - err + LfBoundNotSatisfied { + span, + notes: instantiated.into_iter().chain(must_outlive).collect(), + } + .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) } }; if sub.is_error() || sup.is_error() { @@ -347,22 +324,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let Some(generics) = self.tcx.hir().get_generics(impl_item_def_id) else { return; }; - if trait_predicates.is_empty() { - err.span_suggestion_verbose( - generics.where_clause_span, - "remove the `where` clause", - String::new(), - Applicability::MachineApplicable, - ); + let suggestion = if trait_predicates.is_empty() { + WhereClauseSuggestions::Remove { span: generics.where_clause_span } } else { let space = if generics.where_clause_span.is_empty() { " " } else { "" }; - err.span_suggestion_verbose( - generics.where_clause_span, - "copy the `where` clause predicates from the trait", - format!("{space}where {}", trait_predicates.join(", ")), - Applicability::MachineApplicable, - ); - } + WhereClauseSuggestions::CopyPredicates { + span: generics.where_clause_span, + space, + trait_predicates: trait_predicates.join(", "), + } + }; + err.subdiagnostic(suggestion); } pub(super) fn report_placeholder_failure( diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index 984e8cf6a0eb9..b6337d6853fa3 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -504,7 +504,9 @@ fn foo(&self) -> Self::T { String::new() } let methods: Vec<(Span, String)> = items .in_definition_order() .filter(|item| { - ty::AssocKind::Fn == item.kind && Some(item.name) != current_method_ident + ty::AssocKind::Fn == item.kind + && Some(item.name) != current_method_ident + && !tcx.is_doc_hidden(item.def_id) }) .filter_map(|item| { let method = tcx.fn_sig(item.def_id).subst_identity(); @@ -576,7 +578,7 @@ fn foo(&self) -> Self::T { String::new() } tcx.impl_defaultness(item.id.owner_id) { let assoc_ty = tcx.bound_type_of(item.id.owner_id).subst_identity(); - if self.infcx.can_eq(param_env, assoc_ty, found).is_ok() { + if self.infcx.can_eq(param_env, assoc_ty, found) { diag.span_label( item.span, "associated type defaults can't be assumed inside the \ @@ -598,7 +600,7 @@ fn foo(&self) -> Self::T { String::new() } if let hir::AssocItemKind::Type = item.kind { let assoc_ty = tcx.bound_type_of(item.id.owner_id).subst_identity(); - if self.infcx.can_eq(param_env, assoc_ty, found).is_ok() { + if self.infcx.can_eq(param_env, assoc_ty, found) { diag.span_label(item.span, "expected this associated type"); return true; } diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index 7d9a53d1c025f..18c5097a26289 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -11,21 +11,22 @@ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TypeVisitable}; use rustc_span::{sym, BytePos, Span}; -use crate::errors::SuggAddLetForLetChains; +use crate::errors::{ + ConsiderAddingAwait, SuggAddLetForLetChains, SuggestRemoveSemiOrReturnBinding, +}; use super::TypeErrCtxt; impl<'tcx> TypeErrCtxt<'_, 'tcx> { pub(super) fn suggest_remove_semi_or_return_binding( &self, - err: &mut Diagnostic, first_id: Option, first_ty: Ty<'tcx>, first_span: Span, second_id: Option, second_ty: Ty<'tcx>, second_span: Span, - ) { + ) -> Option { let remove_semicolon = [ (first_id, self.resolve_vars_if_possible(second_ty)), (second_id, self.resolve_vars_if_possible(first_ty)), @@ -37,35 +38,29 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }); match remove_semicolon { Some((sp, StatementAsExpression::NeedsBoxing)) => { - err.multipart_suggestion( - "consider removing this semicolon and boxing the expressions", - vec![ - (first_span.shrink_to_lo(), "Box::new(".to_string()), - (first_span.shrink_to_hi(), ")".to_string()), - (second_span.shrink_to_lo(), "Box::new(".to_string()), - (second_span.shrink_to_hi(), ")".to_string()), - (sp, String::new()), - ], - Applicability::MachineApplicable, - ); + Some(SuggestRemoveSemiOrReturnBinding::RemoveAndBox { + first_lo: first_span.shrink_to_lo(), + first_hi: first_span.shrink_to_hi(), + second_lo: second_span.shrink_to_lo(), + second_hi: second_span.shrink_to_hi(), + sp, + }) } Some((sp, StatementAsExpression::CorrectType)) => { - err.span_suggestion_short( - sp, - "consider removing this semicolon", - "", - Applicability::MachineApplicable, - ); + Some(SuggestRemoveSemiOrReturnBinding::Remove { sp }) } None => { + let mut ret = None; for (id, ty) in [(first_id, second_ty), (second_id, first_ty)] { if let Some(id) = id && let hir::Node::Block(blk) = self.tcx.hir().get(id) - && self.consider_returning_binding(blk, ty, err) + && let Some(diag) = self.consider_returning_binding_diag(blk, ty) { + ret = Some(diag); break; } } + ret } } } @@ -198,7 +193,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { return; } - match ( + let subdiag = match ( self.get_impl_future_output_ty(exp_found.expected), self.get_impl_future_output_ty(exp_found.found), ) { @@ -207,65 +202,56 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { { ObligationCauseCode::IfExpression(box IfExpressionCause { then_id, .. }) => { let then_span = self.find_block_span_from_hir_id(*then_id); - diag.multipart_suggestion( - "consider `await`ing on both `Future`s", - vec![ - (then_span.shrink_to_hi(), ".await".to_string()), - (exp_span.shrink_to_hi(), ".await".to_string()), - ], - Applicability::MaybeIncorrect, - ); + Some(ConsiderAddingAwait::BothFuturesSugg { + first: then_span.shrink_to_hi(), + second: exp_span.shrink_to_hi(), + }) } ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { prior_arms, .. }) => { if let [.., arm_span] = &prior_arms[..] { - diag.multipart_suggestion( - "consider `await`ing on both `Future`s", - vec![ - (arm_span.shrink_to_hi(), ".await".to_string()), - (exp_span.shrink_to_hi(), ".await".to_string()), - ], - Applicability::MaybeIncorrect, - ); + Some(ConsiderAddingAwait::BothFuturesSugg { + first: arm_span.shrink_to_hi(), + second: exp_span.shrink_to_hi(), + }) } else { - diag.help("consider `await`ing on both `Future`s"); + Some(ConsiderAddingAwait::BothFuturesHelp) } } - _ => { - diag.help("consider `await`ing on both `Future`s"); - } + _ => Some(ConsiderAddingAwait::BothFuturesHelp), }, (_, Some(ty)) if self.same_type_modulo_infer(exp_found.expected, ty) => { - self.suggest_await_on_future(diag, exp_span); - diag.span_note(exp_span, "calling an async function returns a future"); + // FIXME: Seems like we can't have a suggestion and a note with different spans in a single subdiagnostic + diag.subdiagnostic(ConsiderAddingAwait::FutureSugg { + span: exp_span.shrink_to_hi(), + }); + Some(ConsiderAddingAwait::FutureSuggNote { span: exp_span }) } (Some(ty), _) if self.same_type_modulo_infer(ty, exp_found.found) => match cause.code() { ObligationCauseCode::Pattern { span: Some(then_span), .. } => { - self.suggest_await_on_future(diag, then_span.shrink_to_hi()); + Some(ConsiderAddingAwait::FutureSugg { span: then_span.shrink_to_hi() }) } ObligationCauseCode::IfExpression(box IfExpressionCause { then_id, .. }) => { let then_span = self.find_block_span_from_hir_id(*then_id); - self.suggest_await_on_future(diag, then_span.shrink_to_hi()); + Some(ConsiderAddingAwait::FutureSugg { span: then_span.shrink_to_hi() }) } ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { ref prior_arms, .. - }) => { - diag.multipart_suggestion_verbose( - "consider `await`ing on the `Future`", - prior_arms - .iter() - .map(|arm| (arm.shrink_to_hi(), ".await".to_string())) - .collect(), - Applicability::MaybeIncorrect, - ); - } - _ => {} + }) => Some({ + ConsiderAddingAwait::FutureSuggMultiple { + spans: prior_arms.iter().map(|arm| arm.shrink_to_hi()).collect(), + } + }), + _ => None, }, - _ => {} + _ => None, + }; + if let Some(subdiag) = subdiag { + diag.subdiagnostic(subdiag); } } @@ -655,16 +641,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { /// Suggest returning a local binding with a compatible type if the block /// has no return expression. - pub fn consider_returning_binding( + pub fn consider_returning_binding_diag( &self, blk: &'tcx hir::Block<'tcx>, expected_ty: Ty<'tcx>, - err: &mut Diagnostic, - ) -> bool { + ) -> Option { let blk = blk.innermost_block(); // Do not suggest if we have a tail expr. if blk.expr.is_some() { - return false; + return None; } let mut shadowed = FxIndexSet::default(); let mut candidate_idents = vec![]; @@ -733,7 +718,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { match &candidate_idents[..] { [(ident, _ty)] => { let sm = self.tcx.sess.source_map(); - if let Some(stmt) = blk.stmts.last() { + let (span, sugg) = if let Some(stmt) = blk.stmts.last() { let stmt_span = sm.stmt_span(stmt.span, blk.span); let sugg = if sm.is_multiline(blk.span) && let Some(spacing) = sm.indentation_before(stmt_span) @@ -742,12 +727,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } else { format!(" {ident}") }; - err.span_suggestion_verbose( - stmt_span.shrink_to_hi(), - format!("consider returning the local binding `{ident}`"), - sugg, - Applicability::MaybeIncorrect, - ); + (stmt_span.shrink_to_hi(), sugg) } else { let sugg = if sm.is_multiline(blk.span) && let Some(spacing) = sm.indentation_before(blk.span.shrink_to_lo()) @@ -757,21 +737,34 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { format!(" {ident} ") }; let left_span = sm.span_through_char(blk.span, '{').shrink_to_hi(); - err.span_suggestion_verbose( + ( sm.span_extend_while(left_span, |c| c.is_whitespace()).unwrap_or(left_span), - format!("consider returning the local binding `{ident}`"), sugg, - Applicability::MaybeIncorrect, - ); - } - true + ) + }; + Some(SuggestRemoveSemiOrReturnBinding::Add { sp: span, code: sugg, ident: *ident }) } values if (1..3).contains(&values.len()) => { let spans = values.iter().map(|(ident, _)| ident.span).collect::>(); - err.span_note(spans, "consider returning one of these bindings"); + Some(SuggestRemoveSemiOrReturnBinding::AddOne { spans: spans.into() }) + } + _ => None, + } + } + + pub fn consider_returning_binding( + &self, + blk: &'tcx hir::Block<'tcx>, + expected_ty: Ty<'tcx>, + err: &mut Diagnostic, + ) -> bool { + let diag = self.consider_returning_binding_diag(blk, expected_ty); + match diag { + Some(diag) => { + err.subdiagnostic(diag); true } - _ => false, + None => false, } } } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index b5a10ea659037..17e734f070032 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -880,30 +880,20 @@ impl<'tcx> InferCtxt<'tcx> { self.inner.borrow_mut().unwrap_region_constraints().add_given(sub, sup); } - pub fn can_sub(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> UnitResult<'tcx> + pub fn can_sub(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool where T: at::ToTrace<'tcx>, { let origin = &ObligationCause::dummy(); - self.probe(|_| { - self.at(origin, param_env).sub(a, b).map(|InferOk { obligations: _, .. }| { - // Ignore obligations, since we are unrolling - // everything anyway. - }) - }) + self.probe(|_| self.at(origin, param_env).sub(a, b).is_ok()) } - pub fn can_eq(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> UnitResult<'tcx> + pub fn can_eq(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool where T: at::ToTrace<'tcx>, { let origin = &ObligationCause::dummy(); - self.probe(|_| { - self.at(origin, param_env).eq(a, b).map(|InferOk { obligations: _, .. }| { - // Ignore obligations, since we are unrolling - // everything anyway. - }) - }) + self.probe(|_| self.at(origin, param_env).eq(a, b).is_ok()) } #[instrument(skip(self), level = "debug")] diff --git a/compiler/rustc_middle/src/mir/interpret/pointer.rs b/compiler/rustc_middle/src/mir/interpret/pointer.rs index ab667c22a1453..60927eed85d3b 100644 --- a/compiler/rustc_middle/src/mir/interpret/pointer.rs +++ b/compiler/rustc_middle/src/mir/interpret/pointer.rs @@ -19,29 +19,29 @@ pub trait PointerArithmetic: HasDataLayout { #[inline(always)] fn max_size_of_val(&self) -> Size { - Size::from_bytes(self.machine_isize_max()) + Size::from_bytes(self.target_isize_max()) } #[inline] - fn machine_usize_max(&self) -> u64 { + fn target_usize_max(&self) -> u64 { self.pointer_size().unsigned_int_max().try_into().unwrap() } #[inline] - fn machine_isize_min(&self) -> i64 { + fn target_isize_min(&self) -> i64 { self.pointer_size().signed_int_min().try_into().unwrap() } #[inline] - fn machine_isize_max(&self) -> i64 { + fn target_isize_max(&self) -> i64 { self.pointer_size().signed_int_max().try_into().unwrap() } #[inline] - fn machine_usize_to_isize(&self, val: u64) -> i64 { + fn target_usize_to_isize(&self, val: u64) -> i64 { let val = val as i64; // Now wrap-around into the machine_isize range. - if val > self.machine_isize_max() { + if val > self.target_isize_max() { // This can only happen if the ptr size is < 64, so we know max_usize_plus_1 fits into // i64. debug_assert!(self.pointer_size().bits() < 64); @@ -76,11 +76,11 @@ pub trait PointerArithmetic: HasDataLayout { let n = i.unsigned_abs(); if i >= 0 { let (val, over) = self.overflowing_offset(val, n); - (val, over || i > self.machine_isize_max()) + (val, over || i > self.target_isize_max()) } else { let res = val.overflowing_sub(n); let (val, over) = self.truncate_to_ptr(res); - (val, over || i < self.machine_isize_min()) + (val, over || i < self.target_isize_min()) } } diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index 77594e3440e36..36dbbe4bf7765 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -75,8 +75,8 @@ impl<'tcx> ConstValue<'tcx> { self.try_to_scalar_int()?.try_into().ok() } - pub fn try_to_machine_usize(&self, tcx: TyCtxt<'tcx>) -> Option { - self.try_to_scalar_int()?.try_to_machine_usize(tcx).ok() + pub fn try_to_target_usize(&self, tcx: TyCtxt<'tcx>) -> Option { + self.try_to_scalar_int()?.try_to_target_usize(tcx).ok() } pub fn try_to_bits_for_ty( @@ -97,8 +97,8 @@ impl<'tcx> ConstValue<'tcx> { ConstValue::Scalar(Scalar::from_u64(i)) } - pub fn from_machine_usize(i: u64, cx: &impl HasDataLayout) -> Self { - ConstValue::Scalar(Scalar::from_machine_usize(i, cx)) + pub fn from_target_usize(i: u64, cx: &impl HasDataLayout) -> Self { + ConstValue::Scalar(Scalar::from_target_usize(i, cx)) } } @@ -241,7 +241,7 @@ impl Scalar { } #[inline] - pub fn from_machine_usize(i: u64, cx: &impl HasDataLayout) -> Self { + pub fn from_target_usize(i: u64, cx: &impl HasDataLayout) -> Self { Self::from_uint(i, cx.data_layout().pointer_size) } @@ -268,7 +268,7 @@ impl Scalar { } #[inline] - pub fn from_machine_isize(i: i64, cx: &impl HasDataLayout) -> Self { + pub fn from_target_isize(i: i64, cx: &impl HasDataLayout) -> Self { Self::from_int(i, cx.data_layout().pointer_size) } @@ -429,7 +429,7 @@ impl<'tcx, Prov: Provenance> Scalar { /// Converts the scalar to produce a machine-pointer-sized unsigned integer. /// Fails if the scalar is a pointer. - pub fn to_machine_usize(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, u64> { + pub fn to_target_usize(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, u64> { let b = self.to_uint(cx.data_layout().pointer_size)?; Ok(u64::try_from(b).unwrap()) } @@ -469,7 +469,7 @@ impl<'tcx, Prov: Provenance> Scalar { /// Converts the scalar to produce a machine-pointer-sized signed integer. /// Fails if the scalar is a pointer. - pub fn to_machine_isize(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, i64> { + pub fn to_target_isize(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, i64> { let b = self.to_int(cx.data_layout().pointer_size)?; Ok(i64::try_from(b).unwrap()) } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 6996d91a80dcc..c596e91160c8a 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2357,10 +2357,10 @@ impl<'tcx> ConstantKind<'tcx> { ) -> Option { match self { Self::Ty(ct) => ct.try_eval_target_usize(tcx, param_env), - Self::Val(val, _) => val.try_to_machine_usize(tcx), + Self::Val(val, _) => val.try_to_target_usize(tcx), Self::Unevaluated(uneval, _) => { match tcx.const_eval_resolve(param_env, *uneval, None) { - Ok(val) => val.try_to_machine_usize(tcx), + Ok(val) => val.try_to_target_usize(tcx), Err(_) => None, } } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 3ad56e8f273df..927f18f59b979 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -206,7 +206,7 @@ impl<'tcx> Const<'tcx> { tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ) -> Option { - self.kind().eval(tcx, param_env).try_to_machine_usize(tcx) + self.kind().eval(tcx, param_env).try_to_target_usize(tcx) } #[inline] diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index 48958e0d9e91c..eecd78ab6c048 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -232,7 +232,7 @@ impl ScalarInt { } #[inline] - pub fn try_to_machine_usize(&self, tcx: TyCtxt<'_>) -> Result { + pub fn try_to_target_usize(&self, tcx: TyCtxt<'_>) -> Result { Ok(self.to_bits(tcx.data_layout.pointer_size)? as u64) } diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index d9721863a58c8..58c5e21df66b9 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -125,8 +125,8 @@ impl<'tcx> ConstKind<'tcx> { } #[inline] - pub fn try_to_machine_usize(self, tcx: TyCtxt<'tcx>) -> Option { - self.try_to_value()?.try_to_machine_usize(tcx) + pub fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option { + self.try_to_value()?.try_to_target_usize(tcx) } } diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs index a803fca0d5b89..5ed4af2e9229d 100644 --- a/compiler/rustc_middle/src/ty/consts/valtree.rs +++ b/compiler/rustc_middle/src/ty/consts/valtree.rs @@ -78,8 +78,8 @@ impl<'tcx> ValTree<'tcx> { } } - pub fn try_to_machine_usize(self, tcx: TyCtxt<'tcx>) -> Option { - self.try_to_scalar_int().map(|s| s.try_to_machine_usize(tcx).ok()).flatten() + pub fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option { + self.try_to_scalar_int().map(|s| s.try_to_target_usize(tcx).ok()).flatten() } /// Get the values inside the ValTree as a slice of bytes. This only works for diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs index 8d0c7bf2f478f..e268553f8268b 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs @@ -159,7 +159,7 @@ impl<'tcx> InhabitedPredicate<'tcx> { match self { Self::ConstIsZero(c) => { let c = ty::EarlyBinder(c).subst(tcx, substs); - let pred = match c.kind().try_to_machine_usize(tcx) { + let pred = match c.kind().try_to_target_usize(tcx) { Some(0) => Self::True, Some(1..) => Self::False, None => Self::ConstIsZero(c), diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs index 5d5089cec82a6..690c0d58e01c1 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs @@ -191,7 +191,7 @@ fn inhabited_predicate_type<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> InhabitedP // If we can evaluate the array length before having a `ParamEnv`, then // we can simplify the predicate. This is an optimization. - Array(ty, len) => match len.kind().try_to_machine_usize(tcx) { + Array(ty, len) => match len.kind().try_to_target_usize(tcx) { Some(0) => InhabitedPredicate::True, Some(1..) => ty.inhabited_predicate(tcx), None => ty.inhabited_predicate(tcx).or(tcx, InhabitedPredicate::ConstIsZero(len)), diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index c2565b7a3aa3e..cecacfa1b3e08 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1628,7 +1628,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // Eventually I'll need to implement param-env-aware // `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic. let param_env = ty::ParamEnv::empty(); - if self.can_sub(param_env, error, implication).is_ok() { + if self.can_sub(param_env, error, implication) { debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implication); return true; } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index a3209d35e58be..52ed64868c053 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -72,7 +72,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let impl_self_ty = impl_trait_ref.self_ty(); - if let Ok(..) = self.can_eq(param_env, trait_self_ty, impl_self_ty) { + if self.can_eq(param_env, trait_self_ty, impl_self_ty) { self_match_impls.push((def_id, impl_substs)); if iter::zip( @@ -261,7 +261,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // Arrays give us `[]`, `[{ty}; _]` and `[{ty}; N]` if let ty::Array(aty, len) = self_ty.kind() { flags.push((sym::_Self, Some("[]".to_string()))); - let len = len.kind().try_to_value().and_then(|v| v.try_to_machine_usize(self.tcx)); + let len = len.kind().try_to_value().and_then(|v| v.try_to_target_usize(self.tcx)); flags.push((sym::_Self, Some(format!("[{}; _]", aty)))); if let Some(n) = len { flags.push((sym::_Self, Some(format!("[{}; {}]", aty, n)))); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 0a1dfa7925b0f..135232d1b2089 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -748,10 +748,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let real_ty = real_trait_pred.self_ty(); // We `erase_late_bound_regions` here because `make_subregion` does not handle // `ReLateBound`, and we don't particularly care about the regions. - if self - .can_eq(obligation.param_env, self.tcx.erase_late_bound_regions(real_ty), arg_ty) - .is_err() - { + if !self.can_eq( + obligation.param_env, + self.tcx.erase_late_bound_regions(real_ty), + arg_ty, + ) { continue; } @@ -3690,7 +3691,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let Some((span, (assoc, ty))) = entry else { continue; }; if primary_spans.is_empty() || type_diffs.iter().any(|diff| { let Sorts(expected_found) = diff else { return false; }; - self.can_eq(param_env, expected_found.found, ty).is_ok() + self.can_eq(param_env, expected_found.found, ty) }) { // FIXME: this doesn't quite work for `Iterator::collect` // because we have `Vec` and `()`, but we'd want `i32` @@ -3717,10 +3718,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let ty_str = with_forced_trimmed_paths!(self.ty_to_string(ty)); let assoc = with_forced_trimmed_paths!(self.tcx.def_path_str(assoc)); - if self.can_eq(param_env, ty, *prev_ty).is_err() { + if !self.can_eq(param_env, ty, *prev_ty) { if type_diffs.iter().any(|diff| { let Sorts(expected_found) = diff else { return false; }; - self.can_eq(param_env, expected_found.found, ty).is_ok() + self.can_eq(param_env, expected_found.found, ty) }) { primary_spans.push(span); } @@ -3868,7 +3869,7 @@ fn hint_missing_borrow<'tcx>( let (found_ty, found_refs) = get_deref_type_and_refs(*found_arg); let (expected_ty, expected_refs) = get_deref_type_and_refs(*expected_arg); - if infcx.can_eq(param_env, found_ty, expected_ty).is_ok() { + if infcx.can_eq(param_env, found_ty, expected_ty) { // FIXME: This could handle more exotic cases like mutability mismatches too! if found_refs.len() < expected_refs.len() && found_refs[..] == expected_refs[expected_refs.len() - found_refs.len()..] diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 5a76e86692336..ee13dae60b198 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -216,7 +216,8 @@ pub fn spin_loop() { /// /// Note however, that `black_box` is only (and can only be) provided on a "best-effort" basis. The /// extent to which it can block optimisations may vary depending upon the platform and code-gen -/// backend used. Programs cannot rely on `black_box` for *correctness* in any way. +/// backend used. Programs cannot rely on `black_box` for *correctness*, beyond it behaving as the +/// identity function. /// /// [`std::convert::identity`]: crate::convert::identity /// diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 286ad68fd13e8..c550378e7d6b7 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -334,6 +334,10 @@ impl File { /// /// See the [`OpenOptions::open`] method for more details. /// + /// If you only need to read the entire file contents, + /// consider [`std::fs::read()`][self::read] or + /// [`std::fs::read_to_string()`][self::read_to_string] instead. + /// /// # Errors /// /// This function will return an error if `path` does not already exist. @@ -343,9 +347,12 @@ impl File { /// /// ```no_run /// use std::fs::File; + /// use std::io::Read; /// /// fn main() -> std::io::Result<()> { /// let mut f = File::open("foo.txt")?; + /// let mut data = vec![]; + /// f.read_to_end(&mut data)?; /// Ok(()) /// } /// ``` @@ -361,16 +368,20 @@ impl File { /// /// Depending on the platform, this function may fail if the /// full directory path does not exist. - /// /// See the [`OpenOptions::open`] function for more details. /// + /// See also [`std::fs::write()`][self::write] for a simple function to + /// create a file with a given data. + /// /// # Examples /// /// ```no_run /// use std::fs::File; + /// use std::io::Write; /// /// fn main() -> std::io::Result<()> { /// let mut f = File::create("foo.txt")?; + /// f.write_all(&1234_u32.to_be_bytes())?; /// Ok(()) /// } /// ``` @@ -397,9 +408,11 @@ impl File { /// #![feature(file_create_new)] /// /// use std::fs::File; + /// use std::io::Write; /// /// fn main() -> std::io::Result<()> { /// let mut f = File::create_new("foo.txt")?; + /// f.write_all("Hello, world!".as_bytes())?; /// Ok(()) /// } /// ``` @@ -426,9 +439,11 @@ impl File { /// /// ```no_run /// use std::fs::File; + /// use std::io::Write; /// /// fn main() -> std::io::Result<()> { /// let mut f = File::options().append(true).open("example.log")?; + /// writeln!(&mut f, "new line")?; /// Ok(()) /// } /// ``` @@ -966,6 +981,9 @@ impl OpenOptions { /// In order for the file to be created, [`OpenOptions::write`] or /// [`OpenOptions::append`] access must be used. /// + /// See also [`std::fs::write()`][self::write] for a simple function to + /// create a file with a given data. + /// /// # Examples /// /// ```no_run diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index f1853f3697df2..dd58a5b51fc1a 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -164,10 +164,10 @@ impl Cfg { /// Renders the configuration for human display, as a short HTML description. pub(crate) fn render_short_html(&self) -> String { let mut msg = Display(self, Format::ShortHtml).to_string(); - if self.should_capitalize_first_letter() { - if let Some(i) = msg.find(|c: char| c.is_ascii_alphanumeric()) { - msg[i..i + 1].make_ascii_uppercase(); - } + if self.should_capitalize_first_letter() && + let Some(i) = msg.find(|c: char| c.is_ascii_alphanumeric()) + { + msg[i..i + 1].make_ascii_uppercase(); } msg } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 6592692d8b214..8bb8f122e2268 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -390,18 +390,17 @@ pub(crate) fn build_impl( // Only inline impl if the implemented trait is // reachable in rustdoc generated documentation - if !did.is_local() { - if let Some(traitref) = associated_trait { - let did = traitref.def_id; - if !cx.cache.effective_visibilities.is_directly_public(tcx, did) { - return; - } + if !did.is_local() && let Some(traitref) = associated_trait { + let did = traitref.def_id; + if !cx.cache.effective_visibilities.is_directly_public(tcx, did) { + return; + } - if let Some(stab) = tcx.lookup_stability(did) { - if stab.is_unstable() && stab.feature == sym::rustc_private { - return; - } - } + if let Some(stab) = tcx.lookup_stability(did) && + stab.is_unstable() && + stab.feature == sym::rustc_private + { + return; } } @@ -525,10 +524,8 @@ pub(crate) fn build_impl( } while let Some(ty) = stack.pop() { - if let Some(did) = ty.def_id(&cx.cache) { - if tcx.is_doc_hidden(did) { - return; - } + if let Some(did) = ty.def_id(&cx.cache) && tcx.is_doc_hidden(did) { + return; } if let Some(generics) = ty.generics() { stack.extend(generics); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index bf3bbeb2dd133..65736bb16fc05 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -787,43 +787,43 @@ fn clean_ty_generics<'tcx>( None })(); - if let Some(param_idx) = param_idx { - if let Some(b) = impl_trait.get_mut(¶m_idx.into()) { - let p: WherePredicate = clean_predicate(*p, cx)?; + if let Some(param_idx) = param_idx + && let Some(b) = impl_trait.get_mut(¶m_idx.into()) + { + let p: WherePredicate = clean_predicate(*p, cx)?; + + b.extend( + p.get_bounds() + .into_iter() + .flatten() + .cloned() + .filter(|b| !b.is_sized_bound(cx)), + ); - b.extend( - p.get_bounds() + let proj = projection.map(|p| { + ( + clean_projection(p.map_bound(|p| p.projection_ty), cx, None), + p.map_bound(|p| p.term), + ) + }); + if let Some(((_, trait_did, name), rhs)) = proj + .as_ref() + .and_then(|(lhs, rhs): &(Type, _)| Some((lhs.projection()?, rhs))) + { + // FIXME(...): Remove this unwrap() + impl_trait_proj.entry(param_idx).or_default().push(( + trait_did, + name, + rhs.map_bound(|rhs| rhs.ty().unwrap()), + p.get_bound_params() .into_iter() .flatten() - .cloned() - .filter(|b| !b.is_sized_bound(cx)), - ); - - let proj = projection.map(|p| { - ( - clean_projection(p.map_bound(|p| p.projection_ty), cx, None), - p.map_bound(|p| p.term), - ) - }); - if let Some(((_, trait_did, name), rhs)) = proj - .as_ref() - .and_then(|(lhs, rhs): &(Type, _)| Some((lhs.projection()?, rhs))) - { - // FIXME(...): Remove this unwrap() - impl_trait_proj.entry(param_idx).or_default().push(( - trait_did, - name, - rhs.map_bound(|rhs| rhs.ty().unwrap()), - p.get_bound_params() - .into_iter() - .flatten() - .map(|param| GenericParamDef::lifetime(param.0)) - .collect(), - )); - } - - return None; + .map(|param| GenericParamDef::lifetime(param.0)) + .collect(), + )); } + + return None; } Some(p) @@ -886,7 +886,7 @@ fn clean_ty_generics<'tcx>( // `?Sized` bound for each one we didn't find to be `Sized`. for tp in &stripped_params { if let types::GenericParamDefKind::Type { .. } = tp.kind - && !sized_params.contains(&tp.name) + && !sized_params.contains(&tp.name) { where_predicates.push(WherePredicate::BoundPredicate { ty: Type::Generic(tp.name), @@ -1461,10 +1461,10 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type // Try to normalize `::T` to a type let ty = hir_ty_to_ty(cx.tcx, hir_ty); // `hir_to_ty` can return projection types with escaping vars for GATs, e.g. `<() as Trait>::Gat<'_>` - if !ty.has_escaping_bound_vars() { - if let Some(normalized_value) = normalize(cx, ty::Binder::dummy(ty)) { - return clean_middle_ty(normalized_value, cx, None); - } + if !ty.has_escaping_bound_vars() + && let Some(normalized_value) = normalize(cx, ty::Binder::dummy(ty)) + { + return clean_middle_ty(normalized_value, cx, None); } let trait_segments = &p.segments[..p.segments.len() - 1]; @@ -1878,11 +1878,9 @@ fn clean_middle_opaque_bounds<'tcx>( _ => return None, }; - if let Some(sized) = cx.tcx.lang_items().sized_trait() { - if trait_ref.def_id() == sized { - has_sized = true; - return None; - } + if let Some(sized) = cx.tcx.lang_items().sized_trait() && trait_ref.def_id() == sized { + has_sized = true; + return None; } let bindings: ThinVec<_> = bounds @@ -2392,17 +2390,15 @@ fn clean_use_statement_inner<'tcx>( let is_visible_from_parent_mod = visibility.is_accessible_from(parent_mod, cx.tcx) && !current_mod.is_top_level_module(); - if pub_underscore { - if let Some(ref inline) = inline_attr { - rustc_errors::struct_span_err!( - cx.tcx.sess, - inline.span(), - E0780, - "anonymous imports cannot be inlined" - ) - .span_label(import.span, "anonymous import") - .emit(); - } + if pub_underscore && let Some(ref inline) = inline_attr { + rustc_errors::struct_span_err!( + cx.tcx.sess, + inline.span(), + E0780, + "anonymous imports cannot be inlined" + ) + .span_label(import.span, "anonymous import") + .emit(); } // We consider inlining the documentation of `pub use` statements, but we @@ -2438,14 +2434,13 @@ fn clean_use_statement_inner<'tcx>( } Import::new_glob(resolve_use_source(cx, path), true) } else { - if inline_attr.is_none() { - if let Res::Def(DefKind::Mod, did) = path.res { - if !did.is_local() && did.is_crate_root() { - // if we're `pub use`ing an extern crate root, don't inline it unless we - // were specifically asked for it - denied = true; - } - } + if inline_attr.is_none() + && let Res::Def(DefKind::Mod, did) = path.res + && !did.is_local() && did.is_crate_root() + { + // if we're `pub use`ing an extern crate root, don't inline it unless we + // were specifically asked for it + denied = true; } if !denied { let mut visited = DefIdSet::default(); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index b00cefdddb524..fc1396e86f6b1 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -182,10 +182,8 @@ impl ExternalCrate { return Local; } - if extern_url_takes_precedence { - if let Some(url) = extern_url { - return to_remote(url); - } + if extern_url_takes_precedence && let Some(url) = extern_url { + return to_remote(url); } // Failing that, see if there's an attribute specifying where to find this @@ -1176,10 +1174,10 @@ impl GenericBound { pub(crate) fn is_sized_bound(&self, cx: &DocContext<'_>) -> bool { use rustc_hir::TraitBoundModifier as TBM; - if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self { - if Some(trait_.def_id()) == cx.tcx.lang_items().sized_trait() { - return true; - } + if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self && + Some(trait_.def_id()) == cx.tcx.lang_items().sized_trait() + { + return true; } false } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index ca3a70c7236fe..4d8ce54dc5c62 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -345,10 +345,10 @@ pub(crate) fn is_literal_expr(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool { return true; } - if let hir::ExprKind::Unary(hir::UnOp::Neg, expr) = &expr.kind { - if let hir::ExprKind::Lit(_) = &expr.kind { - return true; - } + if let hir::ExprKind::Unary(hir::UnOp::Neg, expr) = &expr.kind && + let hir::ExprKind::Lit(_) = &expr.kind + { + return true; } } diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 57c41b57311df..0eba81c7c1ee3 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -229,11 +229,11 @@ fn scrape_test_config(attrs: &[ast::Attribute]) -> GlobalTestOptions { if attr.has_name(sym::no_crate_inject) { opts.no_crate_inject = true; } - if attr.has_name(sym::attr) { - if let Some(l) = attr.meta_item_list() { - for item in l { - opts.attrs.push(pprust::meta_list_item_to_string(item)); - } + if attr.has_name(sym::attr) + && let Some(l) = attr.meta_item_list() + { + for item in l { + opts.attrs.push(pprust::meta_list_item_to_string(item)); } } } @@ -594,31 +594,28 @@ pub(crate) fn make_test( loop { match parser.parse_item(ForceCollect::No) { Ok(Some(item)) => { - if !found_main { - if let ast::ItemKind::Fn(..) = item.kind { - if item.ident.name == sym::main { - found_main = true; - } - } + if !found_main && + let ast::ItemKind::Fn(..) = item.kind && + item.ident.name == sym::main + { + found_main = true; } - if !found_extern_crate { - if let ast::ItemKind::ExternCrate(original) = item.kind { - // This code will never be reached if `crate_name` is none because - // `found_extern_crate` is initialized to `true` if it is none. - let crate_name = crate_name.unwrap(); + if !found_extern_crate && + let ast::ItemKind::ExternCrate(original) = item.kind + { + // This code will never be reached if `crate_name` is none because + // `found_extern_crate` is initialized to `true` if it is none. + let crate_name = crate_name.unwrap(); - match original { - Some(name) => found_extern_crate = name.as_str() == crate_name, - None => found_extern_crate = item.ident.as_str() == crate_name, - } + match original { + Some(name) => found_extern_crate = name.as_str() == crate_name, + None => found_extern_crate = item.ident.as_str() == crate_name, } } - if !found_macro { - if let ast::ItemKind::MacCall(..) = item.kind { - found_macro = true; - } + if !found_macro && let ast::ItemKind::MacCall(..) = item.kind { + found_macro = true; } if found_main && found_extern_crate { @@ -972,14 +969,12 @@ impl Collector { fn get_filename(&self) -> FileName { if let Some(ref source_map) = self.source_map { let filename = source_map.span_to_filename(self.position); - if let FileName::Real(ref filename) = filename { - if let Ok(cur_dir) = env::current_dir() { - if let Some(local_path) = filename.local_path() { - if let Ok(path) = local_path.strip_prefix(&cur_dir) { - return path.to_owned().into(); - } - } - } + if let FileName::Real(ref filename) = filename && + let Ok(cur_dir) = env::current_dir() && + let Some(local_path) = filename.local_path() && + let Ok(path) = local_path.strip_prefix(&cur_dir) + { + return path.to_owned().into(); } filename } else if let Some(ref filename) = self.filename { diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 24752cddb337c..b1db16cfe3cac 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -229,16 +229,15 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { } // Collect all the implementors of traits. - if let clean::ImplItem(ref i) = *item.kind { - if let Some(trait_) = &i.trait_ { - if !i.kind.is_blanket() { - self.cache - .implementors - .entry(trait_.def_id()) - .or_default() - .push(Impl { impl_item: item.clone() }); - } - } + if let clean::ImplItem(ref i) = *item.kind && + let Some(trait_) = &i.trait_ && + !i.kind.is_blanket() + { + self.cache + .implementors + .entry(trait_.def_id()) + .or_default() + .push(Impl { impl_item: item.clone() }); } // Index this method for searching later on. diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 314f061224940..1ed0b0bc2d558 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -710,11 +710,9 @@ pub(crate) fn href_with_root_path( } } }; - if !is_remote { - if let Some(root_path) = root_path { - let root = root_path.trim_end_matches('/'); - url_parts.push_front(root); - } + if !is_remote && let Some(root_path) = root_path { + let root = root_path.trim_end_matches('/'); + url_parts.push_front(root); } debug!(?url_parts); match shortty { diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 3c10eb524d724..2c9fc4e3ca378 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -466,10 +466,8 @@ impl<'a> PeekIter<'a> { } /// Returns the next item after the current one. It doesn't interfere with `peek_next` output. fn peek(&mut self) -> Option<&(TokenKind, &'a str)> { - if self.stored.is_empty() { - if let Some(next) = self.iter.next() { - self.stored.push_back(next); - } + if self.stored.is_empty() && let Some(next) = self.iter.next() { + self.stored.push_back(next); } self.stored.front() } diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 6762fba9275cf..5e4a595627b4a 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -705,14 +705,12 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { shared.fs.write(scrape_examples_help_file, v)?; } - if let Some(ref redirections) = shared.redirections { - if !redirections.borrow().is_empty() { - let redirect_map_path = - self.dst.join(crate_name.as_str()).join("redirect-map.json"); - let paths = serde_json::to_string(&*redirections.borrow()).unwrap(); - shared.ensure_dir(&self.dst.join(crate_name.as_str()))?; - shared.fs.write(redirect_map_path, paths)?; - } + if let Some(ref redirections) = shared.redirections && !redirections.borrow().is_empty() { + let redirect_map_path = + self.dst.join(crate_name.as_str()).join("redirect-map.json"); + let paths = serde_json::to_string(&*redirections.borrow()).unwrap(); + shared.ensure_dir(&self.dst.join(crate_name.as_str()))?; + shared.fs.write(redirect_map_path, paths)?; } // No need for it anymore. diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 2086faf78ac8a..e6a040d02e565 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2225,14 +2225,13 @@ fn sidebar_deref_methods( }) { debug!("found target, real_target: {:?} {:?}", target, real_target); - if let Some(did) = target.def_id(c) { - if let Some(type_did) = impl_.inner_impl().for_.def_id(c) { - // `impl Deref for S` - if did == type_did || !derefs.insert(did) { - // Avoid infinite cycles - return; - } - } + if let Some(did) = target.def_id(c) && + let Some(type_did) = impl_.inner_impl().for_.def_id(c) && + // `impl Deref for S` + (did == type_did || !derefs.insert(did)) + { + // Avoid infinite cycles + return; } let deref_mut = v.iter().any(|i| i.trait_did() == cx.tcx().lang_items().deref_mut_trait()); let inner_impl = target @@ -2266,25 +2265,24 @@ fn sidebar_deref_methods( } // Recurse into any further impls that might exist for `target` - if let Some(target_did) = target.def_id(c) { - if let Some(target_impls) = c.impls.get(&target_did) { - if let Some(target_deref_impl) = target_impls.iter().find(|i| { - i.inner_impl() - .trait_ - .as_ref() - .map(|t| Some(t.def_id()) == cx.tcx().lang_items().deref_trait()) - .unwrap_or(false) - }) { - sidebar_deref_methods( - cx, - out, - target_deref_impl, - target_impls, - derefs, - used_links, - ); - } - } + if let Some(target_did) = target.def_id(c) && + let Some(target_impls) = c.impls.get(&target_did) && + let Some(target_deref_impl) = target_impls.iter().find(|i| { + i.inner_impl() + .trait_ + .as_ref() + .map(|t| Some(t.def_id()) == cx.tcx().lang_items().deref_trait()) + .unwrap_or(false) + }) + { + sidebar_deref_methods( + cx, + out, + target_deref_impl, + target_impls, + derefs, + used_links, + ); } } } diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index 7c5c6eb3d2bbf..e3788fe57d013 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -80,12 +80,11 @@ impl<'tcx> JsonRenderer<'tcx> { // document primitive items in an arbitrary crate by using // `doc(primitive)`. let mut is_primitive_impl = false; - if let clean::types::ItemKind::ImplItem(ref impl_) = *item.kind { - if impl_.trait_.is_none() { - if let clean::types::Type::Primitive(_) = impl_.for_ { - is_primitive_impl = true; - } - } + if let clean::types::ItemKind::ImplItem(ref impl_) = *item.kind && + impl_.trait_.is_none() && + let clean::types::Type::Primitive(_) = impl_.for_ + { + is_primitive_impl = true; } if item.item_id.is_local() || is_primitive_impl { diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index f3961d5017ef4..a39d57d42b72e 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -82,18 +82,17 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) - let def_id = item.item_id.expect_def_id().expect_local(); // check if parent is trait impl - if let Some(parent_def_id) = cx.tcx.opt_local_parent(def_id) { - if let Some(parent_node) = cx.tcx.hir().find_by_def_id(parent_def_id) { - if matches!( - parent_node, - hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }), - .. - }) - ) { - return false; - } - } + if let Some(parent_def_id) = cx.tcx.opt_local_parent(def_id) && + let Some(parent_node) = cx.tcx.hir().find_by_def_id(parent_def_id) && + matches!( + parent_node, + hir::Node::Item(hir::Item { + kind: hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }), + .. + }) + ) + { + return false; } if cx.tcx.is_doc_hidden(def_id.to_def_id()) diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 878e738fe508c..189b37b69d132 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -156,39 +156,38 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> // scan through included items ahead of time to splice in Deref targets to the "valid" sets for it in new_items_external.iter().chain(new_items_local.iter()) { - if let ImplItem(box Impl { ref for_, ref trait_, ref items, .. }) = *it.kind { - if trait_.as_ref().map(|t| t.def_id()) == cx.tcx.lang_items().deref_trait() - && cleaner.keep_impl(for_, true) - { - let target = items - .iter() - .find_map(|item| match *item.kind { - AssocTypeItem(ref t, _) => Some(&t.type_), - _ => None, - }) - .expect("Deref impl without Target type"); + if let ImplItem(box Impl { ref for_, ref trait_, ref items, .. }) = *it.kind && + trait_.as_ref().map(|t| t.def_id()) == cx.tcx.lang_items().deref_trait() && + cleaner.keep_impl(for_, true) + { + let target = items + .iter() + .find_map(|item| match *item.kind { + AssocTypeItem(ref t, _) => Some(&t.type_), + _ => None, + }) + .expect("Deref impl without Target type"); - if let Some(prim) = target.primitive_type() { - cleaner.prims.insert(prim); - } else if let Some(did) = target.def_id(&cx.cache) { - cleaner.items.insert(did.into()); - } - if let Some(for_did) = for_.def_id(&cx.cache) { - if type_did_to_deref_target.insert(for_did, target).is_none() { - // Since only the `DefId` portion of the `Type` instances is known to be same for both the - // `Deref` target type and the impl for type positions, this map of types is keyed by - // `DefId` and for convenience uses a special cleaner that accepts `DefId`s directly. - if cleaner.keep_impl_with_def_id(for_did.into()) { - let mut targets = DefIdSet::default(); - targets.insert(for_did); - add_deref_target( - cx, - &type_did_to_deref_target, - &mut cleaner, - &mut targets, - for_did, - ); - } + if let Some(prim) = target.primitive_type() { + cleaner.prims.insert(prim); + } else if let Some(did) = target.def_id(&cx.cache) { + cleaner.items.insert(did.into()); + } + if let Some(for_did) = for_.def_id(&cx.cache) { + if type_did_to_deref_target.insert(for_did, target).is_none() { + // Since only the `DefId` portion of the `Type` instances is known to be same for both the + // `Deref` target type and the impl for type positions, this map of types is keyed by + // `DefId` and for convenience uses a special cleaner that accepts `DefId`s directly. + if cleaner.keep_impl_with_def_id(for_did.into()) { + let mut targets = DefIdSet::default(); + targets.insert(for_did); + add_deref_target( + cx, + &type_did_to_deref_target, + &mut cleaner, + &mut targets, + for_did, + ); } } } diff --git a/src/librustdoc/passes/lint/html_tags.rs b/src/librustdoc/passes/lint/html_tags.rs index 070c0aab5868b..eac362b37b209 100644 --- a/src/librustdoc/passes/lint/html_tags.rs +++ b/src/librustdoc/passes/lint/html_tags.rs @@ -210,11 +210,9 @@ fn extract_path_backwards(text: &str, end_pos: usize) -> Option { .take_while(|(_, c)| is_id_start(*c) || is_id_continue(*c)) .reduce(|_accum, item| item) .and_then(|(new_pos, c)| is_id_start(c).then_some(new_pos)); - if let Some(new_pos) = new_pos { - if current_pos != new_pos { - current_pos = new_pos; - continue; - } + if let Some(new_pos) = new_pos && current_pos != new_pos { + current_pos = new_pos; + continue; } break; } diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index 048ed2646233c..cba55e5fe655c 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -201,27 +201,25 @@ impl<'a> DocFolder for ImplStripper<'a, '_> { // Because we don't inline in `maybe_inline_local` if the output format is JSON, // we need to make a special check for JSON output: we want to keep it unless it has // a `#[doc(hidden)]` attribute if the `for_` type is exported. - if let Some(did) = imp.for_.def_id(self.cache) { - if !imp.for_.is_assoc_ty() && !self.should_keep_impl(&i, did) { - debug!("ImplStripper: impl item for stripped type; removing"); - return None; - } + if let Some(did) = imp.for_.def_id(self.cache) && + !imp.for_.is_assoc_ty() && !self.should_keep_impl(&i, did) + { + debug!("ImplStripper: impl item for stripped type; removing"); + return None; } - if let Some(did) = imp.trait_.as_ref().map(|t| t.def_id()) { - if !self.should_keep_impl(&i, did) { - debug!("ImplStripper: impl item for stripped trait; removing"); - return None; - } + if let Some(did) = imp.trait_.as_ref().map(|t| t.def_id()) && + !self.should_keep_impl(&i, did) { + debug!("ImplStripper: impl item for stripped trait; removing"); + return None; } if let Some(generics) = imp.trait_.as_ref().and_then(|t| t.generics()) { for typaram in generics { - if let Some(did) = typaram.def_id(self.cache) { - if !self.should_keep_impl(&i, did) { - debug!( - "ImplStripper: stripped item in trait's generics; removing impl" - ); - return None; - } + if let Some(did) = typaram.def_id(self.cache) && !self.should_keep_impl(&i, did) + { + debug!( + "ImplStripper: stripped item in trait's generics; removing impl" + ); + return None; } } } diff --git a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs index db637dfc068d4..4dc750c03b488 100644 --- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs @@ -54,7 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays { let ty = hir_ty_to_ty(cx.tcx, hir_ty); if let ty::Array(element_type, cst) = ty.kind(); if let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind(); - if let Ok(element_count) = element_count.try_to_machine_usize(cx.tcx); + if let Ok(element_count) = element_count.try_to_target_usize(cx.tcx); if let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes()); if self.maximum_allowed_size < u128::from(element_count) * u128::from(element_size); diff --git a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs index 89ae83d48f536..32c6312e06946 100644 --- a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs @@ -41,7 +41,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays { if let ExprKind::Repeat(_, _) = expr.kind && let ty::Array(element_type, cst) = cx.typeck_results().expr_ty(expr).kind() && let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind() - && let Ok(element_count) = element_count.try_to_machine_usize(cx.tcx) + && let Ok(element_count) = element_count.try_to_target_usize(cx.tcx) && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes()) && !cx.tcx.hir().parent_iter(expr.hir_id) .any(|(_, node)| matches!(node, Node::Item(Item { kind: ItemKind::Static(..), .. }))) diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 9d812fbdcc37e..8b00ce2cc2586 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -640,7 +640,7 @@ pub fn miri_to_const<'tcx>(tcx: TyCtxt<'tcx>, result: mir::ConstantKind<'tcx>) - }, mir::ConstantKind::Val(ConstValue::ByRef { alloc, offset: _ }, _) => match result.ty().kind() { ty::Array(sub_type, len) => match sub_type.kind() { - ty::Float(FloatTy::F32) => match len.kind().try_to_machine_usize(tcx) { + ty::Float(FloatTy::F32) => match len.kind().try_to_target_usize(tcx) { Some(len) => alloc .inner() .inspect_with_uninit_and_ptr_outside_interpreter(0..(4 * usize::try_from(len).unwrap())) @@ -651,7 +651,7 @@ pub fn miri_to_const<'tcx>(tcx: TyCtxt<'tcx>, result: mir::ConstantKind<'tcx>) - .map(Constant::Vec), _ => None, }, - ty::Float(FloatTy::F64) => match len.kind().try_to_machine_usize(tcx) { + ty::Float(FloatTy::F64) => match len.kind().try_to_target_usize(tcx) { Some(len) => alloc .inner() .inspect_with_uninit_and_ptr_outside_interpreter(0..(8 * usize::try_from(len).unwrap())) diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs index 106e93751d219..cf1ff603281ee 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -718,7 +718,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' throw_ub!(PointerOutOfBounds { alloc_id, alloc_size, - ptr_offset: this.machine_usize_to_isize(base_offset.bytes()), + ptr_offset: this.target_usize_to_isize(base_offset.bytes()), ptr_size: size, msg: CheckInAllocMsg::InboundsTest }); diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index 96ab8b0d98e63..d61e17cbf9a4a 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -236,7 +236,7 @@ impl MainThreadState { this.machine.main_fn_ret_place.unwrap().ptr, this.machine.layouts.isize, ); - let exit_code = this.read_machine_isize(&ret_place.into())?; + let exit_code = this.read_target_isize(&ret_place.into())?; // Need to call this ourselves since we are not going to return to the scheduler // loop, and we want the main thread TLS to not show up as memory leaks. this.terminate_active_thread()?; @@ -287,7 +287,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( // First argument is constructed later, because it's skipped if the entry function uses #[start]. // Second argument (argc): length of `config.args`. - let argc = Scalar::from_machine_usize(u64::try_from(config.args.len()).unwrap(), &ecx); + let argc = Scalar::from_target_usize(u64::try_from(config.args.len()).unwrap(), &ecx); // Third argument (`argv`): created from `config.args`. let argv = { // Put each argument in memory, collect pointers. diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 527d31d1f0ae8..5286023e0f64e 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -758,10 +758,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let this = self.eval_context_mut(); let seconds_place = this.mplace_field(tp, 0)?; let seconds_scalar = this.read_scalar(&seconds_place.into())?; - let seconds = seconds_scalar.to_machine_isize(this)?; + let seconds = seconds_scalar.to_target_isize(this)?; let nanoseconds_place = this.mplace_field(tp, 1)?; let nanoseconds_scalar = this.read_scalar(&nanoseconds_place.into())?; - let nanoseconds = nanoseconds_scalar.to_machine_isize(this)?; + let nanoseconds = nanoseconds_scalar.to_target_isize(this)?; Ok(try { // tv_sec must be non-negative. diff --git a/src/tools/miri/src/intptrcast.rs b/src/tools/miri/src/intptrcast.rs index dcb1879042041..2ba18293121dc 100644 --- a/src/tools/miri/src/intptrcast.rs +++ b/src/tools/miri/src/intptrcast.rs @@ -207,7 +207,7 @@ impl<'mir, 'tcx> GlobalStateInner { .checked_add(max(size.bytes(), 1)) .ok_or_else(|| err_exhaust!(AddressSpaceFull))?; // Even if `Size` didn't overflow, we might still have filled up the address space. - if global_state.next_base_addr > ecx.machine_usize_max() { + if global_state.next_base_addr > ecx.target_usize_max() { throw_exhaust!(AddressSpaceFull); } // Given that `next_base_addr` increases in each allocation, pushing the diff --git a/src/tools/miri/src/operator.rs b/src/tools/miri/src/operator.rs index a0ef7fcad16dc..79d5dfb5551bd 100644 --- a/src/tools/miri/src/operator.rs +++ b/src/tools/miri/src/operator.rs @@ -56,7 +56,7 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriInterpCx<'mir, 'tcx> { Offset => { assert!(left.layout.ty.is_unsafe_ptr()); let ptr = left.to_scalar().to_pointer(self)?; - let offset = right.to_scalar().to_machine_isize(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; @@ -73,14 +73,14 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriInterpCx<'mir, 'tcx> { // We do the actual operation with usize-typed scalars. let left = ImmTy::from_uint(ptr.addr().bytes(), self.machine.layouts.usize); let right = ImmTy::from_uint( - right.to_scalar().to_machine_usize(self)?, + right.to_scalar().to_target_usize(self)?, self.machine.layouts.usize, ); let (result, overflowing, _ty) = self.overflowing_binary_op(bin_op, &left, &right)?; // Construct a new pointer with the provenance of `ptr` (the LHS). let result_ptr = - Pointer::new(ptr.provenance, Size::from_bytes(result.to_machine_usize(self)?)); + Pointer::new(ptr.provenance, Size::from_bytes(result.to_target_usize(self)?)); (Scalar::from_maybe_pointer(result_ptr, self), overflowing, left.layout.ty) } diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs index ed1c6ebfece76..1e4ab2f0f6227 100644 --- a/src/tools/miri/src/shims/backtrace.rs +++ b/src/tools/miri/src/shims/backtrace.rs @@ -24,7 +24,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let frame_count = this.active_thread_stack().len(); - this.write_scalar(Scalar::from_machine_usize(frame_count.try_into().unwrap(), this), dest) + this.write_scalar(Scalar::from_target_usize(frame_count.try_into().unwrap(), this), dest) } fn handle_miri_get_backtrace( @@ -205,11 +205,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } 1 => { this.write_scalar( - Scalar::from_machine_usize(name.len().try_into().unwrap(), this), + Scalar::from_target_usize(name.len().try_into().unwrap(), this), &this.mplace_field(&dest, 0)?.into(), )?; this.write_scalar( - Scalar::from_machine_usize(filename.len().try_into().unwrap(), this), + Scalar::from_target_usize(filename.len().try_into().unwrap(), this), &this.mplace_field(&dest, 1)?.into(), )?; } diff --git a/src/tools/miri/src/shims/env.rs b/src/tools/miri/src/shims/env.rs index ce24b23ca3273..f50c135435fd7 100644 --- a/src/tools/miri/src/shims/env.rs +++ b/src/tools/miri/src/shims/env.rs @@ -323,7 +323,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.assert_target_os_is_unix("getcwd"); let buf = this.read_pointer(buf_op)?; - let size = this.read_machine_usize(size_op)?; + let size = this.read_target_usize(size_op)?; if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op { this.reject_in_isolation("`getcwd`", reject_with)?; diff --git a/src/tools/miri/src/shims/ffi_support.rs b/src/tools/miri/src/shims/ffi_support.rs index c5db868cdc7c5..e628c44a86788 100644 --- a/src/tools/miri/src/shims/ffi_support.rs +++ b/src/tools/miri/src/shims/ffi_support.rs @@ -36,7 +36,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ty::Int(IntTy::Isize) => { // This will fail if host != target, but then the entire FFI thing probably won't work well // in that situation. - return Ok(CArg::ISize(k.to_machine_isize(cx)?.try_into().unwrap())); + return Ok(CArg::ISize(k.to_target_isize(cx)?.try_into().unwrap())); } // the uints ty::Uint(UintTy::U8) => { @@ -54,7 +54,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ty::Uint(UintTy::Usize) => { // This will fail if host != target, but then the entire FFI thing probably won't work well // in that situation. - return Ok(CArg::USize(k.to_machine_usize(cx)?.try_into().unwrap())); + return Ok(CArg::USize(k.to_target_usize(cx)?.try_into().unwrap())); } _ => {} } diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index c792a27ab4ca2..2d9eb37a25806 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -449,7 +449,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [ptr, out, out_size] = this.check_shim(abi, Abi::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let out = this.read_pointer(out)?; - let out_size = this.read_scalar(out_size)?.to_machine_usize(this)?; + let out_size = this.read_scalar(out_size)?.to_target_usize(this)?; // The host affects program behavior here, so this requires isolation to be disabled. this.check_no_isolation("`miri_host_to_target_path`")?; @@ -490,7 +490,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [bytes] = this.check_shim(abi, Abi::Rust, link_name, args)?; let (ptr, len) = this.read_immediate(bytes)?.to_scalar_pair(); let ptr = ptr.to_pointer(this)?; - let len = len.to_machine_usize(this)?; + let len = len.to_target_usize(this)?; let msg = this.read_bytes_ptr_strip_provenance(ptr, Size::from_bytes(len))?; // Note: we're ignoring errors writing to host stdout/stderr. @@ -504,15 +504,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Standard C allocation "malloc" => { let [size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - let size = this.read_machine_usize(size)?; + let size = this.read_target_usize(size)?; let res = this.malloc(size, /*zero_init:*/ false, MiriMemoryKind::C)?; this.write_pointer(res, dest)?; } "calloc" => { let [items, len] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - let items = this.read_machine_usize(items)?; - let len = this.read_machine_usize(len)?; + let items = this.read_target_usize(items)?; + let len = this.read_target_usize(len)?; let size = items .checked_mul(len) .ok_or_else(|| err_ub_format!("overflow during calloc size computation"))?; @@ -528,7 +528,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [old_ptr, new_size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let old_ptr = this.read_pointer(old_ptr)?; - let new_size = this.read_machine_usize(new_size)?; + let new_size = this.read_target_usize(new_size)?; let res = this.realloc(old_ptr, new_size, MiriMemoryKind::C)?; this.write_pointer(res, dest)?; } @@ -536,8 +536,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Rust allocation "__rust_alloc" | "miri_alloc" => { let [size, align] = this.check_shim(abi, Abi::Rust, link_name, args)?; - let size = this.read_machine_usize(size)?; - let align = this.read_machine_usize(align)?; + let size = this.read_target_usize(size)?; + let align = this.read_target_usize(align)?; let default = |this: &mut MiriInterpCx<'mir, 'tcx>| { Self::check_alloc_request(size, align)?; @@ -569,8 +569,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } "__rust_alloc_zeroed" => { let [size, align] = this.check_shim(abi, Abi::Rust, link_name, args)?; - let size = this.read_machine_usize(size)?; - let align = this.read_machine_usize(align)?; + let size = this.read_target_usize(size)?; + let align = this.read_target_usize(align)?; return this.emulate_allocator(Symbol::intern("__rg_alloc_zeroed"), |this| { Self::check_alloc_request(size, align)?; @@ -593,8 +593,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "__rust_dealloc" | "miri_dealloc" => { let [ptr, old_size, align] = this.check_shim(abi, Abi::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; - let old_size = this.read_machine_usize(old_size)?; - let align = this.read_machine_usize(align)?; + let old_size = this.read_target_usize(old_size)?; + let align = this.read_target_usize(align)?; let default = |this: &mut MiriInterpCx<'mir, 'tcx>| { let memory_kind = match link_name.as_str() { @@ -625,9 +625,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [ptr, old_size, align, new_size] = this.check_shim(abi, Abi::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; - let old_size = this.read_machine_usize(old_size)?; - let align = this.read_machine_usize(align)?; - let new_size = this.read_machine_usize(new_size)?; + let old_size = this.read_target_usize(old_size)?; + let align = this.read_target_usize(align)?; + let new_size = this.read_target_usize(new_size)?; // No need to check old_size; we anyway check that they match the allocation. return this.emulate_allocator(Symbol::intern("__rg_realloc"), |this| { @@ -651,7 +651,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let left = this.read_pointer(left)?; let right = this.read_pointer(right)?; - let n = Size::from_bytes(this.read_machine_usize(n)?); + let n = Size::from_bytes(this.read_target_usize(n)?); let result = { let left_bytes = this.read_bytes_ptr_strip_provenance(left, n)?; @@ -672,7 +672,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let ptr = this.read_pointer(ptr)?; let val = this.read_scalar(val)?.to_i32()?; - let num = this.read_machine_usize(num)?; + let num = this.read_target_usize(num)?; // The docs say val is "interpreted as unsigned char". #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)] let val = val as u8; @@ -696,7 +696,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let ptr = this.read_pointer(ptr)?; let val = this.read_scalar(val)?.to_i32()?; - let num = this.read_machine_usize(num)?; + let num = this.read_target_usize(num)?; // The docs say val is "interpreted as unsigned char". #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)] let val = val as u8; @@ -717,7 +717,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let ptr = this.read_pointer(ptr)?; let n = this.read_c_str(ptr)?.len(); this.write_scalar( - Scalar::from_machine_usize(u64::try_from(n).unwrap(), this), + Scalar::from_target_usize(u64::try_from(n).unwrap(), this), dest, )?; } diff --git a/src/tools/miri/src/shims/intrinsics/mod.rs b/src/tools/miri/src/shims/intrinsics/mod.rs index 1b97a9d20de0c..d21a1560699c2 100644 --- a/src/tools/miri/src/shims/intrinsics/mod.rs +++ b/src/tools/miri/src/shims/intrinsics/mod.rs @@ -111,8 +111,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let ty_layout = this.layout_of(ty)?; let val_byte = this.read_scalar(val_byte)?.to_u8()?; let ptr = this.read_pointer(ptr)?; - let count = this.read_machine_usize(count)?; - // `checked_mul` enforces a too small bound (the correct one would probably be machine_isize_max), + let count = this.read_target_usize(count)?; + // `checked_mul` enforces a too small bound (the correct one would probably be target_isize_max), // but no actual allocation can be big enough for the difference to be noticeable. let byte_count = ty_layout.size.checked_mul(count, this).ok_or_else(|| { err_ub_format!("overflow computing total size of `{intrinsic_name}`") @@ -124,7 +124,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [ptr, mask] = check_arg_count(args)?; let ptr = this.read_pointer(ptr)?; - let mask = this.read_machine_usize(mask)?; + let mask = this.read_target_usize(mask)?; let masked_addr = Size::from_bytes(ptr.addr().bytes() & mask); diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs index f24ddb887b95a..f2e16521290fe 100644 --- a/src/tools/miri/src/shims/intrinsics/simd.rs +++ b/src/tools/miri/src/shims/intrinsics/simd.rs @@ -202,7 +202,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } Op::WrappingOffset => { let ptr = left.to_scalar().to_pointer(this)?; - let offset_count = right.to_scalar().to_machine_isize(this)?; + let offset_count = right.to_scalar().to_target_isize(this)?; let pointee_ty = left.layout.ty.builtin_deref(true).unwrap().ty; let pointee_size = i64::try_from(this.layout_of(pointee_ty)?.size.bytes()).unwrap(); diff --git a/src/tools/miri/src/shims/mod.rs b/src/tools/miri/src/shims/mod.rs index 39db97b72e2ce..dbc48876a4b06 100644 --- a/src/tools/miri/src/shims/mod.rs +++ b/src/tools/miri/src/shims/mod.rs @@ -80,7 +80,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { return Ok(false); } - let req_align = this.read_machine_usize(align_op)?; + let req_align = this.read_target_usize(align_op)?; // Stop if the alignment is not a power of two. if !req_align.is_power_of_two() { @@ -106,7 +106,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } // Return error result (usize::MAX), and jump to caller. - this.write_scalar(Scalar::from_machine_usize(this.machine_usize_max(), this), dest)?; + this.write_scalar(Scalar::from_target_usize(this.target_usize_max(), this), dest)?; this.go_to_block(ret); Ok(true) } diff --git a/src/tools/miri/src/shims/tls.rs b/src/tools/miri/src/shims/tls.rs index ca31efa486c27..e9119f9e1eced 100644 --- a/src/tools/miri/src/shims/tls.rs +++ b/src/tools/miri/src/shims/tls.rs @@ -108,7 +108,7 @@ impl<'tcx> TlsData<'tcx> { ) -> InterpResult<'tcx> { match self.keys.get_mut(&key) { Some(TlsEntry { data, .. }) => { - if new_data.to_machine_usize(cx)? != 0 { + if new_data.to_target_usize(cx)? != 0 { trace!("TLS key {} for thread {:?} stored: {:?}", key, thread_id, new_data); data.insert(thread_id, new_data); } else { @@ -356,7 +356,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { state.last_key = Some(key); trace!("Running TLS dtor {:?} on {:?} at {:?}", instance, ptr, active_thread); assert!( - !ptr.to_machine_usize(this).unwrap() != 0, + !ptr.to_target_usize(this).unwrap() != 0, "data can't be NULL when dtor is called!" ); diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index d018a7ea252b7..c371e85c312e8 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -78,19 +78,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [fd, buf, count] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; - let count = this.read_machine_usize(count)?; + let count = this.read_target_usize(count)?; let result = this.read(fd, buf, count)?; - this.write_scalar(Scalar::from_machine_isize(result, this), dest)?; + this.write_scalar(Scalar::from_target_isize(result, this), dest)?; } "write" => { let [fd, buf, n] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; - let count = this.read_machine_usize(n)?; + let count = this.read_target_usize(n)?; trace!("Called write({:?}, {:?}, {:?})", fd, buf, count); let result = this.write(fd, buf, count)?; // Now, `result` is the value we return back to the program. - this.write_scalar(Scalar::from_machine_isize(result, this), dest)?; + this.write_scalar(Scalar::from_target_isize(result, this), dest)?; } "unlink" => { let [path] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; @@ -151,14 +151,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "readlink" => { let [pathname, buf, bufsize] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let result = this.readlink(pathname, buf, bufsize)?; - this.write_scalar(Scalar::from_machine_isize(result, this), dest)?; + this.write_scalar(Scalar::from_target_isize(result, this), dest)?; } "posix_fadvise" => { let [fd, offset, len, advice] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; this.read_scalar(fd)?.to_i32()?; - this.read_machine_isize(offset)?; - this.read_machine_isize(len)?; + this.read_target_isize(offset)?; + this.read_target_isize(len)?; this.read_scalar(advice)?.to_i32()?; // fadvise is only informational, we can ignore it. this.write_null(dest)?; @@ -191,8 +191,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "posix_memalign" => { let [ret, align, size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let ret = this.deref_operand(ret)?; - let align = this.read_machine_usize(align)?; - let size = this.read_machine_usize(size)?; + let align = this.read_target_usize(align)?; + let size = this.read_target_usize(size)?; // Align must be power of 2, and also at least ptr-sized (POSIX rules). // But failure to adhere to this is not UB, it's an error condition. if !align.is_power_of_two() || align < this.pointer_size().bytes() { @@ -216,7 +216,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Dynamic symbol loading "dlsym" => { let [handle, symbol] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - this.read_machine_usize(handle)?; + this.read_target_usize(handle)?; let symbol = this.read_pointer(symbol)?; let symbol_name = this.read_c_str(symbol)?; if let Some(dlsym) = Dlsym::from_str(symbol_name, &this.tcx.sess.target.os)? { @@ -472,7 +472,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [errnum, buf, buflen] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let errnum = this.read_scalar(errnum)?; let buf = this.read_pointer(buf)?; - let buflen = this.read_machine_usize(buflen)?; + let buflen = this.read_target_usize(buflen)?; let error = this.try_errnum_to_io_error(errnum)?; let formatted = match error { @@ -565,7 +565,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let uid = this.read_scalar(uid)?.to_u32()?; let pwd = this.deref_operand(pwd)?; let buf = this.read_pointer(buf)?; - let buflen = this.read_machine_usize(buflen)?; + let buflen = this.read_target_usize(buflen)?; let result = this.deref_operand(result)?; // Must be for "us". diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index 1b8f52f36657d..d05c4d98fad6f 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -754,7 +754,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // We cap the number of read bytes to the largest value that we are able to fit in both the // host's and target's `isize`. This saves us from having to handle overflows later. let count = count - .min(u64::try_from(this.machine_isize_max()).unwrap()) + .min(u64::try_from(this.target_isize_max()).unwrap()) .min(u64::try_from(isize::MAX).unwrap()); let communicate = this.machine.communicate(); @@ -807,7 +807,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // We cap the number of written bytes to the largest value that we are able to fit in both the // host's and target's `isize`. This saves us from having to handle overflows later. let count = count - .min(u64::try_from(this.machine_isize_max()).unwrap()) + .min(u64::try_from(this.target_isize_max()).unwrap()) .min(u64::try_from(isize::MAX).unwrap()); let communicate = this.machine.communicate(); @@ -1290,7 +1290,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // The libc API for opendir says that this method returns a pointer to an opaque // structure, but we are returning an ID number. Thus, pass it as a scalar of // pointer width. - Ok(Scalar::from_machine_usize(id, this)) + Ok(Scalar::from_target_usize(id, this)) } Err(e) => { this.set_last_error_from_io_error(e.kind())?; @@ -1307,7 +1307,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.assert_target_os("linux", "readdir64"); - let dirp = this.read_machine_usize(dirp_op)?; + let dirp = this.read_target_usize(dirp_op)?; // Reject if isolation is enabled. if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op { @@ -1399,7 +1399,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.assert_target_os("macos", "readdir_r"); - let dirp = this.read_machine_usize(dirp_op)?; + let dirp = this.read_target_usize(dirp_op)?; // Reject if isolation is enabled. if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op { @@ -1492,7 +1492,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn closedir(&mut self, dirp_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); - let dirp = this.read_machine_usize(dirp_op)?; + let dirp = this.read_target_usize(dirp_op)?; // Reject if isolation is enabled. if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op { @@ -1656,7 +1656,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let pathname = this.read_path_from_c_str(this.read_pointer(pathname_op)?)?; let buf = this.read_pointer(buf_op)?; - let bufsize = this.read_machine_usize(bufsize_op)?; + let bufsize = this.read_target_usize(bufsize_op)?; // Reject if isolation is enabled. if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op { @@ -1727,7 +1727,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.reject_in_isolation("`realpath`", reject_with)?; let eacc = this.eval_libc("EACCES"); this.set_last_error(eacc)?; - return Ok(Scalar::from_machine_usize(0, this)); + return Ok(Scalar::from_target_usize(0, this)); } let result = std::fs::canonicalize(pathname); @@ -1758,7 +1758,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // seems like a bit of a mess anyway: . let enametoolong = this.eval_libc("ENAMETOOLONG"); this.set_last_error(enametoolong)?; - return Ok(Scalar::from_machine_usize(0, this)); + return Ok(Scalar::from_target_usize(0, this)); } processed_ptr }; @@ -1767,7 +1767,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } Err(e) => { this.set_last_error_from_io_error(e.kind())?; - Ok(Scalar::from_machine_usize(0, this)) + Ok(Scalar::from_target_usize(0, this)) } } } diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs index 82cb21c124a26..9f6938424fb2d 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -119,18 +119,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // argument, we have to also check all arguments *before* it to ensure that they // have the right type. - let sys_getrandom = this.eval_libc("SYS_getrandom").to_machine_usize(this)?; + let sys_getrandom = this.eval_libc("SYS_getrandom").to_target_usize(this)?; - let sys_statx = this.eval_libc("SYS_statx").to_machine_usize(this)?; + let sys_statx = this.eval_libc("SYS_statx").to_target_usize(this)?; - let sys_futex = this.eval_libc("SYS_futex").to_machine_usize(this)?; + let sys_futex = this.eval_libc("SYS_futex").to_target_usize(this)?; if args.is_empty() { throw_ub_format!( "incorrect number of arguments for syscall: got 0, expected at least 1" ); } - match this.read_machine_usize(&args[0])? { + match this.read_target_usize(&args[0])? { // `libc::syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), GRND_NONBLOCK)` // is called if a `HashMap` is created the regular way (e.g. HashMap). id if id == sys_getrandom => { @@ -155,7 +155,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } let result = this.linux_statx(&args[1], &args[2], &args[3], &args[4], &args[5])?; - this.write_scalar(Scalar::from_machine_isize(result.into(), this), dest)?; + this.write_scalar(Scalar::from_target_isize(result.into(), this), dest)?; } // `futex` is used by some synchonization primitives. id if id == sys_futex => { @@ -178,7 +178,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [pid, cpusetsize, mask] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; this.read_scalar(pid)?.to_i32()?; - this.read_machine_usize(cpusetsize)?; + this.read_target_usize(cpusetsize)?; this.deref_operand(mask)?; // FIXME: we just return an error; `num_cpus` then falls back to `sysconf`. let einval = this.eval_libc("EINVAL"); @@ -210,7 +210,7 @@ fn getrandom<'tcx>( dest: &PlaceTy<'tcx, Provenance>, ) -> InterpResult<'tcx> { let ptr = this.read_pointer(ptr)?; - let len = this.read_machine_usize(len)?; + let len = this.read_target_usize(len)?; // The only supported flags are GRND_RANDOM and GRND_NONBLOCK, // neither of which have any effect on our current PRNG. @@ -218,6 +218,6 @@ fn getrandom<'tcx>( let _flags = this.read_scalar(flags)?.to_i32(); this.gen_random(ptr, len)?; - this.write_scalar(Scalar::from_machine_usize(len, this), dest)?; + this.write_scalar(Scalar::from_target_usize(len, this), dest)?; Ok(()) } diff --git a/src/tools/miri/src/shims/unix/linux/sync.rs b/src/tools/miri/src/shims/unix/linux/sync.rs index ef43c9b0ff438..ffe3ca69c5866 100644 --- a/src/tools/miri/src/shims/unix/linux/sync.rs +++ b/src/tools/miri/src/shims/unix/linux/sync.rs @@ -81,7 +81,7 @@ pub fn futex<'tcx>( if bitset == 0 { let einval = this.eval_libc("EINVAL"); this.set_last_error(einval)?; - this.write_scalar(Scalar::from_machine_isize(-1, this), dest)?; + this.write_scalar(Scalar::from_target_isize(-1, this), dest)?; return Ok(()); } @@ -101,7 +101,7 @@ pub fn futex<'tcx>( None => { let einval = this.eval_libc("EINVAL"); this.set_last_error(einval)?; - this.write_scalar(Scalar::from_machine_isize(-1, this), dest)?; + this.write_scalar(Scalar::from_target_isize(-1, this), dest)?; return Ok(()); } }; @@ -173,7 +173,7 @@ pub fn futex<'tcx>( this.block_thread(thread); this.futex_wait(addr_usize, thread, bitset); // Succesfully waking up from FUTEX_WAIT always returns zero. - this.write_scalar(Scalar::from_machine_isize(0, this), dest)?; + this.write_scalar(Scalar::from_target_isize(0, this), dest)?; // Register a timeout callback if a timeout was specified. // This callback will override the return value when the timeout triggers. if let Some(timeout_time) = timeout_time { @@ -196,7 +196,7 @@ pub fn futex<'tcx>( this.futex_remove_waiter(self.addr_usize, self.thread); let etimedout = this.eval_libc("ETIMEDOUT"); this.set_last_error(etimedout)?; - this.write_scalar(Scalar::from_machine_isize(-1, this), &self.dest)?; + this.write_scalar(Scalar::from_target_isize(-1, this), &self.dest)?; Ok(()) } @@ -213,7 +213,7 @@ pub fn futex<'tcx>( // right away without sleeping: -1 and errno set to EAGAIN. let eagain = this.eval_libc("EAGAIN"); this.set_last_error(eagain)?; - this.write_scalar(Scalar::from_machine_isize(-1, this), dest)?; + this.write_scalar(Scalar::from_target_isize(-1, this), dest)?; } } // FUTEX_WAKE: (int *addr, int op = FUTEX_WAKE, int val) @@ -239,7 +239,7 @@ pub fn futex<'tcx>( if bitset == 0 { let einval = this.eval_libc("EINVAL"); this.set_last_error(einval)?; - this.write_scalar(Scalar::from_machine_isize(-1, this), dest)?; + this.write_scalar(Scalar::from_target_isize(-1, this), dest)?; return Ok(()); } // Together with the SeqCst fence in futex_wait, this makes sure that futex_wait @@ -257,7 +257,7 @@ pub fn futex<'tcx>( break; } } - this.write_scalar(Scalar::from_machine_isize(n, this), dest)?; + this.write_scalar(Scalar::from_target_isize(n, this), dest)?; } op => throw_unsup_format!("Miri does not support `futex` syscall with op={}", op), } diff --git a/src/tools/miri/src/shims/unix/macos/dlsym.rs b/src/tools/miri/src/shims/unix/macos/dlsym.rs index 44b9af79005a9..9177ecefe1207 100644 --- a/src/tools/miri/src/shims/unix/macos/dlsym.rs +++ b/src/tools/miri/src/shims/unix/macos/dlsym.rs @@ -39,7 +39,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { Dlsym::getentropy => { let [ptr, len] = check_arg_count(args)?; let ptr = this.read_pointer(ptr)?; - let len = this.read_machine_usize(len)?; + let len = this.read_target_usize(len)?; this.gen_random(ptr, len)?; this.write_null(dest)?; } diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs index a55b0ee523b08..1271788a97ef0 100644 --- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs @@ -161,13 +161,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Querying system information "pthread_get_stackaddr_np" => { let [thread] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - this.read_machine_usize(thread)?; + this.read_target_usize(thread)?; let stack_addr = Scalar::from_uint(this.machine.stack_addr, this.pointer_size()); this.write_scalar(stack_addr, dest)?; } "pthread_get_stacksize_np" => { let [thread] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - this.read_machine_usize(thread)?; + this.read_target_usize(thread)?; let stack_size = Scalar::from_uint(this.machine.stack_size, this.pointer_size()); this.write_scalar(stack_size, dest)?; } @@ -176,7 +176,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "pthread_setname_np" => { let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let thread = this.pthread_self()?; - let max_len = this.eval_libc("MAXTHREADNAMESIZE").to_machine_usize(this)?; + let max_len = this.eval_libc("MAXTHREADNAMESIZE").to_target_usize(this)?; let res = this.pthread_setname_np( thread, this.read_scalar(name)?, diff --git a/src/tools/miri/src/shims/unix/thread.rs b/src/tools/miri/src/shims/unix/thread.rs index 832628003d770..6165cfd282307 100644 --- a/src/tools/miri/src/shims/unix/thread.rs +++ b/src/tools/miri/src/shims/unix/thread.rs @@ -42,7 +42,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { throw_unsup_format!("Miri supports pthread_join only with retval==NULL"); } - let thread_id = this.read_machine_usize(thread)?; + let thread_id = this.read_target_usize(thread)?; this.join_thread_exclusive(thread_id.try_into().expect("thread ID should fit in u32"))?; Ok(0) @@ -51,7 +51,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn pthread_detach(&mut self, thread: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); - let thread_id = this.read_machine_usize(thread)?; + let thread_id = this.read_target_usize(thread)?; this.detach_thread( thread_id.try_into().expect("thread ID should fit in u32"), /*allow_terminated_joined*/ false, @@ -64,7 +64,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let this = self.eval_context_mut(); let thread_id = this.get_active_thread(); - Ok(Scalar::from_machine_usize(thread_id.into(), this)) + Ok(Scalar::from_target_usize(thread_id.into(), this)) } /// Set the name of the current thread. `max_name_len` is the maximal length of the name @@ -77,7 +77,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - let thread = ThreadId::try_from(thread.to_machine_usize(this)?).unwrap(); + let thread = ThreadId::try_from(thread.to_target_usize(this)?).unwrap(); let name = name.to_pointer(this)?; let name = this.read_c_str(name)?.to_owned(); @@ -100,9 +100,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - let thread = ThreadId::try_from(thread.to_machine_usize(this)?).unwrap(); + let thread = ThreadId::try_from(thread.to_target_usize(this)?).unwrap(); let name_out = name_out.to_pointer(this)?; - let len = len.to_machine_usize(this)?; + let len = len.to_target_usize(this)?; let name = this.get_thread_name(thread).to_owned(); let (success, _written) = this.write_c_str(&name, name_out, len)?; diff --git a/src/tools/miri/src/shims/windows/dlsym.rs b/src/tools/miri/src/shims/windows/dlsym.rs index 857cf1ae7037b..60dd299c43813 100644 --- a/src/tools/miri/src/shims/windows/dlsym.rs +++ b/src/tools/miri/src/shims/windows/dlsym.rs @@ -67,10 +67,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { byte_offset, _key, ] = check_arg_count(args)?; - let handle = this.read_machine_isize(handle)?; + let handle = this.read_target_isize(handle)?; let buf = this.read_pointer(buf)?; let n = this.read_scalar(n)?.to_u32()?; - let byte_offset = this.read_machine_usize(byte_offset)?; // is actually a pointer + let byte_offset = this.read_target_usize(byte_offset)?; // is actually a pointer let io_status_block = this.deref_operand(io_status_block)?; if byte_offset != 0 { @@ -104,7 +104,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let io_status_information = this.mplace_field_named(&io_status_block, "Information")?; this.write_scalar( - Scalar::from_machine_usize(n.into(), this), + Scalar::from_target_usize(n.into(), this), &io_status_information.into(), )?; } diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index f310d16e86198..a3d7176a97686 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -73,9 +73,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "HeapAlloc" => { let [handle, flags, size] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; - this.read_machine_isize(handle)?; + this.read_target_isize(handle)?; let flags = this.read_scalar(flags)?.to_u32()?; - let size = this.read_machine_usize(size)?; + let size = this.read_target_usize(size)?; let heap_zero_memory = 0x00000008; // HEAP_ZERO_MEMORY let zero_init = (flags & heap_zero_memory) == heap_zero_memory; let res = this.malloc(size, zero_init, MiriMemoryKind::WinHeap)?; @@ -84,7 +84,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "HeapFree" => { let [handle, flags, ptr] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; - this.read_machine_isize(handle)?; + this.read_target_isize(handle)?; this.read_scalar(flags)?.to_u32()?; let ptr = this.read_pointer(ptr)?; this.free(ptr, MiriMemoryKind::WinHeap)?; @@ -93,10 +93,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "HeapReAlloc" => { let [handle, flags, ptr, size] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; - this.read_machine_isize(handle)?; + this.read_target_isize(handle)?; this.read_scalar(flags)?.to_u32()?; let ptr = this.read_pointer(ptr)?; - let size = this.read_machine_usize(size)?; + let size = this.read_target_usize(size)?; let res = this.realloc(ptr, size, MiriMemoryKind::WinHeap)?; this.write_pointer(res, dest)?; } @@ -299,7 +299,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { #[allow(non_snake_case)] let [hModule, lpProcName] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; - this.read_machine_isize(hModule)?; + this.read_target_isize(hModule)?; let name = this.read_c_str(this.read_pointer(lpProcName)?)?; if let Some(dlsym) = Dlsym::from_str(name, &this.tcx.sess.target.os)? { let ptr = this.create_fn_alloc_ptr(FnVal::Other(dlsym)); @@ -323,7 +323,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [algorithm, ptr, len, flags] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; let algorithm = this.read_scalar(algorithm)?; - let algorithm = algorithm.to_machine_usize(this)?; + let algorithm = algorithm.to_target_usize(this)?; let ptr = this.read_pointer(ptr)?; let len = this.read_scalar(len)?.to_u32()?; let flags = this.read_scalar(flags)?.to_u32()?; @@ -357,7 +357,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // `term` needs this, so we fake it. let [console, buffer_info] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; - this.read_machine_isize(console)?; + this.read_target_isize(console)?; this.deref_operand(buffer_info)?; // Indicate an error. // FIXME: we should set last_error, but to what? @@ -371,7 +371,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // one it is. This is very fake, but libtest needs it so we cannot make it a // std-only shim. // FIXME: this should return real HANDLEs when io support is added - this.write_scalar(Scalar::from_machine_isize(which.into(), this), dest)?; + this.write_scalar(Scalar::from_target_isize(which.into(), this), dest)?; } "CloseHandle" => { let [handle] = @@ -386,7 +386,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; this.check_no_isolation("`GetModuleFileNameW`")?; - let handle = this.read_machine_usize(handle)?; + let handle = this.read_target_usize(handle)?; let filename = this.read_pointer(filename)?; let size = this.read_scalar(size)?.to_u32()?; @@ -473,7 +473,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "GetConsoleMode" if this.frame_in_std() => { let [console, mode] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; - this.read_machine_isize(console)?; + this.read_target_isize(console)?; this.deref_operand(mode)?; // Indicate an error. this.write_null(dest)?; diff --git a/src/tools/miri/src/shims/windows/handle.rs b/src/tools/miri/src/shims/windows/handle.rs index 5b22c4bd73584..8bffa9991c75a 100644 --- a/src/tools/miri/src/shims/windows/handle.rs +++ b/src/tools/miri/src/shims/windows/handle.rs @@ -124,14 +124,14 @@ impl Handle { // see https://docs.microsoft.com/en-us/windows/win32/winprog64/interprocess-communication #[allow(clippy::cast_possible_wrap)] // we want it to wrap let signed_handle = self.to_packed() as i32; - Scalar::from_machine_isize(signed_handle.into(), cx) + Scalar::from_target_isize(signed_handle.into(), cx) } pub fn from_scalar<'tcx>( handle: Scalar, cx: &impl HasDataLayout, ) -> InterpResult<'tcx, Option> { - let sign_extended_handle = handle.to_machine_isize(cx)?; + let sign_extended_handle = handle.to_target_isize(cx)?; #[allow(clippy::cast_sign_loss)] // we want to lose the sign let handle = if let Ok(signed_handle) = i32::try_from(sign_extended_handle) { diff --git a/src/tools/miri/src/shims/windows/sync.rs b/src/tools/miri/src/shims/windows/sync.rs index 9177f1632f704..b9cc3e15be9fe 100644 --- a/src/tools/miri/src/shims/windows/sync.rs +++ b/src/tools/miri/src/shims/windows/sync.rs @@ -273,7 +273,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let ptr = this.read_pointer(ptr_op)?; let compare = this.read_pointer(compare_op)?; - let size = this.read_machine_usize(size_op)?; + let size = this.read_target_usize(size_op)?; let timeout_ms = this.read_scalar(timeout_op)?.to_u32()?; let thread = this.get_active_thread(); diff --git a/src/tools/miri/src/shims/windows/thread.rs b/src/tools/miri/src/shims/windows/thread.rs index f5bf362ea1caf..9cbae15885985 100644 --- a/src/tools/miri/src/shims/windows/thread.rs +++ b/src/tools/miri/src/shims/windows/thread.rs @@ -21,7 +21,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let security = this.read_pointer(security_op)?; // stacksize is ignored, but still needs to be a valid usize - this.read_machine_usize(stacksize_op)?; + this.read_target_usize(stacksize_op)?; let start_routine = this.read_pointer(start_op)?; let func_arg = this.read_immediate(arg_op)?; let flags = this.read_scalar(flags_op)?.to_u32()?; diff --git a/src/tools/x/Cargo.toml b/src/tools/x/Cargo.toml index 3150272796234..84a42ca36ef1c 100644 --- a/src/tools/x/Cargo.toml +++ b/src/tools/x/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "x" -version = "0.1.0" +version = "0.1.1" description = "Run x.py slightly more conveniently" edition = "2021" publish = false diff --git a/src/tools/x/src/main.rs b/src/tools/x/src/main.rs index 01f7187851e38..5da8a2888ec83 100644 --- a/src/tools/x/src/main.rs +++ b/src/tools/x/src/main.rs @@ -9,11 +9,47 @@ //! We also don't use `pwsh` on Windows, because it is not installed by default; use std::{ - env, io, + env::{self, consts::EXE_EXTENSION}, + io, path::Path, process::{self, Command, ExitStatus}, }; +const PYTHON: &str = "python"; +const PYTHON2: &str = "python2"; +const PYTHON3: &str = "python3"; + +fn python() -> &'static str { + let val = match env::var_os("PATH") { + Some(val) => val, + None => return PYTHON, + }; + + let mut python2 = false; + let mut python3 = false; + + for dir in env::split_paths(&val) { + // `python` should always take precedence over python2 / python3 if it exists + if dir.join(PYTHON).with_extension(EXE_EXTENSION).exists() { + return PYTHON; + } + + python2 |= dir.join(PYTHON2).with_extension(EXE_EXTENSION).exists(); + python3 |= dir.join(PYTHON3).with_extension(EXE_EXTENSION).exists(); + } + + // try 3 before 2 + if python3 { + PYTHON3 + } else if python2 { + PYTHON2 + } else { + // Python was not found on path, so exit + eprintln!("Unable to find python in your PATH. Please check it is installed."); + process::exit(1); + } +} + #[cfg(windows)] fn x_command(dir: &Path) -> Command { let mut cmd = Command::new("powershell.exe"); @@ -51,6 +87,17 @@ fn exec_or_status(command: &mut Command) -> io::Result { command.status() } +fn handle_result(result: io::Result, cmd: Command) { + match result { + Err(error) => { + eprintln!("Failed to invoke `{:?}`: {}", cmd, error); + } + Ok(status) => { + process::exit(status.code().unwrap_or(1)); + } + } +} + fn main() { match env::args().skip(1).next().as_deref() { Some("--wrapper-version") => { @@ -70,22 +117,19 @@ fn main() { for dir in current.ancestors() { let candidate = dir.join("x.py"); - if candidate.exists() { - let mut cmd = x_command(dir); - - cmd.args(env::args().skip(1)).current_dir(dir); - - let result = exec_or_status(&mut cmd); - - match result { - Err(error) => { - eprintln!("Failed to invoke `{:?}`: {}", cmd, error); - } - Ok(status) => { - process::exit(status.code().unwrap_or(1)); - } + let shell_script_candidate = dir.join("x"); + let mut cmd: Command; + if shell_script_candidate.exists() { + cmd = x_command(dir); + cmd.args(env::args().skip(1)).current_dir(dir); + } else { + // For older checkouts that do not have the x shell script, default to python + cmd = Command::new(python()); + cmd.arg(&candidate).args(env::args().skip(1)).current_dir(dir); } + let result = exec_or_status(&mut cmd); + handle_result(result, cmd); } } diff --git a/tests/ui/associated-consts/issue-105330.stderr b/tests/ui/associated-consts/issue-105330.stderr index 30c380152a5e6..08570d4a5d982 100644 --- a/tests/ui/associated-consts/issue-105330.stderr +++ b/tests/ui/associated-consts/issue-105330.stderr @@ -33,7 +33,7 @@ LL | fn main>() { = note: see issue #92827 for more information = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl header --> $DIR/issue-105330.rs:6:27 | LL | impl TraitWAssocConst for impl Demo { diff --git a/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed b/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed index 26703fbf81193..b74b5e94e2b75 100644 --- a/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed +++ b/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed @@ -26,7 +26,7 @@ fn test_send_trait() { //~| HELP: add a dummy let to cause `fptr` to be fully captured *fptr.0 = 20; //~^ NOTE: in Rust 2018, this closure captures all of `fptr`, but in Rust 2021, it will only capture `fptr.0` - } }); + } }).join().unwrap(); } /* Test Sync Trait Migration */ @@ -47,7 +47,7 @@ fn test_sync_trait() { //~| HELP: add a dummy let to cause `fptr` to be fully captured *fptr.0.0 = 20; //~^ NOTE: in Rust 2018, this closure captures all of `fptr`, but in Rust 2021, it will only capture `fptr.0.0` - } }); + } }).join().unwrap(); } /* Test Clone Trait Migration */ diff --git a/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.rs b/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.rs index 932db51d43713..e4965e33cc16f 100644 --- a/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.rs +++ b/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.rs @@ -26,7 +26,7 @@ fn test_send_trait() { //~| HELP: add a dummy let to cause `fptr` to be fully captured *fptr.0 = 20; //~^ NOTE: in Rust 2018, this closure captures all of `fptr`, but in Rust 2021, it will only capture `fptr.0` - }); + }).join().unwrap(); } /* Test Sync Trait Migration */ @@ -47,7 +47,7 @@ fn test_sync_trait() { //~| HELP: add a dummy let to cause `fptr` to be fully captured *fptr.0.0 = 20; //~^ NOTE: in Rust 2018, this closure captures all of `fptr`, but in Rust 2021, it will only capture `fptr.0.0` - }); + }).join().unwrap(); } /* Test Clone Trait Migration */ diff --git a/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr b/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr index 3a42cc8b8439b..856ec4a5b9eb3 100644 --- a/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr +++ b/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr @@ -19,7 +19,7 @@ LL ~ thread::spawn(move || { let _ = &fptr; unsafe { LL | ... LL | -LL ~ } }); +LL ~ } }).join().unwrap(); | error: changes to closure capture in Rust 2021 will affect which traits the closure implements @@ -41,7 +41,7 @@ LL ~ thread::spawn(move || { let _ = &fptr; unsafe { LL | ... LL | -LL ~ } }); +LL ~ } }).join().unwrap(); | error: changes to closure capture in Rust 2021 will affect drop order and which traits the closure implements diff --git a/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.fixed b/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.fixed index 173dd2e2cff2e..bde8c7497310d 100644 --- a/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.fixed +++ b/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.fixed @@ -145,7 +145,7 @@ fn test_multi_traits_issues() { //~^ NOTE: in Rust 2018, this closure captures all of `fptr1`, but in Rust 2021, it will only capture `fptr1.0.0` *fptr2.0 = 20; //~^ NOTE: in Rust 2018, this closure captures all of `fptr2`, but in Rust 2021, it will only capture `fptr2.0` - } }); + } }).join().unwrap(); } fn main() { diff --git a/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.rs b/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.rs index cfc4555ca03a0..584c52ea13430 100644 --- a/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.rs +++ b/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.rs @@ -141,7 +141,7 @@ fn test_multi_traits_issues() { //~^ NOTE: in Rust 2018, this closure captures all of `fptr1`, but in Rust 2021, it will only capture `fptr1.0.0` *fptr2.0 = 20; //~^ NOTE: in Rust 2018, this closure captures all of `fptr2`, but in Rust 2021, it will only capture `fptr2.0` - }); + }).join().unwrap(); } fn main() { diff --git a/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr b/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr index efb264447f68d..344bc662ee73f 100644 --- a/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr +++ b/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr @@ -111,7 +111,7 @@ LL ~ thread::spawn(move || { let _ = (&fptr1, &fptr2); unsafe { LL | ... LL | -LL ~ } }); +LL ~ } }).join().unwrap(); | error: aborting due to 5 previous errors diff --git a/tests/ui/consts/const-eval/issue-91827-extern-types.rs b/tests/ui/consts/const-eval/issue-91827-extern-types.rs index 43c99799f7704..c9aaa6e558747 100644 --- a/tests/ui/consts/const-eval/issue-91827-extern-types.rs +++ b/tests/ui/consts/const-eval/issue-91827-extern-types.rs @@ -28,7 +28,10 @@ pub struct ListImpl { impl List { const fn as_slice(&self) -> &[T] { - unsafe { std::slice::from_raw_parts(self.data.as_ptr(), self.len) } + unsafe { + let ptr = addr_of!(self.tail) as *const T; + std::slice::from_raw_parts(ptr, self.len) + } } } diff --git a/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr b/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr index 5be1d97a05985..6f2919b6c0909 100644 --- a/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr +++ b/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr @@ -115,13 +115,13 @@ LL | let _: impl Tr1 = S1; = note: see issue #52662 for more information = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const type --> $DIR/feature-gate-associated_type_bounds.rs:58:14 | LL | const _cdef: impl Tr1 = S1; | ^^^^^^^^^^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const type --> $DIR/feature-gate-associated_type_bounds.rs:64:15 | LL | static _sdef: impl Tr1 = S1; diff --git a/tests/ui/impl-trait/issues/issue-58956.stderr b/tests/ui/impl-trait/issues/issue-58956.stderr index 123fb4df4b3c8..f591c07bcf5f4 100644 --- a/tests/ui/impl-trait/issues/issue-58956.stderr +++ b/tests/ui/impl-trait/issues/issue-58956.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const type --> $DIR/issue-58956.rs:7:11 | LL | const _A: impl Lam = { diff --git a/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr b/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr index e635e554e2384..a227f0ba7d135 100644 --- a/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr +++ b/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr @@ -1,10 +1,10 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default --> $DIR/issue-83929-impl-trait-in-generic-default.rs:1:16 | LL | struct Foo(T); | ^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default --> $DIR/issue-83929-impl-trait-in-generic-default.rs:4:20 | LL | type Result = std::result::Result; diff --git a/tests/ui/impl-trait/issues/issue-86642.stderr b/tests/ui/impl-trait/issues/issue-86642.stderr index 0ec118d5be802..a137777840b31 100644 --- a/tests/ui/impl-trait/issues/issue-86642.stderr +++ b/tests/ui/impl-trait/issues/issue-86642.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const type --> $DIR/issue-86642.rs:1:11 | LL | static x: impl Fn(&str) -> Result<&str, ()> = move |source| { diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr index e3a9caa646026..201aba3adff96 100644 --- a/tests/ui/impl-trait/where-allowed.stderr +++ b/tests/ui/impl-trait/where-allowed.stderr @@ -115,31 +115,31 @@ error[E0562]: `impl Trait` only allowed in function and inherent method return t LL | fn in_Fn_return_in_generics impl Debug> (_: F) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type --> $DIR/where-allowed.rs:81:32 | LL | struct InBraceStructField { x: impl Debug } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in path +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type --> $DIR/where-allowed.rs:85:41 | LL | struct InAdtInBraceStructField { x: Vec } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type --> $DIR/where-allowed.rs:89:27 | LL | struct InTupleStructField(impl Debug); | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type --> $DIR/where-allowed.rs:94:25 | LL | InBraceVariant { x: impl Debug }, | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type --> $DIR/where-allowed.rs:96:20 | LL | InTupleVariant(impl Debug), @@ -187,31 +187,31 @@ error[E0562]: `impl Trait` only allowed in function and inherent method return t LL | impl PartialEq for () { | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl header --> $DIR/where-allowed.rs:166:24 | LL | impl PartialEq<()> for impl Debug { | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl header --> $DIR/where-allowed.rs:171:6 | LL | impl impl Debug { | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl header --> $DIR/where-allowed.rs:177:24 | LL | impl InInherentImplAdt { | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bound --> $DIR/where-allowed.rs:183:11 | LL | where impl Debug: Debug | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bound --> $DIR/where-allowed.rs:190:15 | LL | where Vec: Debug @@ -235,37 +235,37 @@ error[E0562]: `impl Trait` only allowed in function and inherent method return t LL | where T: Fn() -> impl Debug | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default --> $DIR/where-allowed.rs:217:40 | LL | struct InStructGenericParamDefault(T); | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default --> $DIR/where-allowed.rs:221:36 | LL | enum InEnumGenericParamDefault { Variant(T) } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default --> $DIR/where-allowed.rs:225:38 | LL | trait InTraitGenericParamDefault {} | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default --> $DIR/where-allowed.rs:229:41 | LL | type InTypeAliasGenericParamDefault = T; | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default --> $DIR/where-allowed.rs:233:11 | LL | impl T {} | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default --> $DIR/where-allowed.rs:240:40 | LL | fn in_method_generic_param_default(_: T) {} diff --git a/tests/ui/suggestions/trait-hidden-method.rs b/tests/ui/suggestions/trait-hidden-method.rs new file mode 100644 index 0000000000000..ae7ef47e1d4de --- /dev/null +++ b/tests/ui/suggestions/trait-hidden-method.rs @@ -0,0 +1,11 @@ +// #107983 - testing that `__iterator_get_unchecked` isn't suggested +// HELP included so that compiletest errors on the bad suggestion +pub fn i_can_has_iterator() -> impl Iterator { + //~^ ERROR expected `Box` + //~| HELP consider constraining the associated type + Box::new(1..=10) as Box + //~^ ERROR the value of the associated type `Item` + //~| HELP specify the associated type +} + +fn main() {} diff --git a/tests/ui/suggestions/trait-hidden-method.stderr b/tests/ui/suggestions/trait-hidden-method.stderr new file mode 100644 index 0000000000000..a5a65d193db06 --- /dev/null +++ b/tests/ui/suggestions/trait-hidden-method.stderr @@ -0,0 +1,24 @@ +error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified + --> $DIR/trait-hidden-method.rs:6:33 + | +LL | Box::new(1..=10) as Box + | ^^^^^^^^ help: specify the associated type: `Iterator` + +error[E0271]: expected `Box` to be an iterator that yields `u32`, but it yields `::Item` + --> $DIR/trait-hidden-method.rs:3:32 + | +LL | pub fn i_can_has_iterator() -> impl Iterator { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found `u32` +... +LL | Box::new(1..=10) as Box + | ------------------------------------- return type was inferred to be `Box` here + | + = note: expected associated type `::Item` + found type `u32` + = help: consider constraining the associated type `::Item` to `u32` or calling a method that returns `::Item` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0191, E0271. +For more information about an error, try `rustc --explain E0191`. diff --git a/tests/ui/unsized/unsized3-rpass.rs b/tests/ui/unsized/unsized3-rpass.rs index 4d5e89575bef6..a3f92be6cf61f 100644 --- a/tests/ui/unsized/unsized3-rpass.rs +++ b/tests/ui/unsized/unsized3-rpass.rs @@ -59,7 +59,7 @@ pub fn main() { } let data: Box> = Box::new(Foo_ { f: [1, 2, 3] }); - let x: &Foo = mem::transmute(slice::from_raw_parts(&*data, 3)); + let x: &Foo = mem::transmute(ptr::slice_from_raw_parts(&*data, 3)); assert_eq!(x.f.len(), 3); assert_eq!(x.f[0], 1); @@ -70,7 +70,7 @@ pub fn main() { let data: Box<_> = Box::new(Baz_ { f1: 42, f2: ['a' as u8, 'b' as u8, 'c' as u8, 'd' as u8, 'e' as u8] }); - let x: &Baz = mem::transmute(slice::from_raw_parts(&*data, 5)); + let x: &Baz = mem::transmute(ptr::slice_from_raw_parts(&*data, 5)); assert_eq!(x.f1, 42); let chs: Vec = x.f2.chars().collect(); assert_eq!(chs.len(), 5);