Skip to content

Commit 942db67

Browse files
committed
Auto merge of #136641 - matthiaskrgr:rollup-lajwje5, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #136073 (Always compute coroutine layout for eagerly emitting recursive layout errors) - #136235 (Pretty print pattern type values with transmute if they don't satisfy their pattern) - #136311 (Ensure that we never try to monomorphize the upcasting or vtable calls of impossible dyn types) - #136315 (Use short ty string for binop and unop errors) - #136393 (Fix accidentally not emitting overflowing literals lints anymore in patterns) - #136435 (Simplify some code for lowering THIR patterns) - #136630 (Change two std process tests to not output to std{out,err}, and fix test suite stat reset in bootstrap CI test rendering) r? `@ghost` `@rustbot` modify labels: rollup try-job: aarch64-gnu-debug
2 parents 79f82ad + 5b22425 commit 942db67

File tree

45 files changed

+524
-349
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+524
-349
lines changed

compiler/rustc_const_eval/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ pub fn provide(providers: &mut Providers) {
5151
providers.check_validity_requirement = |tcx, (init_kind, param_env_and_ty)| {
5252
util::check_validity_requirement(tcx, init_kind, param_env_and_ty)
5353
};
54+
providers.hooks.validate_scalar_in_layout =
55+
|tcx, scalar, layout| util::validate_scalar_in_layout(tcx, scalar, layout);
5456
}
5557

5658
/// `rustc_driver::main` installs a handler that will set this to `true` if

compiler/rustc_const_eval/src/util/check_validity_requirement.rs

+41-13
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use rustc_abi::{BackendRepr, FieldsShape, Scalar, Variants};
2-
use rustc_middle::bug;
32
use rustc_middle::ty::layout::{
43
HasTyCtxt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, ValidityRequirement,
54
};
6-
use rustc_middle::ty::{PseudoCanonicalInput, Ty, TyCtxt};
5+
use rustc_middle::ty::{PseudoCanonicalInput, ScalarInt, Ty, TyCtxt};
6+
use rustc_middle::{bug, ty};
7+
use rustc_span::DUMMY_SP;
78

89
use crate::const_eval::{CanAccessMutGlobal, CheckAlignment, CompileTimeMachine};
910
use crate::interpret::{InterpCx, MemoryKind};
@@ -34,7 +35,7 @@ pub fn check_validity_requirement<'tcx>(
3435

3536
let layout_cx = LayoutCx::new(tcx, input.typing_env);
3637
if kind == ValidityRequirement::Uninit || tcx.sess.opts.unstable_opts.strict_init_checks {
37-
check_validity_requirement_strict(layout, &layout_cx, kind)
38+
Ok(check_validity_requirement_strict(layout, &layout_cx, kind))
3839
} else {
3940
check_validity_requirement_lax(layout, &layout_cx, kind)
4041
}
@@ -46,10 +47,10 @@ fn check_validity_requirement_strict<'tcx>(
4647
ty: TyAndLayout<'tcx>,
4748
cx: &LayoutCx<'tcx>,
4849
kind: ValidityRequirement,
49-
) -> Result<bool, &'tcx LayoutError<'tcx>> {
50+
) -> bool {
5051
let machine = CompileTimeMachine::new(CanAccessMutGlobal::No, CheckAlignment::Error);
5152

52-
let mut cx = InterpCx::new(cx.tcx(), rustc_span::DUMMY_SP, cx.typing_env, machine);
53+
let mut cx = InterpCx::new(cx.tcx(), DUMMY_SP, cx.typing_env, machine);
5354

5455
let allocated = cx
5556
.allocate(ty, MemoryKind::Machine(crate::const_eval::MemoryKind::Heap))
@@ -69,14 +70,13 @@ fn check_validity_requirement_strict<'tcx>(
6970
// due to this.
7071
// The value we are validating is temporary and discarded at the end of this function, so
7172
// there is no point in reseting provenance and padding.
72-
Ok(cx
73-
.validate_operand(
74-
&allocated.into(),
75-
/*recursive*/ false,
76-
/*reset_provenance_and_padding*/ false,
77-
)
78-
.discard_err()
79-
.is_some())
73+
cx.validate_operand(
74+
&allocated.into(),
75+
/*recursive*/ false,
76+
/*reset_provenance_and_padding*/ false,
77+
)
78+
.discard_err()
79+
.is_some()
8080
}
8181

8282
/// Implements the 'lax' (default) version of the [`check_validity_requirement`] checks; see that
@@ -168,3 +168,31 @@ fn check_validity_requirement_lax<'tcx>(
168168

169169
Ok(true)
170170
}
171+
172+
pub(crate) fn validate_scalar_in_layout<'tcx>(
173+
tcx: TyCtxt<'tcx>,
174+
scalar: ScalarInt,
175+
ty: Ty<'tcx>,
176+
) -> bool {
177+
let machine = CompileTimeMachine::new(CanAccessMutGlobal::No, CheckAlignment::Error);
178+
179+
let typing_env = ty::TypingEnv::fully_monomorphized();
180+
let mut cx = InterpCx::new(tcx, DUMMY_SP, typing_env, machine);
181+
182+
let Ok(layout) = cx.layout_of(ty) else {
183+
bug!("could not compute layout of {scalar:?}:{ty:?}")
184+
};
185+
let allocated = cx
186+
.allocate(layout, MemoryKind::Machine(crate::const_eval::MemoryKind::Heap))
187+
.expect("OOM: failed to allocate for uninit check");
188+
189+
cx.write_scalar(scalar, &allocated).unwrap();
190+
191+
cx.validate_operand(
192+
&allocated.into(),
193+
/*recursive*/ false,
194+
/*reset_provenance_and_padding*/ false,
195+
)
196+
.discard_err()
197+
.is_some()
198+
}

compiler/rustc_const_eval/src/util/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ mod type_name;
88

99
pub use self::alignment::{is_disaligned, is_within_packed};
1010
pub use self::check_validity_requirement::check_validity_requirement;
11+
pub(crate) use self::check_validity_requirement::validate_scalar_in_layout;
1112
pub use self::compare_types::{relate_types, sub_types};
1213
pub use self::type_name::type_name;
1314

compiler/rustc_hir/src/intravisit.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,9 @@ pub trait Visitor<'v>: Sized {
345345
fn visit_pat_expr(&mut self, expr: &'v PatExpr<'v>) -> Self::Result {
346346
walk_pat_expr(self, expr)
347347
}
348+
fn visit_lit(&mut self, _hir_id: HirId, _lit: &'v Lit, _negated: bool) -> Self::Result {
349+
Self::Result::output()
350+
}
348351
fn visit_anon_const(&mut self, c: &'v AnonConst) -> Self::Result {
349352
walk_anon_const(self, c)
350353
}
@@ -764,7 +767,7 @@ pub fn walk_pat_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v PatField<'
764767
pub fn walk_pat_expr<'v, V: Visitor<'v>>(visitor: &mut V, expr: &'v PatExpr<'v>) -> V::Result {
765768
try_visit!(visitor.visit_id(expr.hir_id));
766769
match &expr.kind {
767-
PatExprKind::Lit { .. } => V::Result::output(),
770+
PatExprKind::Lit { lit, negated } => visitor.visit_lit(expr.hir_id, lit, *negated),
768771
PatExprKind::ConstBlock(c) => visitor.visit_inline_const(c),
769772
PatExprKind::Path(qpath) => visitor.visit_qpath(qpath, expr.hir_id, expr.span),
770773
}
@@ -912,7 +915,8 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
912915
try_visit!(visitor.visit_expr(expr));
913916
visit_opt!(visitor, visit_ty_unambig, ty);
914917
}
915-
ExprKind::Lit(_) | ExprKind::Err(_) => {}
918+
ExprKind::Lit(lit) => try_visit!(visitor.visit_lit(expression.hir_id, lit, false)),
919+
ExprKind::Err(_) => {}
916920
}
917921
V::Result::output()
918922
}

compiler/rustc_hir_analysis/src/check/check.rs

+4-25
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use rustc_middle::span_bug;
1919
use rustc_middle::ty::error::TypeErrorToStringExt;
2020
use rustc_middle::ty::fold::{BottomUpFolder, fold_regions};
2121
use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
22-
use rustc_middle::ty::util::{Discr, InspectCoroutineFields, IntTypeExt};
22+
use rustc_middle::ty::util::{Discr, IntTypeExt};
2323
use rustc_middle::ty::{
2424
AdtDef, GenericArgKind, RegionKind, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
2525
};
@@ -257,30 +257,9 @@ pub(super) fn check_opaque_for_cycles<'tcx>(
257257

258258
// First, try to look at any opaque expansion cycles, considering coroutine fields
259259
// (even though these aren't necessarily true errors).
260-
if tcx
261-
.try_expand_impl_trait_type(def_id.to_def_id(), args, InspectCoroutineFields::Yes)
262-
.is_err()
263-
{
264-
// Look for true opaque expansion cycles, but ignore coroutines.
265-
// This will give us any true errors. Coroutines are only problematic
266-
// if they cause layout computation errors.
267-
if tcx
268-
.try_expand_impl_trait_type(def_id.to_def_id(), args, InspectCoroutineFields::No)
269-
.is_err()
270-
{
271-
let reported = opaque_type_cycle_error(tcx, def_id);
272-
return Err(reported);
273-
}
274-
275-
// And also look for cycle errors in the layout of coroutines.
276-
if let Err(&LayoutError::Cycle(guar)) =
277-
tcx.layout_of(
278-
ty::TypingEnv::post_analysis(tcx, def_id.to_def_id())
279-
.as_query_input(Ty::new_opaque(tcx, def_id.to_def_id(), args)),
280-
)
281-
{
282-
return Err(guar);
283-
}
260+
if tcx.try_expand_impl_trait_type(def_id.to_def_id(), args).is_err() {
261+
let reported = opaque_type_cycle_error(tcx, def_id);
262+
return Err(reported);
284263
}
285264

286265
Ok(())

compiler/rustc_hir_typeck/src/op.rs

+44-27
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
306306
lang_item_for_op(self.tcx, Op::Binary(op, is_assign), op.span);
307307
let missing_trait = trait_def_id
308308
.map(|def_id| with_no_trimmed_paths!(self.tcx.def_path_str(def_id)));
309+
let mut path = None;
310+
let lhs_ty_str = self.tcx.short_string(lhs_ty, &mut path);
311+
let rhs_ty_str = self.tcx.short_string(rhs_ty, &mut path);
309312
let (mut err, output_def_id) = match is_assign {
310313
IsAssign::Yes => {
311314
let mut err = struct_span_code_err!(
@@ -314,53 +317,54 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
314317
E0368,
315318
"binary assignment operation `{}=` cannot be applied to type `{}`",
316319
op.node.as_str(),
317-
lhs_ty,
320+
lhs_ty_str,
318321
);
319322
err.span_label(
320323
lhs_expr.span,
321-
format!("cannot use `{}=` on type `{}`", op.node.as_str(), lhs_ty),
324+
format!("cannot use `{}=` on type `{}`", op.node.as_str(), lhs_ty_str),
322325
);
323326
self.note_unmet_impls_on_type(&mut err, errors, false);
324327
(err, None)
325328
}
326329
IsAssign::No => {
327330
let message = match op.node {
328331
hir::BinOpKind::Add => {
329-
format!("cannot add `{rhs_ty}` to `{lhs_ty}`")
332+
format!("cannot add `{rhs_ty_str}` to `{lhs_ty_str}`")
330333
}
331334
hir::BinOpKind::Sub => {
332-
format!("cannot subtract `{rhs_ty}` from `{lhs_ty}`")
335+
format!("cannot subtract `{rhs_ty_str}` from `{lhs_ty_str}`")
333336
}
334337
hir::BinOpKind::Mul => {
335-
format!("cannot multiply `{lhs_ty}` by `{rhs_ty}`")
338+
format!("cannot multiply `{lhs_ty_str}` by `{rhs_ty_str}`")
336339
}
337340
hir::BinOpKind::Div => {
338-
format!("cannot divide `{lhs_ty}` by `{rhs_ty}`")
341+
format!("cannot divide `{lhs_ty_str}` by `{rhs_ty_str}`")
339342
}
340343
hir::BinOpKind::Rem => {
341344
format!(
342-
"cannot calculate the remainder of `{lhs_ty}` divided by `{rhs_ty}`"
345+
"cannot calculate the remainder of `{lhs_ty_str}` divided by \
346+
`{rhs_ty_str}`"
343347
)
344348
}
345349
hir::BinOpKind::BitAnd => {
346-
format!("no implementation for `{lhs_ty} & {rhs_ty}`")
350+
format!("no implementation for `{lhs_ty_str} & {rhs_ty_str}`")
347351
}
348352
hir::BinOpKind::BitXor => {
349-
format!("no implementation for `{lhs_ty} ^ {rhs_ty}`")
353+
format!("no implementation for `{lhs_ty_str} ^ {rhs_ty_str}`")
350354
}
351355
hir::BinOpKind::BitOr => {
352-
format!("no implementation for `{lhs_ty} | {rhs_ty}`")
356+
format!("no implementation for `{lhs_ty_str} | {rhs_ty_str}`")
353357
}
354358
hir::BinOpKind::Shl => {
355-
format!("no implementation for `{lhs_ty} << {rhs_ty}`")
359+
format!("no implementation for `{lhs_ty_str} << {rhs_ty_str}`")
356360
}
357361
hir::BinOpKind::Shr => {
358-
format!("no implementation for `{lhs_ty} >> {rhs_ty}`")
362+
format!("no implementation for `{lhs_ty_str} >> {rhs_ty_str}`")
359363
}
360364
_ => format!(
361365
"binary operation `{}` cannot be applied to type `{}`",
362366
op.node.as_str(),
363-
lhs_ty
367+
lhs_ty_str,
364368
),
365369
};
366370
let output_def_id = trait_def_id.and_then(|def_id| {
@@ -375,14 +379,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
375379
let mut err =
376380
struct_span_code_err!(self.dcx(), op.span, E0369, "{message}");
377381
if !lhs_expr.span.eq(&rhs_expr.span) {
378-
err.span_label(lhs_expr.span, lhs_ty.to_string());
379-
err.span_label(rhs_expr.span, rhs_ty.to_string());
382+
err.span_label(lhs_expr.span, lhs_ty_str.clone());
383+
err.span_label(rhs_expr.span, rhs_ty_str);
380384
}
381385
let suggest_derive = self.can_eq(self.param_env, lhs_ty, rhs_ty);
382386
self.note_unmet_impls_on_type(&mut err, errors, suggest_derive);
383387
(err, output_def_id)
384388
}
385389
};
390+
*err.long_ty_path() = path;
386391

387392
// Try to suggest a semicolon if it's `A \n *B` where `B` is a place expr
388393
let maybe_missing_semi = self.check_for_missing_semi(expr, &mut err);
@@ -417,7 +422,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
417422
IsAssign::Yes => "=",
418423
IsAssign::No => "",
419424
},
420-
lhs_deref_ty,
425+
self.tcx.short_string(lhs_deref_ty, err.long_ty_path()),
421426
);
422427
err.span_suggestion_verbose(
423428
lhs_expr.span.shrink_to_lo(),
@@ -443,8 +448,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
443448
)
444449
.is_ok()
445450
{
446-
let op_str = op.node.as_str();
447-
err.note(format!("an implementation for `{lhs_adjusted_ty} {op_str} {rhs_adjusted_ty}` exists"));
451+
let lhs = self.tcx.short_string(lhs_adjusted_ty, err.long_ty_path());
452+
let rhs = self.tcx.short_string(rhs_adjusted_ty, err.long_ty_path());
453+
let op = op.node.as_str();
454+
err.note(format!("an implementation for `{lhs} {op} {rhs}` exists"));
448455

449456
if let Some(lhs_new_mutbl) = lhs_new_mutbl
450457
&& let Some(rhs_new_mutbl) = rhs_new_mutbl
@@ -628,7 +635,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
628635
// When we know that a missing bound is responsible, we don't show
629636
// this note as it is redundant.
630637
err.note(format!(
631-
"the trait `{missing_trait}` is not implemented for `{lhs_ty}`"
638+
"the trait `{missing_trait}` is not implemented for `{lhs_ty_str}`"
632639
));
633640
}
634641
}
@@ -654,24 +661,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
654661
hir::BinOpKind::Sub => {
655662
if lhs_ty.is_unsafe_ptr() && rhs_ty.is_integral() {
656663
err.multipart_suggestion(
657-
"consider using `wrapping_sub` or `sub` for pointer - {integer}",
664+
"consider using `wrapping_sub` or `sub` for \
665+
pointer - {integer}",
658666
vec![
659-
(lhs_expr.span.between(rhs_expr.span), ".wrapping_sub(".to_owned()),
667+
(
668+
lhs_expr.span.between(rhs_expr.span),
669+
".wrapping_sub(".to_owned(),
670+
),
660671
(rhs_expr.span.shrink_to_hi(), ")".to_owned()),
661672
],
662-
Applicability::MaybeIncorrect
673+
Applicability::MaybeIncorrect,
663674
);
664675
}
665676

666677
if lhs_ty.is_unsafe_ptr() && rhs_ty.is_unsafe_ptr() {
667678
err.multipart_suggestion(
668-
"consider using `offset_from` for pointer - pointer if the pointers point to the same allocation",
679+
"consider using `offset_from` for pointer - pointer if the \
680+
pointers point to the same allocation",
669681
vec![
670682
(lhs_expr.span.shrink_to_lo(), "unsafe { ".to_owned()),
671-
(lhs_expr.span.between(rhs_expr.span), ".offset_from(".to_owned()),
683+
(
684+
lhs_expr.span.between(rhs_expr.span),
685+
".offset_from(".to_owned(),
686+
),
672687
(rhs_expr.span.shrink_to_hi(), ") }".to_owned()),
673688
],
674-
Applicability::MaybeIncorrect
689+
Applicability::MaybeIncorrect,
675690
);
676691
}
677692
}
@@ -793,14 +808,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
793808
Err(errors) => {
794809
let actual = self.resolve_vars_if_possible(operand_ty);
795810
let guar = actual.error_reported().err().unwrap_or_else(|| {
811+
let mut file = None;
812+
let ty_str = self.tcx.short_string(actual, &mut file);
796813
let mut err = struct_span_code_err!(
797814
self.dcx(),
798815
ex.span,
799816
E0600,
800-
"cannot apply unary operator `{}` to type `{}`",
817+
"cannot apply unary operator `{}` to type `{ty_str}`",
801818
op.as_str(),
802-
actual
803819
);
820+
*err.long_ty_path() = file;
804821
err.span_label(
805822
ex.span,
806823
format!("cannot apply unary operator `{}`", op.as_str()),

compiler/rustc_interface/src/passes.rs

+5
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,11 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
909909
tcx.ensure_ok().check_coroutine_obligations(
910910
tcx.typeck_root_def_id(def_id.to_def_id()).expect_local(),
911911
);
912+
// Eagerly check the unsubstituted layout for cycles.
913+
tcx.ensure_ok().layout_of(
914+
ty::TypingEnv::post_analysis(tcx, def_id.to_def_id())
915+
.as_query_input(tcx.type_of(def_id).instantiate_identity()),
916+
);
912917
}
913918
});
914919
});

compiler/rustc_lint/src/late.rs

+4
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,10 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
152152
hir_visit::walk_pat(self, p);
153153
}
154154

155+
fn visit_lit(&mut self, hir_id: HirId, lit: &'tcx hir::Lit, negated: bool) {
156+
lint_callback!(self, check_lit, hir_id, lit, negated);
157+
}
158+
155159
fn visit_expr_field(&mut self, field: &'tcx hir::ExprField<'tcx>) {
156160
self.with_lint_attrs(field.hir_id, |cx| hir_visit::walk_expr_field(cx, field))
157161
}

compiler/rustc_lint/src/passes.rs

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ macro_rules! late_lint_methods {
2323
fn check_stmt(a: &'tcx rustc_hir::Stmt<'tcx>);
2424
fn check_arm(a: &'tcx rustc_hir::Arm<'tcx>);
2525
fn check_pat(a: &'tcx rustc_hir::Pat<'tcx>);
26+
fn check_lit(hir_id: rustc_hir::HirId, a: &'tcx rustc_hir::Lit, negated: bool);
2627
fn check_expr(a: &'tcx rustc_hir::Expr<'tcx>);
2728
fn check_expr_post(a: &'tcx rustc_hir::Expr<'tcx>);
2829
fn check_ty(a: &'tcx rustc_hir::Ty<'tcx, rustc_hir::AmbigArg>);

0 commit comments

Comments
 (0)