Skip to content

Commit 297a801

Browse files
committedApr 1, 2022
Auto merge of rust-lang#95552 - matthiaskrgr:rollup-bxminn9, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - rust-lang#95032 (Clean up, categorize and sort unstable features in std.) - rust-lang#95260 (Better suggestions for `Fn`-family trait selection errors) - rust-lang#95293 (suggest wrapping single-expr blocks in square brackets) - rust-lang#95344 (Make `impl Debug for rustdoc::clean::Item` easier to read) - rust-lang#95388 (interpret: make isize::MAX the limit for dynamic value sizes) - rust-lang#95530 (rustdoc: do not show primitives and keywords as private) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 99da9ae + c6750e4 commit 297a801

File tree

28 files changed

+702
-224
lines changed

28 files changed

+702
-224
lines changed
 

‎compiler/rustc_const_eval/src/interpret/eval_context.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ use rustc_target::abi::{call::FnAbi, Align, HasDataLayout, Size, TargetDataLayou
2323

2424
use super::{
2525
AllocCheck, AllocId, GlobalId, Immediate, InterpErrorInfo, InterpResult, MPlaceTy, Machine,
26-
MemPlace, MemPlaceMeta, Memory, MemoryKind, Operand, Place, PlaceTy, Pointer, Provenance,
27-
Scalar, ScalarMaybeUninit, StackPopJump,
26+
MemPlace, MemPlaceMeta, Memory, MemoryKind, Operand, Place, PlaceTy, Pointer,
27+
PointerArithmetic, Provenance, Scalar, ScalarMaybeUninit, StackPopJump,
2828
};
2929
use crate::transform::validate::equal_up_to_regions;
3030

@@ -678,7 +678,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
678678
let size = size.align_to(align);
679679

680680
// Check if this brought us over the size limit.
681-
if size.bytes() >= self.tcx.data_layout.obj_size_bound() {
681+
if size > self.max_size_of_val() {
682682
throw_ub!(InvalidMeta("total size is bigger than largest supported object"));
683683
}
684684
Ok(Some((size, align)))
@@ -694,9 +694,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
694694
let elem = layout.field(self, 0);
695695

696696
// Make sure the slice is not too big.
697-
let size = elem.size.checked_mul(len, self).ok_or_else(|| {
698-
err_ub!(InvalidMeta("slice is bigger than largest supported object"))
699-
})?;
697+
let size = elem.size.bytes().saturating_mul(len); // we rely on `max_size_of_val` being smaller than `u64::MAX`.
698+
let size = Size::from_bytes(size);
699+
if size > self.max_size_of_val() {
700+
throw_ub!(InvalidMeta("slice is bigger than largest supported object"));
701+
}
700702
Ok(Some((size, elem.align.abi)))
701703
}
702704

‎compiler/rustc_const_eval/src/interpret/intrinsics.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
531531
) -> InterpResult<'tcx, Pointer<Option<M::PointerTag>>> {
532532
// We cannot overflow i64 as a type's size must be <= isize::MAX.
533533
let pointee_size = i64::try_from(self.layout_of(pointee_ty)?.size.bytes()).unwrap();
534-
// The computed offset, in bytes, cannot overflow an isize.
534+
// The computed offset, in bytes, must not overflow an isize.
535+
// `checked_mul` enforces a too small bound, but no actual allocation can be big enough for
536+
// the difference to be noticeable.
535537
let offset_bytes =
536538
offset_count.checked_mul(pointee_size).ok_or(err_ub!(PointerArithOverflow))?;
537539
// The offset being in bounds cannot rely on "wrapping around" the address space.
@@ -563,6 +565,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
563565
let count = self.read_scalar(&count)?.to_machine_usize(self)?;
564566
let layout = self.layout_of(src.layout.ty.builtin_deref(true).unwrap().ty)?;
565567
let (size, align) = (layout.size, layout.align.abi);
568+
// `checked_mul` enforces a too small bound (the correct one would probably be machine_isize_max),
569+
// but no actual allocation can be big enough for the difference to be noticeable.
566570
let size = size.checked_mul(count, self).ok_or_else(|| {
567571
err_ub_format!(
568572
"overflow computing total size of `{}`",
@@ -588,6 +592,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
588592
let byte = self.read_scalar(&byte)?.to_u8()?;
589593
let count = self.read_scalar(&count)?.to_machine_usize(self)?;
590594

595+
// `checked_mul` enforces a too small bound (the correct one would probably be machine_isize_max),
596+
// but no actual allocation can be big enough for the difference to be noticeable.
591597
let len = layout
592598
.size
593599
.checked_mul(count, self)

‎compiler/rustc_const_eval/src/interpret/traits.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -110,16 +110,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
110110
.read_ptr_sized(pointer_size * u64::try_from(COMMON_VTABLE_ENTRIES_SIZE).unwrap())?
111111
.check_init()?;
112112
let size = size.to_machine_usize(self)?;
113+
let size = Size::from_bytes(size);
113114
let align = vtable
114115
.read_ptr_sized(pointer_size * u64::try_from(COMMON_VTABLE_ENTRIES_ALIGN).unwrap())?
115116
.check_init()?;
116117
let align = align.to_machine_usize(self)?;
117118
let align = Align::from_bytes(align).map_err(|e| err_ub!(InvalidVtableAlignment(e)))?;
118119

119-
if size >= self.tcx.data_layout.obj_size_bound() {
120+
if size > self.max_size_of_val() {
120121
throw_ub!(InvalidVtableSize);
121122
}
122-
Ok((Size::from_bytes(size), align))
123+
Ok((size, align))
123124
}
124125

125126
pub fn read_new_vtable_after_trait_upcasting_from_vtable(

‎compiler/rustc_infer/src/infer/error_reporting/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1091,7 +1091,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
10911091

10921092
/// Compares two given types, eliding parts that are the same between them and highlighting
10931093
/// relevant differences, and return two representation of those types for highlighted printing.
1094-
fn cmp(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) -> (DiagnosticStyledString, DiagnosticStyledString) {
1094+
pub fn cmp(
1095+
&self,
1096+
t1: Ty<'tcx>,
1097+
t2: Ty<'tcx>,
1098+
) -> (DiagnosticStyledString, DiagnosticStyledString) {
10951099
debug!("cmp(t1={}, t1.kind={:?}, t2={}, t2.kind={:?})", t1, t1.kind(), t2, t2.kind());
10961100

10971101
// helper functions

‎compiler/rustc_middle/src/mir/interpret/pointer.rs

+5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ pub trait PointerArithmetic: HasDataLayout {
1818
self.data_layout().pointer_size
1919
}
2020

21+
#[inline(always)]
22+
fn max_size_of_val(&self) -> Size {
23+
Size::from_bytes(self.machine_isize_max())
24+
}
25+
2126
#[inline]
2227
fn machine_usize_max(&self) -> u64 {
2328
self.pointer_size().unsigned_int_max().try_into().unwrap()

‎compiler/rustc_middle/src/ty/closure.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,21 @@ impl<'tcx> ClosureKind {
119119
/// See `Ty::to_opt_closure_kind` for more details.
120120
pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
121121
match self {
122-
ty::ClosureKind::Fn => tcx.types.i8,
123-
ty::ClosureKind::FnMut => tcx.types.i16,
124-
ty::ClosureKind::FnOnce => tcx.types.i32,
122+
ClosureKind::Fn => tcx.types.i8,
123+
ClosureKind::FnMut => tcx.types.i16,
124+
ClosureKind::FnOnce => tcx.types.i32,
125+
}
126+
}
127+
128+
pub fn from_def_id(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ClosureKind> {
129+
if Some(def_id) == tcx.lang_items().fn_once_trait() {
130+
Some(ClosureKind::FnOnce)
131+
} else if Some(def_id) == tcx.lang_items().fn_mut_trait() {
132+
Some(ClosureKind::FnMut)
133+
} else if Some(def_id) == tcx.lang_items().fn_trait() {
134+
Some(ClosureKind::Fn)
135+
} else {
136+
None
125137
}
126138
}
127139
}

‎compiler/rustc_parse/src/parser/expr.rs

+7-11
Original file line numberDiff line numberDiff line change
@@ -1919,17 +1919,13 @@ impl<'a> Parser<'a> {
19191919
match snapshot.parse_array_or_repeat_expr(attrs, token::Brace) {
19201920
Ok(arr) => {
19211921
let hi = snapshot.prev_token.span;
1922-
self.struct_span_err(
1923-
arr.span,
1924-
"this code is interpreted as a block expression, not an array",
1925-
)
1926-
.multipart_suggestion(
1927-
"try using [] instead of {}",
1928-
vec![(lo, "[".to_owned()), (hi, "]".to_owned())],
1929-
Applicability::MaybeIncorrect,
1930-
)
1931-
.note("to define an array, one would use square brackets instead of curly braces")
1932-
.emit();
1922+
self.struct_span_err(arr.span, "this is a block expression, not an array")
1923+
.multipart_suggestion(
1924+
"to make an array, use square brackets instead of curly braces",
1925+
vec![(lo, "[".to_owned()), (hi, "]".to_owned())],
1926+
Applicability::MaybeIncorrect,
1927+
)
1928+
.emit();
19331929

19341930
self.restore_snapshot(snapshot);
19351931
Some(self.mk_expr_err(arr.span))

‎compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+121-5
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ pub mod on_unimplemented;
22
pub mod suggestions;
33

44
use super::{
5-
EvaluationResult, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes,
6-
Obligation, ObligationCause, ObligationCauseCode, OnUnimplementedDirective,
7-
OnUnimplementedNote, OutputTypeParameterMismatch, Overflow, PredicateObligation,
8-
SelectionContext, SelectionError, TraitNotObjectSafe,
5+
EvaluationResult, FulfillmentContext, FulfillmentError, FulfillmentErrorCode,
6+
MismatchedProjectionTypes, Obligation, ObligationCause, ObligationCauseCode,
7+
OnUnimplementedDirective, OnUnimplementedNote, OutputTypeParameterMismatch, Overflow,
8+
PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe,
99
};
1010

1111
use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
@@ -21,6 +21,8 @@ use rustc_hir::intravisit::Visitor;
2121
use rustc_hir::GenericParam;
2222
use rustc_hir::Item;
2323
use rustc_hir::Node;
24+
use rustc_infer::infer::error_reporting::same_type_modulo_infer;
25+
use rustc_infer::traits::TraitEngine;
2426
use rustc_middle::thir::abstract_const::NotConstEvaluatable;
2527
use rustc_middle::traits::select::OverflowError;
2628
use rustc_middle::ty::error::ExpectedFound;
@@ -103,6 +105,17 @@ pub trait InferCtxtExt<'tcx> {
103105
found_args: Vec<ArgKind>,
104106
is_closure: bool,
105107
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>;
108+
109+
/// Checks if the type implements one of `Fn`, `FnMut`, or `FnOnce`
110+
/// in that order, and returns the generic type corresponding to the
111+
/// argument of that trait (corresponding to the closure arguments).
112+
fn type_implements_fn_trait(
113+
&self,
114+
param_env: ty::ParamEnv<'tcx>,
115+
ty: ty::Binder<'tcx, Ty<'tcx>>,
116+
constness: ty::BoundConstness,
117+
polarity: ty::ImplPolarity,
118+
) -> Result<(ty::ClosureKind, ty::Binder<'tcx, Ty<'tcx>>), ()>;
106119
}
107120

108121
impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
@@ -563,7 +576,64 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
563576
}
564577

565578
// Try to report a help message
566-
if !trait_ref.has_infer_types_or_consts()
579+
if is_fn_trait
580+
&& let Ok((implemented_kind, params)) = self.type_implements_fn_trait(
581+
obligation.param_env,
582+
trait_ref.self_ty(),
583+
trait_predicate.skip_binder().constness,
584+
trait_predicate.skip_binder().polarity,
585+
)
586+
{
587+
// If the type implements `Fn`, `FnMut`, or `FnOnce`, suppress the following
588+
// suggestion to add trait bounds for the type, since we only typically implement
589+
// these traits once.
590+
591+
// Note if the `FnMut` or `FnOnce` is less general than the trait we're trying
592+
// to implement.
593+
let selected_kind =
594+
ty::ClosureKind::from_def_id(self.tcx, trait_ref.def_id())
595+
.expect("expected to map DefId to ClosureKind");
596+
if !implemented_kind.extends(selected_kind) {
597+
err.note(
598+
&format!(
599+
"`{}` implements `{}`, but it must implement `{}`, which is more general",
600+
trait_ref.skip_binder().self_ty(),
601+
implemented_kind,
602+
selected_kind
603+
)
604+
);
605+
}
606+
607+
// Note any argument mismatches
608+
let given_ty = params.skip_binder();
609+
let expected_ty = trait_ref.skip_binder().substs.type_at(1);
610+
if let ty::Tuple(given) = given_ty.kind()
611+
&& let ty::Tuple(expected) = expected_ty.kind()
612+
{
613+
if expected.len() != given.len() {
614+
// Note number of types that were expected and given
615+
err.note(
616+
&format!(
617+
"expected a closure taking {} argument{}, but one taking {} argument{} was given",
618+
given.len(),
619+
if given.len() == 1 { "" } else { "s" },
620+
expected.len(),
621+
if expected.len() == 1 { "" } else { "s" },
622+
)
623+
);
624+
} else if !same_type_modulo_infer(given_ty, expected_ty) {
625+
// Print type mismatch
626+
let (expected_args, given_args) =
627+
self.cmp(given_ty, expected_ty);
628+
err.note_expected_found(
629+
&"a closure with arguments",
630+
expected_args,
631+
&"a closure with arguments",
632+
given_args,
633+
);
634+
}
635+
}
636+
} else if !trait_ref.has_infer_types_or_consts()
567637
&& self.predicate_can_apply(obligation.param_env, trait_ref)
568638
{
569639
// If a where-clause may be useful, remind the
@@ -1148,6 +1218,52 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
11481218

11491219
err
11501220
}
1221+
1222+
fn type_implements_fn_trait(
1223+
&self,
1224+
param_env: ty::ParamEnv<'tcx>,
1225+
ty: ty::Binder<'tcx, Ty<'tcx>>,
1226+
constness: ty::BoundConstness,
1227+
polarity: ty::ImplPolarity,
1228+
) -> Result<(ty::ClosureKind, ty::Binder<'tcx, Ty<'tcx>>), ()> {
1229+
self.commit_if_ok(|_| {
1230+
for trait_def_id in [
1231+
self.tcx.lang_items().fn_trait(),
1232+
self.tcx.lang_items().fn_mut_trait(),
1233+
self.tcx.lang_items().fn_once_trait(),
1234+
] {
1235+
let Some(trait_def_id) = trait_def_id else { continue };
1236+
// Make a fresh inference variable so we can determine what the substitutions
1237+
// of the trait are.
1238+
let var = self.next_ty_var(TypeVariableOrigin {
1239+
span: DUMMY_SP,
1240+
kind: TypeVariableOriginKind::MiscVariable,
1241+
});
1242+
let substs = self.tcx.mk_substs_trait(ty.skip_binder(), &[var.into()]);
1243+
let obligation = Obligation::new(
1244+
ObligationCause::dummy(),
1245+
param_env,
1246+
ty.rebind(ty::TraitPredicate {
1247+
trait_ref: ty::TraitRef::new(trait_def_id, substs),
1248+
constness,
1249+
polarity,
1250+
})
1251+
.to_predicate(self.tcx),
1252+
);
1253+
let mut fulfill_cx = FulfillmentContext::new_in_snapshot();
1254+
fulfill_cx.register_predicate_obligation(self, obligation);
1255+
if fulfill_cx.select_all_or_error(self).is_empty() {
1256+
return Ok((
1257+
ty::ClosureKind::from_def_id(self.tcx, trait_def_id)
1258+
.expect("expected to map DefId to ClosureKind"),
1259+
ty.rebind(self.resolve_vars_if_possible(var)),
1260+
));
1261+
}
1262+
}
1263+
1264+
Err(())
1265+
})
1266+
}
11511267
}
11521268

11531269
trait InferCtxtPrivExt<'hir, 'tcx> {

‎compiler/rustc_typeck/src/check/demand.rs

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3939
self.suggest_no_capture_closure(err, expected, expr_ty);
4040
self.suggest_boxing_when_appropriate(err, expr, expected, expr_ty);
4141
self.suggest_missing_parentheses(err, expr);
42+
self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected);
4243
self.note_need_for_fn_pointer(err, expected, expr_ty);
4344
self.note_internal_mutation_in_method(err, expr, expected, expr_ty);
4445
self.report_closure_inferred_return_type(err, expected);

‎compiler/rustc_typeck/src/check/fn_ctxt/checks.rs

+80-65
Original file line numberDiff line numberDiff line change
@@ -774,57 +774,68 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
774774
let prev_diverges = self.diverges.get();
775775
let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false };
776776

777-
let (ctxt, ()) =
778-
self.with_breakable_ctxt(blk.hir_id, ctxt, || {
779-
for (pos, s) in blk.stmts.iter().enumerate() {
780-
self.check_stmt(s, blk.stmts.len() - 1 == pos);
781-
}
777+
let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
778+
for (pos, s) in blk.stmts.iter().enumerate() {
779+
self.check_stmt(s, blk.stmts.len() - 1 == pos);
780+
}
782781

783-
// check the tail expression **without** holding the
784-
// `enclosing_breakables` lock below.
785-
let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
786-
787-
let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
788-
let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
789-
let coerce = ctxt.coerce.as_mut().unwrap();
790-
if let Some(tail_expr_ty) = tail_expr_ty {
791-
let tail_expr = tail_expr.unwrap();
792-
let span = self.get_expr_coercion_span(tail_expr);
793-
let cause =
794-
self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
795-
coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
796-
} else {
797-
// Subtle: if there is no explicit tail expression,
798-
// that is typically equivalent to a tail expression
799-
// of `()` -- except if the block diverges. In that
800-
// case, there is no value supplied from the tail
801-
// expression (assuming there are no other breaks,
802-
// this implies that the type of the block will be
803-
// `!`).
804-
//
805-
// #41425 -- label the implicit `()` as being the
806-
// "found type" here, rather than the "expected type".
807-
if !self.diverges.get().is_always() {
808-
// #50009 -- Do not point at the entire fn block span, point at the return type
809-
// span, as it is the cause of the requirement, and
810-
// `consider_hint_about_removing_semicolon` will point at the last expression
811-
// if it were a relevant part of the error. This improves usability in editors
812-
// that highlight errors inline.
813-
let mut sp = blk.span;
814-
let mut fn_span = None;
815-
if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
816-
let ret_sp = decl.output.span();
817-
if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
818-
// HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
819-
// output would otherwise be incorrect and even misleading. Make sure
820-
// the span we're aiming at correspond to a `fn` body.
821-
if block_sp == blk.span {
822-
sp = ret_sp;
823-
fn_span = Some(ident.span);
824-
}
782+
// check the tail expression **without** holding the
783+
// `enclosing_breakables` lock below.
784+
let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
785+
786+
let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
787+
let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
788+
let coerce = ctxt.coerce.as_mut().unwrap();
789+
if let Some(tail_expr_ty) = tail_expr_ty {
790+
let tail_expr = tail_expr.unwrap();
791+
let span = self.get_expr_coercion_span(tail_expr);
792+
let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
793+
let ty_for_diagnostic = coerce.merged_ty();
794+
// We use coerce_inner here because we want to augment the error
795+
// suggesting to wrap the block in square brackets if it might've
796+
// been mistaken array syntax
797+
coerce.coerce_inner(
798+
self,
799+
&cause,
800+
Some(tail_expr),
801+
tail_expr_ty,
802+
Some(&mut |diag: &mut Diagnostic| {
803+
self.suggest_block_to_brackets(diag, blk, tail_expr_ty, ty_for_diagnostic);
804+
}),
805+
false,
806+
);
807+
} else {
808+
// Subtle: if there is no explicit tail expression,
809+
// that is typically equivalent to a tail expression
810+
// of `()` -- except if the block diverges. In that
811+
// case, there is no value supplied from the tail
812+
// expression (assuming there are no other breaks,
813+
// this implies that the type of the block will be
814+
// `!`).
815+
//
816+
// #41425 -- label the implicit `()` as being the
817+
// "found type" here, rather than the "expected type".
818+
if !self.diverges.get().is_always() {
819+
// #50009 -- Do not point at the entire fn block span, point at the return type
820+
// span, as it is the cause of the requirement, and
821+
// `consider_hint_about_removing_semicolon` will point at the last expression
822+
// if it were a relevant part of the error. This improves usability in editors
823+
// that highlight errors inline.
824+
let mut sp = blk.span;
825+
let mut fn_span = None;
826+
if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
827+
let ret_sp = decl.output.span();
828+
if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
829+
// HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
830+
// output would otherwise be incorrect and even misleading. Make sure
831+
// the span we're aiming at correspond to a `fn` body.
832+
if block_sp == blk.span {
833+
sp = ret_sp;
834+
fn_span = Some(ident.span);
825835
}
826836
}
827-
coerce.coerce_forced_unit(
837+
}
838+
coerce.coerce_forced_unit(
828839
self,
829840
&self.misc(sp),
830841
&mut |err| {
@@ -837,21 +848,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
837848
// Our block must be a `assign desugar local; assignment`
838849
if let Some(hir::Node::Block(hir::Block {
839850
stmts:
840-
[hir::Stmt {
841-
kind:
842-
hir::StmtKind::Local(hir::Local {
843-
source: hir::LocalSource::AssignDesugar(_),
844-
..
845-
}),
846-
..
847-
}, hir::Stmt {
848-
kind:
849-
hir::StmtKind::Expr(hir::Expr {
850-
kind: hir::ExprKind::Assign(..),
851-
..
852-
}),
853-
..
854-
}],
851+
[
852+
hir::Stmt {
853+
kind:
854+
hir::StmtKind::Local(hir::Local {
855+
source:
856+
hir::LocalSource::AssignDesugar(_),
857+
..
858+
}),
859+
..
860+
},
861+
hir::Stmt {
862+
kind:
863+
hir::StmtKind::Expr(hir::Expr {
864+
kind: hir::ExprKind::Assign(..),
865+
..
866+
}),
867+
..
868+
},
869+
],
855870
..
856871
})) = self.tcx.hir().find(blk.hir_id)
857872
{
@@ -871,9 +886,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
871886
},
872887
false,
873888
);
874-
}
875889
}
876-
});
890+
}
891+
});
877892

878893
if ctxt.may_break {
879894
// If we can break from the block, then the block's exit is always reachable

‎compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs

+71
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,77 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
766766
}
767767
}
768768

769+
/// Given an expression type mismatch, peel any `&` expressions until we get to
770+
/// a block expression, and then suggest replacing the braces with square braces
771+
/// if it was possibly mistaken array syntax.
772+
pub(crate) fn suggest_block_to_brackets_peeling_refs(
773+
&self,
774+
diag: &mut Diagnostic,
775+
mut expr: &hir::Expr<'_>,
776+
mut expr_ty: Ty<'tcx>,
777+
mut expected_ty: Ty<'tcx>,
778+
) {
779+
loop {
780+
match (&expr.kind, expr_ty.kind(), expected_ty.kind()) {
781+
(
782+
hir::ExprKind::AddrOf(_, _, inner_expr),
783+
ty::Ref(_, inner_expr_ty, _),
784+
ty::Ref(_, inner_expected_ty, _),
785+
) => {
786+
expr = *inner_expr;
787+
expr_ty = *inner_expr_ty;
788+
expected_ty = *inner_expected_ty;
789+
}
790+
(hir::ExprKind::Block(blk, _), _, _) => {
791+
self.suggest_block_to_brackets(diag, *blk, expr_ty, expected_ty);
792+
break;
793+
}
794+
_ => break,
795+
}
796+
}
797+
}
798+
799+
/// Suggest wrapping the block in square brackets instead of curly braces
800+
/// in case the block was mistaken array syntax, e.g. `{ 1 }` -> `[ 1 ]`.
801+
pub(crate) fn suggest_block_to_brackets(
802+
&self,
803+
diag: &mut Diagnostic,
804+
blk: &hir::Block<'_>,
805+
blk_ty: Ty<'tcx>,
806+
expected_ty: Ty<'tcx>,
807+
) {
808+
if let ty::Slice(elem_ty) | ty::Array(elem_ty, _) = expected_ty.kind() {
809+
if self.can_coerce(blk_ty, *elem_ty)
810+
&& blk.stmts.is_empty()
811+
&& blk.rules == hir::BlockCheckMode::DefaultBlock
812+
{
813+
let source_map = self.tcx.sess.source_map();
814+
if let Ok(snippet) = source_map.span_to_snippet(blk.span) {
815+
if snippet.starts_with('{') && snippet.ends_with('}') {
816+
diag.multipart_suggestion_verbose(
817+
"to create an array, use square brackets instead of curly braces",
818+
vec![
819+
(
820+
blk.span
821+
.shrink_to_lo()
822+
.with_hi(rustc_span::BytePos(blk.span.lo().0 + 1)),
823+
"[".to_string(),
824+
),
825+
(
826+
blk.span
827+
.shrink_to_hi()
828+
.with_lo(rustc_span::BytePos(blk.span.hi().0 - 1)),
829+
"]".to_string(),
830+
),
831+
],
832+
Applicability::MachineApplicable,
833+
);
834+
}
835+
}
836+
}
837+
}
838+
}
839+
769840
fn is_loop(&self, id: hir::HirId) -> bool {
770841
let node = self.tcx.hir().get(id);
771842
matches!(node, Node::Expr(Expr { kind: ExprKind::Loop(..), .. }))

‎library/std/src/lib.rs

+74-63
Original file line numberDiff line numberDiff line change
@@ -218,111 +218,122 @@
218218
feature(slice_index_methods, coerce_unsized, sgx_platform)
219219
)]
220220
#![deny(rustc::existing_doc_keyword)]
221-
// std is implemented with unstable features, many of which are internal
222-
// compiler details that will never be stable
223-
// NB: the following list is sorted to minimize merge conflicts.
221+
//
222+
// Language features:
224223
#![feature(alloc_error_handler)]
225-
#![feature(alloc_layout_extra)]
226-
#![feature(allocator_api)]
227224
#![feature(allocator_internals)]
228225
#![feature(allow_internal_unsafe)]
229226
#![feature(allow_internal_unstable)]
230-
#![feature(array_error_internals)]
231-
#![feature(assert_matches)]
232227
#![feature(associated_type_bounds)]
233-
#![feature(async_iterator)]
234-
#![feature(atomic_mut_ptr)]
235-
#![feature(bench_black_box)]
236228
#![feature(box_syntax)]
237229
#![feature(c_unwind)]
238-
#![feature(c_variadic)]
239-
#![feature(cfg_accessible)]
240-
#![feature(cfg_eval)]
241230
#![feature(cfg_target_thread_local)]
242-
#![feature(char_error_internals)]
243-
#![feature(char_internals)]
244-
#![feature(concat_bytes)]
245231
#![feature(concat_idents)]
246232
#![cfg_attr(bootstrap, feature(const_fn_fn_ptr_basics))]
247233
#![cfg_attr(bootstrap, feature(const_fn_trait_bound))]
248-
#![feature(const_format_args)]
249-
#![feature(const_io_structs)]
250-
#![feature(const_ip)]
251-
#![feature(const_ipv4)]
252-
#![feature(const_ipv6)]
253234
#![feature(const_mut_refs)]
254-
#![feature(const_option)]
255-
#![feature(const_socketaddr)]
256235
#![feature(const_trait_impl)]
257-
#![feature(c_size_t)]
258-
#![feature(core_ffi_c)]
259-
#![feature(core_intrinsics)]
260-
#![feature(core_panic)]
261-
#![feature(custom_test_frameworks)]
262236
#![feature(decl_macro)]
237+
#![cfg_attr(not(bootstrap), feature(deprecated_suggestion))]
263238
#![feature(doc_cfg)]
264239
#![feature(doc_cfg_hide)]
265-
#![feature(rustdoc_internals)]
266-
#![cfg_attr(not(bootstrap), feature(deprecated_suggestion))]
267240
#![feature(doc_masked)]
268241
#![feature(doc_notable_trait)]
269242
#![feature(dropck_eyepatch)]
270-
#![feature(duration_checked_float)]
271-
#![feature(duration_constants)]
272-
#![feature(edition_panic)]
273-
#![feature(exact_size_is_empty)]
274243
#![feature(exhaustive_patterns)]
275-
#![feature(extend_one)]
276-
#![feature(float_minimum_maximum)]
277-
#![feature(format_args_nl)]
278-
#![feature(strict_provenance)]
279-
#![feature(get_mut_unchecked)]
280-
#![feature(hashmap_internals)]
281-
#![feature(int_error_internals)]
282244
#![feature(intra_doc_pointers)]
283245
#![feature(lang_items)]
284246
#![feature(linkage)]
285-
#![feature(log_syntax)]
286-
#![feature(map_try_insert)]
287-
#![feature(maybe_uninit_slice)]
288-
#![feature(maybe_uninit_write_slice)]
289247
#![feature(min_specialization)]
290-
#![feature(mixed_integer_ops)]
291248
#![feature(must_not_suspend)]
292249
#![feature(needs_panic_runtime)]
293250
#![feature(negative_impls)]
294251
#![feature(never_type)]
295-
#![feature(new_uninit)]
296252
#![feature(nll)]
253+
#![feature(platform_intrinsics)]
254+
#![feature(prelude_import)]
255+
#![feature(rustc_attrs)]
256+
#![feature(rustdoc_internals)]
257+
#![feature(staged_api)]
258+
#![feature(thread_local)]
259+
#![feature(try_blocks)]
260+
//
261+
// Library features (core):
262+
#![feature(array_error_internals)]
263+
#![feature(atomic_mut_ptr)]
264+
#![feature(char_error_internals)]
265+
#![feature(char_internals)]
266+
#![feature(core_intrinsics)]
267+
#![feature(duration_checked_float)]
268+
#![feature(duration_constants)]
269+
#![feature(exact_size_is_empty)]
270+
#![feature(extend_one)]
271+
#![feature(float_minimum_maximum)]
272+
#![feature(hashmap_internals)]
273+
#![feature(int_error_internals)]
274+
#![feature(maybe_uninit_slice)]
275+
#![feature(maybe_uninit_write_slice)]
276+
#![feature(mixed_integer_ops)]
297277
#![feature(nonnull_slice_from_raw_parts)]
298-
#![feature(once_cell)]
278+
#![feature(panic_can_unwind)]
299279
#![feature(panic_info_message)]
300280
#![feature(panic_internals)]
301-
#![feature(panic_can_unwind)]
302-
#![feature(panic_unwind)]
303-
#![feature(platform_intrinsics)]
304281
#![feature(portable_simd)]
305-
#![feature(prelude_import)]
306282
#![feature(ptr_as_uninit)]
307283
#![feature(raw_os_nonzero)]
308-
#![feature(rustc_attrs)]
309-
#![feature(saturating_int_impl)]
310284
#![feature(slice_internals)]
311285
#![feature(slice_ptr_get)]
312-
#![feature(staged_api)]
313286
#![feature(std_internals)]
314-
#![feature(stdsimd)]
315287
#![feature(str_internals)]
316-
#![feature(test)]
317-
#![feature(thread_local)]
318-
#![feature(thread_local_internals)]
319-
#![feature(toowned_clone_into)]
288+
#![feature(strict_provenance)]
320289
#![feature(total_cmp)]
321-
#![feature(trace_macros)]
322-
#![feature(try_blocks)]
290+
//
291+
// Library features (alloc):
292+
#![feature(alloc_layout_extra)]
293+
#![feature(allocator_api)]
294+
#![feature(get_mut_unchecked)]
295+
#![feature(map_try_insert)]
296+
#![feature(new_uninit)]
297+
#![feature(toowned_clone_into)]
323298
#![feature(try_reserve_kind)]
324299
#![feature(vec_into_raw_parts)]
325-
// NB: the above list is sorted to minimize merge conflicts.
300+
//
301+
// Library features (unwind):
302+
#![feature(panic_unwind)]
303+
//
304+
// Only for re-exporting:
305+
#![feature(assert_matches)]
306+
#![feature(async_iterator)]
307+
#![feature(c_size_t)]
308+
#![feature(c_variadic)]
309+
#![feature(cfg_accessible)]
310+
#![feature(cfg_eval)]
311+
#![feature(concat_bytes)]
312+
#![feature(const_format_args)]
313+
#![feature(core_ffi_c)]
314+
#![feature(core_panic)]
315+
#![feature(custom_test_frameworks)]
316+
#![feature(edition_panic)]
317+
#![feature(format_args_nl)]
318+
#![feature(log_syntax)]
319+
#![feature(once_cell)]
320+
#![feature(saturating_int_impl)]
321+
#![feature(stdsimd)]
322+
#![feature(test)]
323+
#![feature(trace_macros)]
324+
//
325+
// Only used in tests/benchmarks:
326+
#![feature(bench_black_box)]
327+
//
328+
// Only for const-ness:
329+
#![feature(const_io_structs)]
330+
#![feature(const_ip)]
331+
#![feature(const_ipv4)]
332+
#![feature(const_ipv6)]
333+
#![feature(const_option)]
334+
#![feature(const_socketaddr)]
335+
#![feature(thread_local_internals)]
336+
//
326337
#![default_lib_allocator]
327338

328339
// Explicitly import the prelude. The compiler uses this same unstable attribute

‎src/librustdoc/clean/types.rs

+34-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::cell::RefCell;
22
use std::default::Default;
3+
use std::fmt;
34
use std::hash::Hash;
45
use std::iter;
56
use std::lazy::SyncOnceCell as OnceCell;
@@ -355,7 +356,7 @@ crate enum ExternalLocation {
355356
/// Anything with a source location and set of attributes and, optionally, a
356357
/// name. That is, anything that can be documented. This doesn't correspond
357358
/// directly to the AST's concept of an item; it's a strict superset.
358-
#[derive(Clone, Debug)]
359+
#[derive(Clone)]
359360
crate struct Item {
360361
/// The name of this item.
361362
/// Optional because not every item has a name, e.g. impls.
@@ -370,6 +371,27 @@ crate struct Item {
370371
crate cfg: Option<Arc<Cfg>>,
371372
}
372373

374+
/// NOTE: this does NOT unconditionally print every item, to avoid thousands of lines of logs.
375+
/// If you want to see the debug output for attributes and the `kind` as well, use `{:#?}` instead of `{:?}`.
376+
impl fmt::Debug for Item {
377+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
378+
let alternate = f.alternate();
379+
// hand-picked fields that don't bloat the logs too much
380+
let mut fmt = f.debug_struct("Item");
381+
fmt.field("name", &self.name)
382+
.field("visibility", &self.visibility)
383+
.field("def_id", &self.def_id);
384+
// allow printing the full item if someone really wants to
385+
if alternate {
386+
fmt.field("attrs", &self.attrs).field("kind", &self.kind).field("cfg", &self.cfg);
387+
} else {
388+
fmt.field("kind", &self.type_());
389+
fmt.field("docs", &self.doc_value());
390+
}
391+
fmt.finish()
392+
}
393+
}
394+
373395
// `Item` is used a lot. Make sure it doesn't unintentionally get bigger.
374396
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
375397
rustc_data_structures::static_assert_size!(Item, 56);
@@ -471,14 +493,17 @@ impl Item {
471493
) -> Item {
472494
trace!("name={:?}, def_id={:?}", name, def_id);
473495

474-
Item {
475-
def_id: def_id.into(),
476-
kind: box kind,
477-
name,
478-
attrs,
479-
visibility: cx.tcx.visibility(def_id).clean(cx),
480-
cfg,
481-
}
496+
// Primitives and Keywords are written in the source code as private modules.
497+
// The modules need to be private so that nobody actually uses them, but the
498+
// keywords and primitives that they are documenting are public.
499+
let visibility = if matches!(&kind, ItemKind::KeywordItem(..) | ItemKind::PrimitiveItem(..))
500+
{
501+
Visibility::Public
502+
} else {
503+
cx.tcx.visibility(def_id).clean(cx)
504+
};
505+
506+
Item { def_id: def_id.into(), kind: box kind, name, attrs, visibility, cfg }
482507
}
483508

484509
/// Finds all `doc` attributes as NameValues and returns their corresponding values, joined

‎src/test/rustdoc/keyword.rs

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// @has foo/index.html '//a/@href' '../foo/index.html'
1313
// @!has foo/foo/index.html
1414
// @!has-dir foo/foo
15+
// @!has foo/index.html '//span' '🔒'
1516
#[doc(keyword = "match")]
1617
/// this is a test!
1718
mod foo{}

‎src/test/rustdoc/primitive.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#![crate_name = "foo"]
2+
3+
#![feature(rustdoc_internals)]
4+
5+
// @has foo/index.html '//h2[@id="primitives"]' 'Primitive Types'
6+
// @has foo/index.html '//a[@href="primitive.i32.html"]' 'i32'
7+
// @has foo/index.html '//div[@class="sidebar-elems"]//li/a' 'Primitive Types'
8+
// @has foo/index.html '//div[@class="sidebar-elems"]//li/a/@href' '#primitives'
9+
// @has foo/primitive.i32.html '//a[@class="primitive"]' 'i32'
10+
// @has foo/primitive.i32.html '//span[@class="in-band"]' 'Primitive Type i32'
11+
// @has foo/primitive.i32.html '//section[@id="main-content"]//div[@class="docblock"]//p' 'this is a test!'
12+
// @has foo/index.html '//a/@href' '../foo/index.html'
13+
// @!has foo/index.html '//span' '🔒'
14+
#[doc(primitive = "i32")]
15+
/// this is a test!
16+
mod i32{}
17+
18+
// @has foo/primitive.bool.html '//section[@id="main-content"]//div[@class="docblock"]//p' 'hello'
19+
#[doc(primitive = "bool")]
20+
/// hello
21+
mod bool {}

‎src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr

+32-21
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,17 @@ LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
104104
error[E0080]: it is undefined behavior to use this value
105105
--> $DIR/ub-wide-ptr.rs:71:1
106106
|
107+
LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) };
108+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid reference metadata: slice is bigger than largest supported object
109+
|
110+
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
111+
= note: the raw bytes of the constant (size: 8, align: 4) {
112+
╾─allocN─╼ ff ff ff 7f │ ╾──╼....
113+
}
114+
115+
error[E0080]: it is undefined behavior to use this value
116+
--> $DIR/ub-wide-ptr.rs:74:1
117+
|
107118
LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
108119
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
109120
|
@@ -113,7 +124,7 @@ LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
113124
}
114125

115126
error[E0080]: it is undefined behavior to use this value
116-
--> $DIR/ub-wide-ptr.rs:74:1
127+
--> $DIR/ub-wide-ptr.rs:77:1
117128
|
118129
LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) };
119130
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling box (going beyond the bounds of its allocation)
@@ -124,7 +135,7 @@ LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999us
124135
}
125136

126137
error[E0080]: it is undefined behavior to use this value
127-
--> $DIR/ub-wide-ptr.rs:77:1
138+
--> $DIR/ub-wide-ptr.rs:80:1
128139
|
129140
LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) };
130141
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
@@ -135,7 +146,7 @@ LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)
135146
}
136147

137148
error[E0080]: it is undefined behavior to use this value
138-
--> $DIR/ub-wide-ptr.rs:81:1
149+
--> $DIR/ub-wide-ptr.rs:84:1
139150
|
140151
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
141152
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<deref>[0]: encountered 0x03, but expected a boolean
@@ -146,29 +157,29 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
146157
}
147158

148159
error[E0080]: it is undefined behavior to use this value
149-
--> $DIR/ub-wide-ptr.rs:87:1
160+
--> $DIR/ub-wide-ptr.rs:90:1
150161
|
151162
LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
152163
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<deref>.0: encountered 0x03, but expected a boolean
153164
|
154165
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
155166
= note: the raw bytes of the constant (size: 4, align: 4) {
156-
allocN─╼ │ ╾──╼
167+
╾allocN─╼ │ ╾──╼
157168
}
158169

159170
error[E0080]: it is undefined behavior to use this value
160-
--> $DIR/ub-wide-ptr.rs:90:1
171+
--> $DIR/ub-wide-ptr.rs:93:1
161172
|
162173
LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
163174
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<deref>.1[0]: encountered 0x03, but expected a boolean
164175
|
165176
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
166177
= note: the raw bytes of the constant (size: 4, align: 4) {
167-
allocN─╼ │ ╾──╼
178+
╾allocN─╼ │ ╾──╼
168179
}
169180

170181
error[E0080]: it is undefined behavior to use this value
171-
--> $DIR/ub-wide-ptr.rs:97:1
182+
--> $DIR/ub-wide-ptr.rs:100:1
172183
|
173184
LL | / const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe {
174185
LL | |
@@ -183,7 +194,7 @@ LL | | };
183194
}
184195

185196
error[E0080]: it is undefined behavior to use this value
186-
--> $DIR/ub-wide-ptr.rs:105:1
197+
--> $DIR/ub-wide-ptr.rs:108:1
187198
|
188199
LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) };
189200
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .0: encountered too small vtable
@@ -194,7 +205,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((
194205
}
195206

196207
error[E0080]: it is undefined behavior to use this value
197-
--> $DIR/ub-wide-ptr.rs:108:1
208+
--> $DIR/ub-wide-ptr.rs:111:1
198209
|
199210
LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) };
200211
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .0: encountered too small vtable
@@ -205,7 +216,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((
205216
}
206217

207218
error[E0080]: it is undefined behavior to use this value
208-
--> $DIR/ub-wide-ptr.rs:111:1
219+
--> $DIR/ub-wide-ptr.rs:114:1
209220
|
210221
LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) };
211222
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .0: encountered dangling vtable pointer in wide pointer
@@ -216,7 +227,7 @@ LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u
216227
}
217228

218229
error[E0080]: it is undefined behavior to use this value
219-
--> $DIR/ub-wide-ptr.rs:113:1
230+
--> $DIR/ub-wide-ptr.rs:116:1
220231
|
221232
LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) };
222233
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered unaligned vtable pointer in wide pointer
@@ -227,7 +238,7 @@ LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92
227238
}
228239

229240
error[E0080]: it is undefined behavior to use this value
230-
--> $DIR/ub-wide-ptr.rs:115:1
241+
--> $DIR/ub-wide-ptr.rs:118:1
231242
|
232243
LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) };
233244
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid drop function pointer in vtable (not pointing to a function)
@@ -238,7 +249,7 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92
238249
}
239250

240251
error[E0080]: it is undefined behavior to use this value
241-
--> $DIR/ub-wide-ptr.rs:117:1
252+
--> $DIR/ub-wide-ptr.rs:120:1
242253
|
243254
LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) };
244255
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid drop function pointer in vtable (not pointing to a function)
@@ -249,7 +260,7 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u
249260
}
250261

251262
error[E0080]: it is undefined behavior to use this value
252-
--> $DIR/ub-wide-ptr.rs:119:1
263+
--> $DIR/ub-wide-ptr.rs:122:1
253264
|
254265
LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) };
255266
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .0: encountered invalid drop function pointer in vtable (not pointing to a function)
@@ -260,7 +271,7 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::trans
260271
}
261272

262273
error[E0080]: it is undefined behavior to use this value
263-
--> $DIR/ub-wide-ptr.rs:123:1
274+
--> $DIR/ub-wide-ptr.rs:126:1
264275
|
265276
LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
266277
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<deref>.<dyn-downcast>: encountered 0x03, but expected a boolean
@@ -271,7 +282,7 @@ LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_,
271282
}
272283

273284
error[E0080]: it is undefined behavior to use this value
274-
--> $DIR/ub-wide-ptr.rs:127:1
285+
--> $DIR/ub-wide-ptr.rs:130:1
275286
|
276287
LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
277288
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling vtable pointer in wide pointer
@@ -282,7 +293,7 @@ LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute
282293
}
283294

284295
error[E0080]: it is undefined behavior to use this value
285-
--> $DIR/ub-wide-ptr.rs:129:1
296+
--> $DIR/ub-wide-ptr.rs:132:1
286297
|
287298
LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
288299
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered too small vtable
@@ -293,17 +304,17 @@ LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transm
293304
}
294305

295306
error[E0080]: could not evaluate static initializer
296-
--> $DIR/ub-wide-ptr.rs:135:5
307+
--> $DIR/ub-wide-ptr.rs:138:5
297308
|
298309
LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize))
299310
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is not a valid pointer
300311

301312
error[E0080]: could not evaluate static initializer
302-
--> $DIR/ub-wide-ptr.rs:139:5
313+
--> $DIR/ub-wide-ptr.rs:142:5
303314
|
304315
LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64))
305316
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: allocN has size N, so pointer to 12 bytes starting at offset N is out-of-bounds
306317

307-
error: aborting due to 28 previous errors
318+
error: aborting due to 29 previous errors
308319

309320
For more information about this error, try `rustc --explain E0080`.

‎src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr

+32-21
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,17 @@ LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
104104
error[E0080]: it is undefined behavior to use this value
105105
--> $DIR/ub-wide-ptr.rs:71:1
106106
|
107+
LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) };
108+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid reference metadata: slice is bigger than largest supported object
109+
|
110+
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
111+
= note: the raw bytes of the constant (size: 16, align: 8) {
112+
╾───────allocN───────╼ ff ff ff ff ff ff ff 7f │ ╾──────╼........
113+
}
114+
115+
error[E0080]: it is undefined behavior to use this value
116+
--> $DIR/ub-wide-ptr.rs:74:1
117+
|
107118
LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
108119
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
109120
|
@@ -113,7 +124,7 @@ LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
113124
}
114125

115126
error[E0080]: it is undefined behavior to use this value
116-
--> $DIR/ub-wide-ptr.rs:74:1
127+
--> $DIR/ub-wide-ptr.rs:77:1
117128
|
118129
LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) };
119130
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling box (going beyond the bounds of its allocation)
@@ -124,7 +135,7 @@ LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999us
124135
}
125136

126137
error[E0080]: it is undefined behavior to use this value
127-
--> $DIR/ub-wide-ptr.rs:77:1
138+
--> $DIR/ub-wide-ptr.rs:80:1
128139
|
129140
LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) };
130141
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
@@ -135,7 +146,7 @@ LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)
135146
}
136147

137148
error[E0080]: it is undefined behavior to use this value
138-
--> $DIR/ub-wide-ptr.rs:81:1
149+
--> $DIR/ub-wide-ptr.rs:84:1
139150
|
140151
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
141152
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<deref>[0]: encountered 0x03, but expected a boolean
@@ -146,29 +157,29 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
146157
}
147158

148159
error[E0080]: it is undefined behavior to use this value
149-
--> $DIR/ub-wide-ptr.rs:87:1
160+
--> $DIR/ub-wide-ptr.rs:90:1
150161
|
151162
LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
152163
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<deref>.0: encountered 0x03, but expected a boolean
153164
|
154165
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
155166
= note: the raw bytes of the constant (size: 8, align: 8) {
156-
╾──────allocN───────╼ │ ╾──────╼
167+
╾──────allocN───────╼ │ ╾──────╼
157168
}
158169

159170
error[E0080]: it is undefined behavior to use this value
160-
--> $DIR/ub-wide-ptr.rs:90:1
171+
--> $DIR/ub-wide-ptr.rs:93:1
161172
|
162173
LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
163174
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<deref>.1[0]: encountered 0x03, but expected a boolean
164175
|
165176
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
166177
= note: the raw bytes of the constant (size: 8, align: 8) {
167-
╾──────allocN───────╼ │ ╾──────╼
178+
╾──────allocN───────╼ │ ╾──────╼
168179
}
169180

170181
error[E0080]: it is undefined behavior to use this value
171-
--> $DIR/ub-wide-ptr.rs:97:1
182+
--> $DIR/ub-wide-ptr.rs:100:1
172183
|
173184
LL | / const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe {
174185
LL | |
@@ -183,7 +194,7 @@ LL | | };
183194
}
184195

185196
error[E0080]: it is undefined behavior to use this value
186-
--> $DIR/ub-wide-ptr.rs:105:1
197+
--> $DIR/ub-wide-ptr.rs:108:1
187198
|
188199
LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) };
189200
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .0: encountered too small vtable
@@ -194,7 +205,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((
194205
}
195206

196207
error[E0080]: it is undefined behavior to use this value
197-
--> $DIR/ub-wide-ptr.rs:108:1
208+
--> $DIR/ub-wide-ptr.rs:111:1
198209
|
199210
LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) };
200211
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .0: encountered too small vtable
@@ -205,7 +216,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((
205216
}
206217

207218
error[E0080]: it is undefined behavior to use this value
208-
--> $DIR/ub-wide-ptr.rs:111:1
219+
--> $DIR/ub-wide-ptr.rs:114:1
209220
|
210221
LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) };
211222
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .0: encountered dangling vtable pointer in wide pointer
@@ -216,7 +227,7 @@ LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u
216227
}
217228

218229
error[E0080]: it is undefined behavior to use this value
219-
--> $DIR/ub-wide-ptr.rs:113:1
230+
--> $DIR/ub-wide-ptr.rs:116:1
220231
|
221232
LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) };
222233
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered unaligned vtable pointer in wide pointer
@@ -227,7 +238,7 @@ LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92
227238
}
228239

229240
error[E0080]: it is undefined behavior to use this value
230-
--> $DIR/ub-wide-ptr.rs:115:1
241+
--> $DIR/ub-wide-ptr.rs:118:1
231242
|
232243
LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) };
233244
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid drop function pointer in vtable (not pointing to a function)
@@ -238,7 +249,7 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92
238249
}
239250

240251
error[E0080]: it is undefined behavior to use this value
241-
--> $DIR/ub-wide-ptr.rs:117:1
252+
--> $DIR/ub-wide-ptr.rs:120:1
242253
|
243254
LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) };
244255
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid drop function pointer in vtable (not pointing to a function)
@@ -249,7 +260,7 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u
249260
}
250261

251262
error[E0080]: it is undefined behavior to use this value
252-
--> $DIR/ub-wide-ptr.rs:119:1
263+
--> $DIR/ub-wide-ptr.rs:122:1
253264
|
254265
LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) };
255266
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .0: encountered invalid drop function pointer in vtable (not pointing to a function)
@@ -260,7 +271,7 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::trans
260271
}
261272

262273
error[E0080]: it is undefined behavior to use this value
263-
--> $DIR/ub-wide-ptr.rs:123:1
274+
--> $DIR/ub-wide-ptr.rs:126:1
264275
|
265276
LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
266277
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<deref>.<dyn-downcast>: encountered 0x03, but expected a boolean
@@ -271,7 +282,7 @@ LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_,
271282
}
272283

273284
error[E0080]: it is undefined behavior to use this value
274-
--> $DIR/ub-wide-ptr.rs:127:1
285+
--> $DIR/ub-wide-ptr.rs:130:1
275286
|
276287
LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
277288
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling vtable pointer in wide pointer
@@ -282,7 +293,7 @@ LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute
282293
}
283294

284295
error[E0080]: it is undefined behavior to use this value
285-
--> $DIR/ub-wide-ptr.rs:129:1
296+
--> $DIR/ub-wide-ptr.rs:132:1
286297
|
287298
LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
288299
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered too small vtable
@@ -293,17 +304,17 @@ LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transm
293304
}
294305

295306
error[E0080]: could not evaluate static initializer
296-
--> $DIR/ub-wide-ptr.rs:135:5
307+
--> $DIR/ub-wide-ptr.rs:138:5
297308
|
298309
LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize))
299310
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is not a valid pointer
300311

301312
error[E0080]: could not evaluate static initializer
302-
--> $DIR/ub-wide-ptr.rs:139:5
313+
--> $DIR/ub-wide-ptr.rs:142:5
303314
|
304315
LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64))
305316
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: allocN has size N, so pointer to 24 bytes starting at offset N is out-of-bounds
306317

307-
error: aborting due to 28 previous errors
318+
error: aborting due to 29 previous errors
308319

309320
For more information about this error, try `rustc --explain E0080`.

‎src/test/ui/consts/const-eval/ub-wide-ptr.rs

+3
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ const SLICE_LENGTH_UNINIT: &[u8] = unsafe {
6767
// bad slice: length too big
6868
const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
6969
//~^ ERROR it is undefined behavior to use this value
70+
// bad slice: length computation overflows
71+
const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) };
72+
//~^ ERROR it is undefined behavior to use this value
7073
// bad slice: length not an int
7174
const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
7275
//~^ ERROR it is undefined behavior to use this value

‎src/test/ui/consts/const-size_of_val-align_of_val.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
#![feature(const_size_of_val, const_align_of_val)]
44
#![feature(const_size_of_val_raw, const_align_of_val_raw, layout_for_ptr)]
5+
#![feature(const_slice_from_raw_parts)]
56

6-
use std::mem;
7+
use std::{mem, ptr};
78

89
struct Foo(u32);
910

@@ -34,6 +35,8 @@ const ALIGN_OF_UGH: usize = mem::align_of_val(&UGH);
3435
const SIZE_OF_SLICE: usize = mem::size_of_val("foobar".as_bytes());
3536

3637
const SIZE_OF_DANGLING: usize = unsafe { mem::size_of_val_raw(0x100 as *const i32) };
38+
const SIZE_OF_BIG: usize =
39+
unsafe { mem::size_of_val_raw(ptr::slice_from_raw_parts(0 as *const u8, isize::MAX as usize)) };
3740
const ALIGN_OF_DANGLING: usize = unsafe { mem::align_of_val_raw(0x100 as *const i16) };
3841

3942
fn main() {
@@ -46,6 +49,7 @@ fn main() {
4649
assert_eq!(ALIGN_OF_UGH, mem::align_of::<Ugh>());
4750

4851
assert_eq!(SIZE_OF_DANGLING, mem::size_of::<i32>());
52+
assert_eq!(SIZE_OF_BIG, isize::MAX as usize);
4953
assert_eq!(ALIGN_OF_DANGLING, mem::align_of::<i16>());
5054

5155
assert_eq!(SIZE_OF_SLICE, "foobar".len());
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const A: [&str; 1] = { "hello" };
2+
//~^ ERROR mismatched types
3+
4+
const B: &[u32] = &{ 1 };
5+
//~^ ERROR mismatched types
6+
7+
const C: &&[u32; 1] = &&{ 1 };
8+
//~^ ERROR mismatched types
9+
10+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/brackets-to-braces-single-element.rs:1:24
3+
|
4+
LL | const A: [&str; 1] = { "hello" };
5+
| ^^^^^^^ expected array `[&'static str; 1]`, found `&str`
6+
|
7+
help: to create an array, use square brackets instead of curly braces
8+
|
9+
LL | const A: [&str; 1] = [ "hello" ];
10+
| ~ ~
11+
12+
error[E0308]: mismatched types
13+
--> $DIR/brackets-to-braces-single-element.rs:4:19
14+
|
15+
LL | const B: &[u32] = &{ 1 };
16+
| ^^^^^^ expected slice `[u32]`, found integer
17+
|
18+
= note: expected reference `&'static [u32]`
19+
found reference `&{integer}`
20+
help: to create an array, use square brackets instead of curly braces
21+
|
22+
LL | const B: &[u32] = &[ 1 ];
23+
| ~ ~
24+
25+
error[E0308]: mismatched types
26+
--> $DIR/brackets-to-braces-single-element.rs:7:27
27+
|
28+
LL | const C: &&[u32; 1] = &&{ 1 };
29+
| ^ expected array `[u32; 1]`, found integer
30+
|
31+
help: to create an array, use square brackets instead of curly braces
32+
|
33+
LL | const C: &&[u32; 1] = &&[ 1 ];
34+
| ~ ~
35+
36+
error: aborting due to 3 previous errors
37+
38+
For more information about this error, try `rustc --explain E0308`.

‎src/test/ui/did_you_mean/issue-87830-try-brackets-for-arrays.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
fn main() {}
22

3-
const FOO: [u8; 3] = { //~ ERROR this code is interpreted as a block expression
3+
const FOO: [u8; 3] = {
4+
//~^ ERROR this is a block expression, not an array
45
1, 2, 3
56
};
67

78
const BAR: [&str; 3] = {"one", "two", "three"};
8-
//~^ ERROR this code is interpreted as a block expression
9+
//~^ ERROR this is a block expression, not an array
910

1011
fn foo() {
1112
{1, 2, 3};
12-
//~^ ERROR this code is interpreted as a block expression
13+
//~^ ERROR this is a block expression, not an array
1314
}
1415

1516
fn bar() {

‎src/test/ui/did_you_mean/issue-87830-try-brackets-for-arrays.stderr

+11-12
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,45 @@
1-
error: this code is interpreted as a block expression, not an array
1+
error: this is a block expression, not an array
22
--> $DIR/issue-87830-try-brackets-for-arrays.rs:3:22
33
|
44
LL | const FOO: [u8; 3] = {
55
| ______________________^
6+
LL | |
67
LL | | 1, 2, 3
78
LL | | };
89
| |_^
910
|
10-
= note: to define an array, one would use square brackets instead of curly braces
11-
help: try using [] instead of {}
11+
help: to make an array, use square brackets instead of curly braces
1212
|
1313
LL ~ const FOO: [u8; 3] = [
14+
LL |
1415
LL | 1, 2, 3
1516
LL ~ ];
1617
|
1718

18-
error: this code is interpreted as a block expression, not an array
19-
--> $DIR/issue-87830-try-brackets-for-arrays.rs:7:24
19+
error: this is a block expression, not an array
20+
--> $DIR/issue-87830-try-brackets-for-arrays.rs:8:24
2021
|
2122
LL | const BAR: [&str; 3] = {"one", "two", "three"};
2223
| ^^^^^^^^^^^^^^^^^^^^^^^
2324
|
24-
= note: to define an array, one would use square brackets instead of curly braces
25-
help: try using [] instead of {}
25+
help: to make an array, use square brackets instead of curly braces
2626
|
2727
LL | const BAR: [&str; 3] = ["one", "two", "three"];
2828
| ~ ~
2929

30-
error: this code is interpreted as a block expression, not an array
31-
--> $DIR/issue-87830-try-brackets-for-arrays.rs:11:5
30+
error: this is a block expression, not an array
31+
--> $DIR/issue-87830-try-brackets-for-arrays.rs:12:5
3232
|
3333
LL | {1, 2, 3};
3434
| ^^^^^^^^^
3535
|
36-
= note: to define an array, one would use square brackets instead of curly braces
37-
help: try using [] instead of {}
36+
help: to make an array, use square brackets instead of curly braces
3837
|
3938
LL | [1, 2, 3];
4039
| ~ ~
4140

4241
error: expected one of `.`, `;`, `?`, `}`, or an operator, found `,`
43-
--> $DIR/issue-87830-try-brackets-for-arrays.rs:16:6
42+
--> $DIR/issue-87830-try-brackets-for-arrays.rs:17:6
4443
|
4544
LL | 1, 2, 3
4645
| ^ expected one of `.`, `;`, `?`, `}`, or an operator

‎src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ error[E0277]: expected a `Fn<(<_ as ATC<'a>>::Type,)>` closure, found `F`
44
LL | call(f, ());
55
| ^^^^ expected an `Fn<(<_ as ATC<'a>>::Type,)>` closure, found `F`
66
|
7+
= note: expected a closure with arguments `((),)`
8+
found a closure with arguments `(<_ as ATC<'a>>::Type,)`
79
note: required by a bound in `call`
810
--> $DIR/issue-62529-3.rs:9:36
911
|

‎src/test/ui/issues/issue-59494.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ LL | let t8 = t8n(t7, t7p(f, g));
77
| required by a bound introduced by this call
88
|
99
= help: the trait `Fn<(_,)>` is not implemented for `impl Fn(((_, _), _))`
10+
= note: expected a closure with arguments `(((_, _), _),)`
11+
found a closure with arguments `(_,)`
1012
note: required by a bound in `t8n`
1113
--> $DIR/issue-59494.rs:5:45
1214
|
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
fn take(_f: impl FnMut(i32)) {}
2+
3+
fn test1(f: impl FnMut(u32)) {
4+
take(f)
5+
//~^ ERROR [E0277]
6+
}
7+
8+
fn test2(f: impl FnMut(i32, i32)) {
9+
take(f)
10+
//~^ ERROR [E0277]
11+
}
12+
13+
fn test3(f: impl FnMut()) {
14+
take(f)
15+
//~^ ERROR [E0277]
16+
}
17+
18+
fn test4(f: impl FnOnce(i32)) {
19+
take(f)
20+
//~^ ERROR [E0277]
21+
}
22+
23+
fn test5(f: impl FnOnce(u32)) {
24+
take(f)
25+
//~^ ERROR [E0277]
26+
}
27+
28+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
error[E0277]: expected a `FnMut<(i32,)>` closure, found `impl FnMut(u32)`
2+
--> $DIR/mismatch-fn-trait.rs:4:10
3+
|
4+
LL | take(f)
5+
| ---- ^ expected an `FnMut<(i32,)>` closure, found `impl FnMut(u32)`
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
= note: expected a closure with arguments `(u32,)`
10+
found a closure with arguments `(i32,)`
11+
note: required by a bound in `take`
12+
--> $DIR/mismatch-fn-trait.rs:1:18
13+
|
14+
LL | fn take(_f: impl FnMut(i32)) {}
15+
| ^^^^^^^^^^ required by this bound in `take`
16+
17+
error[E0277]: expected a `FnMut<(i32,)>` closure, found `impl FnMut(i32, i32)`
18+
--> $DIR/mismatch-fn-trait.rs:9:10
19+
|
20+
LL | take(f)
21+
| ---- ^ expected an `FnMut<(i32,)>` closure, found `impl FnMut(i32, i32)`
22+
| |
23+
| required by a bound introduced by this call
24+
|
25+
= note: expected a closure taking 2 arguments, but one taking 1 argument was given
26+
note: required by a bound in `take`
27+
--> $DIR/mismatch-fn-trait.rs:1:18
28+
|
29+
LL | fn take(_f: impl FnMut(i32)) {}
30+
| ^^^^^^^^^^ required by this bound in `take`
31+
32+
error[E0277]: expected a `FnMut<(i32,)>` closure, found `impl FnMut()`
33+
--> $DIR/mismatch-fn-trait.rs:14:10
34+
|
35+
LL | take(f)
36+
| ---- ^ expected an `FnMut<(i32,)>` closure, found `impl FnMut()`
37+
| |
38+
| required by a bound introduced by this call
39+
|
40+
= note: expected a closure taking 0 arguments, but one taking 1 argument was given
41+
note: required by a bound in `take`
42+
--> $DIR/mismatch-fn-trait.rs:1:18
43+
|
44+
LL | fn take(_f: impl FnMut(i32)) {}
45+
| ^^^^^^^^^^ required by this bound in `take`
46+
47+
error[E0277]: expected a `FnMut<(i32,)>` closure, found `impl FnOnce(i32)`
48+
--> $DIR/mismatch-fn-trait.rs:19:10
49+
|
50+
LL | take(f)
51+
| ---- ^ expected an `FnMut<(i32,)>` closure, found `impl FnOnce(i32)`
52+
| |
53+
| required by a bound introduced by this call
54+
|
55+
= note: `impl FnOnce(i32)` implements `FnOnce`, but it must implement `FnMut`, which is more general
56+
note: required by a bound in `take`
57+
--> $DIR/mismatch-fn-trait.rs:1:18
58+
|
59+
LL | fn take(_f: impl FnMut(i32)) {}
60+
| ^^^^^^^^^^ required by this bound in `take`
61+
62+
error[E0277]: expected a `FnMut<(i32,)>` closure, found `impl FnOnce(u32)`
63+
--> $DIR/mismatch-fn-trait.rs:24:10
64+
|
65+
LL | take(f)
66+
| ---- ^ expected an `FnMut<(i32,)>` closure, found `impl FnOnce(u32)`
67+
| |
68+
| required by a bound introduced by this call
69+
|
70+
= note: `impl FnOnce(u32)` implements `FnOnce`, but it must implement `FnMut`, which is more general
71+
= note: expected a closure with arguments `(u32,)`
72+
found a closure with arguments `(i32,)`
73+
note: required by a bound in `take`
74+
--> $DIR/mismatch-fn-trait.rs:1:18
75+
|
76+
LL | fn take(_f: impl FnMut(i32)) {}
77+
| ^^^^^^^^^^ required by this bound in `take`
78+
79+
error: aborting due to 5 previous errors
80+
81+
For more information about this error, try `rustc --explain E0277`.

‎src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ LL | let x = call_it(&S, 22);
77
| required by a bound introduced by this call
88
|
99
= help: the trait `Fn<(isize,)>` is not implemented for `S`
10+
= note: `S` implements `FnMut`, but it must implement `Fn`, which is more general
1011
note: required by a bound in `call_it`
1112
--> $DIR/unboxed-closures-fnmut-as-fn.rs:22:14
1213
|

0 commit comments

Comments
 (0)
Please sign in to comment.