Skip to content

Commit

Permalink
Auto merge of rust-lang#136641 - matthiaskrgr:rollup-lajwje5, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

Rollup of 7 pull requests

Successful merges:

 - rust-lang#136073 (Always compute coroutine layout for eagerly emitting recursive layout errors)
 - rust-lang#136235 (Pretty print pattern type values with transmute if they don't satisfy their pattern)
 - rust-lang#136311 (Ensure that we never try to monomorphize the upcasting or vtable calls of impossible dyn types)
 - rust-lang#136315 (Use short ty string for binop and unop errors)
 - rust-lang#136393 (Fix accidentally not emitting overflowing literals lints anymore in patterns)
 - rust-lang#136435 (Simplify some code for lowering THIR patterns)
 - rust-lang#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
  • Loading branch information
bors committed Feb 6, 2025
2 parents 79f82ad + 5b22425 commit 942db67
Show file tree
Hide file tree
Showing 45 changed files with 524 additions and 349 deletions.
2 changes: 2 additions & 0 deletions compiler/rustc_const_eval/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ pub fn provide(providers: &mut Providers) {
providers.check_validity_requirement = |tcx, (init_kind, param_env_and_ty)| {
util::check_validity_requirement(tcx, init_kind, param_env_and_ty)
};
providers.hooks.validate_scalar_in_layout =
|tcx, scalar, layout| util::validate_scalar_in_layout(tcx, scalar, layout);
}

/// `rustc_driver::main` installs a handler that will set this to `true` if
Expand Down
54 changes: 41 additions & 13 deletions compiler/rustc_const_eval/src/util/check_validity_requirement.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use rustc_abi::{BackendRepr, FieldsShape, Scalar, Variants};
use rustc_middle::bug;
use rustc_middle::ty::layout::{
HasTyCtxt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, ValidityRequirement,
};
use rustc_middle::ty::{PseudoCanonicalInput, Ty, TyCtxt};
use rustc_middle::ty::{PseudoCanonicalInput, ScalarInt, Ty, TyCtxt};
use rustc_middle::{bug, ty};
use rustc_span::DUMMY_SP;

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

let layout_cx = LayoutCx::new(tcx, input.typing_env);
if kind == ValidityRequirement::Uninit || tcx.sess.opts.unstable_opts.strict_init_checks {
check_validity_requirement_strict(layout, &layout_cx, kind)
Ok(check_validity_requirement_strict(layout, &layout_cx, kind))
} else {
check_validity_requirement_lax(layout, &layout_cx, kind)
}
Expand All @@ -46,10 +47,10 @@ fn check_validity_requirement_strict<'tcx>(
ty: TyAndLayout<'tcx>,
cx: &LayoutCx<'tcx>,
kind: ValidityRequirement,
) -> Result<bool, &'tcx LayoutError<'tcx>> {
) -> bool {
let machine = CompileTimeMachine::new(CanAccessMutGlobal::No, CheckAlignment::Error);

let mut cx = InterpCx::new(cx.tcx(), rustc_span::DUMMY_SP, cx.typing_env, machine);
let mut cx = InterpCx::new(cx.tcx(), DUMMY_SP, cx.typing_env, machine);

let allocated = cx
.allocate(ty, MemoryKind::Machine(crate::const_eval::MemoryKind::Heap))
Expand All @@ -69,14 +70,13 @@ fn check_validity_requirement_strict<'tcx>(
// due to this.
// The value we are validating is temporary and discarded at the end of this function, so
// there is no point in reseting provenance and padding.
Ok(cx
.validate_operand(
&allocated.into(),
/*recursive*/ false,
/*reset_provenance_and_padding*/ false,
)
.discard_err()
.is_some())
cx.validate_operand(
&allocated.into(),
/*recursive*/ false,
/*reset_provenance_and_padding*/ false,
)
.discard_err()
.is_some()
}

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

Ok(true)
}

pub(crate) fn validate_scalar_in_layout<'tcx>(
tcx: TyCtxt<'tcx>,
scalar: ScalarInt,
ty: Ty<'tcx>,
) -> bool {
let machine = CompileTimeMachine::new(CanAccessMutGlobal::No, CheckAlignment::Error);

let typing_env = ty::TypingEnv::fully_monomorphized();
let mut cx = InterpCx::new(tcx, DUMMY_SP, typing_env, machine);

let Ok(layout) = cx.layout_of(ty) else {
bug!("could not compute layout of {scalar:?}:{ty:?}")
};
let allocated = cx
.allocate(layout, MemoryKind::Machine(crate::const_eval::MemoryKind::Heap))
.expect("OOM: failed to allocate for uninit check");

cx.write_scalar(scalar, &allocated).unwrap();

cx.validate_operand(
&allocated.into(),
/*recursive*/ false,
/*reset_provenance_and_padding*/ false,
)
.discard_err()
.is_some()
}
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ mod type_name;

pub use self::alignment::{is_disaligned, is_within_packed};
pub use self::check_validity_requirement::check_validity_requirement;
pub(crate) use self::check_validity_requirement::validate_scalar_in_layout;
pub use self::compare_types::{relate_types, sub_types};
pub use self::type_name::type_name;

Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,9 @@ pub trait Visitor<'v>: Sized {
fn visit_pat_expr(&mut self, expr: &'v PatExpr<'v>) -> Self::Result {
walk_pat_expr(self, expr)
}
fn visit_lit(&mut self, _hir_id: HirId, _lit: &'v Lit, _negated: bool) -> Self::Result {
Self::Result::output()
}
fn visit_anon_const(&mut self, c: &'v AnonConst) -> Self::Result {
walk_anon_const(self, c)
}
Expand Down Expand Up @@ -764,7 +767,7 @@ pub fn walk_pat_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v PatField<'
pub fn walk_pat_expr<'v, V: Visitor<'v>>(visitor: &mut V, expr: &'v PatExpr<'v>) -> V::Result {
try_visit!(visitor.visit_id(expr.hir_id));
match &expr.kind {
PatExprKind::Lit { .. } => V::Result::output(),
PatExprKind::Lit { lit, negated } => visitor.visit_lit(expr.hir_id, lit, *negated),
PatExprKind::ConstBlock(c) => visitor.visit_inline_const(c),
PatExprKind::Path(qpath) => visitor.visit_qpath(qpath, expr.hir_id, expr.span),
}
Expand Down Expand Up @@ -912,7 +915,8 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
try_visit!(visitor.visit_expr(expr));
visit_opt!(visitor, visit_ty_unambig, ty);
}
ExprKind::Lit(_) | ExprKind::Err(_) => {}
ExprKind::Lit(lit) => try_visit!(visitor.visit_lit(expression.hir_id, lit, false)),
ExprKind::Err(_) => {}
}
V::Result::output()
}
Expand Down
29 changes: 4 additions & 25 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use rustc_middle::span_bug;
use rustc_middle::ty::error::TypeErrorToStringExt;
use rustc_middle::ty::fold::{BottomUpFolder, fold_regions};
use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
use rustc_middle::ty::util::{Discr, InspectCoroutineFields, IntTypeExt};
use rustc_middle::ty::util::{Discr, IntTypeExt};
use rustc_middle::ty::{
AdtDef, GenericArgKind, RegionKind, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
};
Expand Down Expand Up @@ -257,30 +257,9 @@ pub(super) fn check_opaque_for_cycles<'tcx>(

// First, try to look at any opaque expansion cycles, considering coroutine fields
// (even though these aren't necessarily true errors).
if tcx
.try_expand_impl_trait_type(def_id.to_def_id(), args, InspectCoroutineFields::Yes)
.is_err()
{
// Look for true opaque expansion cycles, but ignore coroutines.
// This will give us any true errors. Coroutines are only problematic
// if they cause layout computation errors.
if tcx
.try_expand_impl_trait_type(def_id.to_def_id(), args, InspectCoroutineFields::No)
.is_err()
{
let reported = opaque_type_cycle_error(tcx, def_id);
return Err(reported);
}

// And also look for cycle errors in the layout of coroutines.
if let Err(&LayoutError::Cycle(guar)) =
tcx.layout_of(
ty::TypingEnv::post_analysis(tcx, def_id.to_def_id())
.as_query_input(Ty::new_opaque(tcx, def_id.to_def_id(), args)),
)
{
return Err(guar);
}
if tcx.try_expand_impl_trait_type(def_id.to_def_id(), args).is_err() {
let reported = opaque_type_cycle_error(tcx, def_id);
return Err(reported);
}

Ok(())
Expand Down
71 changes: 44 additions & 27 deletions compiler/rustc_hir_typeck/src/op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
lang_item_for_op(self.tcx, Op::Binary(op, is_assign), op.span);
let missing_trait = trait_def_id
.map(|def_id| with_no_trimmed_paths!(self.tcx.def_path_str(def_id)));
let mut path = None;
let lhs_ty_str = self.tcx.short_string(lhs_ty, &mut path);
let rhs_ty_str = self.tcx.short_string(rhs_ty, &mut path);
let (mut err, output_def_id) = match is_assign {
IsAssign::Yes => {
let mut err = struct_span_code_err!(
Expand All @@ -314,53 +317,54 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
E0368,
"binary assignment operation `{}=` cannot be applied to type `{}`",
op.node.as_str(),
lhs_ty,
lhs_ty_str,
);
err.span_label(
lhs_expr.span,
format!("cannot use `{}=` on type `{}`", op.node.as_str(), lhs_ty),
format!("cannot use `{}=` on type `{}`", op.node.as_str(), lhs_ty_str),
);
self.note_unmet_impls_on_type(&mut err, errors, false);
(err, None)
}
IsAssign::No => {
let message = match op.node {
hir::BinOpKind::Add => {
format!("cannot add `{rhs_ty}` to `{lhs_ty}`")
format!("cannot add `{rhs_ty_str}` to `{lhs_ty_str}`")
}
hir::BinOpKind::Sub => {
format!("cannot subtract `{rhs_ty}` from `{lhs_ty}`")
format!("cannot subtract `{rhs_ty_str}` from `{lhs_ty_str}`")
}
hir::BinOpKind::Mul => {
format!("cannot multiply `{lhs_ty}` by `{rhs_ty}`")
format!("cannot multiply `{lhs_ty_str}` by `{rhs_ty_str}`")
}
hir::BinOpKind::Div => {
format!("cannot divide `{lhs_ty}` by `{rhs_ty}`")
format!("cannot divide `{lhs_ty_str}` by `{rhs_ty_str}`")
}
hir::BinOpKind::Rem => {
format!(
"cannot calculate the remainder of `{lhs_ty}` divided by `{rhs_ty}`"
"cannot calculate the remainder of `{lhs_ty_str}` divided by \
`{rhs_ty_str}`"
)
}
hir::BinOpKind::BitAnd => {
format!("no implementation for `{lhs_ty} & {rhs_ty}`")
format!("no implementation for `{lhs_ty_str} & {rhs_ty_str}`")
}
hir::BinOpKind::BitXor => {
format!("no implementation for `{lhs_ty} ^ {rhs_ty}`")
format!("no implementation for `{lhs_ty_str} ^ {rhs_ty_str}`")
}
hir::BinOpKind::BitOr => {
format!("no implementation for `{lhs_ty} | {rhs_ty}`")
format!("no implementation for `{lhs_ty_str} | {rhs_ty_str}`")
}
hir::BinOpKind::Shl => {
format!("no implementation for `{lhs_ty} << {rhs_ty}`")
format!("no implementation for `{lhs_ty_str} << {rhs_ty_str}`")
}
hir::BinOpKind::Shr => {
format!("no implementation for `{lhs_ty} >> {rhs_ty}`")
format!("no implementation for `{lhs_ty_str} >> {rhs_ty_str}`")
}
_ => format!(
"binary operation `{}` cannot be applied to type `{}`",
op.node.as_str(),
lhs_ty
lhs_ty_str,
),
};
let output_def_id = trait_def_id.and_then(|def_id| {
Expand All @@ -375,14 +379,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut err =
struct_span_code_err!(self.dcx(), op.span, E0369, "{message}");
if !lhs_expr.span.eq(&rhs_expr.span) {
err.span_label(lhs_expr.span, lhs_ty.to_string());
err.span_label(rhs_expr.span, rhs_ty.to_string());
err.span_label(lhs_expr.span, lhs_ty_str.clone());
err.span_label(rhs_expr.span, rhs_ty_str);
}
let suggest_derive = self.can_eq(self.param_env, lhs_ty, rhs_ty);
self.note_unmet_impls_on_type(&mut err, errors, suggest_derive);
(err, output_def_id)
}
};
*err.long_ty_path() = path;

// Try to suggest a semicolon if it's `A \n *B` where `B` is a place expr
let maybe_missing_semi = self.check_for_missing_semi(expr, &mut err);
Expand Down Expand Up @@ -417,7 +422,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
IsAssign::Yes => "=",
IsAssign::No => "",
},
lhs_deref_ty,
self.tcx.short_string(lhs_deref_ty, err.long_ty_path()),
);
err.span_suggestion_verbose(
lhs_expr.span.shrink_to_lo(),
Expand All @@ -443,8 +448,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
)
.is_ok()
{
let op_str = op.node.as_str();
err.note(format!("an implementation for `{lhs_adjusted_ty} {op_str} {rhs_adjusted_ty}` exists"));
let lhs = self.tcx.short_string(lhs_adjusted_ty, err.long_ty_path());
let rhs = self.tcx.short_string(rhs_adjusted_ty, err.long_ty_path());
let op = op.node.as_str();
err.note(format!("an implementation for `{lhs} {op} {rhs}` exists"));

if let Some(lhs_new_mutbl) = lhs_new_mutbl
&& let Some(rhs_new_mutbl) = rhs_new_mutbl
Expand Down Expand Up @@ -628,7 +635,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// When we know that a missing bound is responsible, we don't show
// this note as it is redundant.
err.note(format!(
"the trait `{missing_trait}` is not implemented for `{lhs_ty}`"
"the trait `{missing_trait}` is not implemented for `{lhs_ty_str}`"
));
}
}
Expand All @@ -654,24 +661,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir::BinOpKind::Sub => {
if lhs_ty.is_unsafe_ptr() && rhs_ty.is_integral() {
err.multipart_suggestion(
"consider using `wrapping_sub` or `sub` for pointer - {integer}",
"consider using `wrapping_sub` or `sub` for \
pointer - {integer}",
vec![
(lhs_expr.span.between(rhs_expr.span), ".wrapping_sub(".to_owned()),
(
lhs_expr.span.between(rhs_expr.span),
".wrapping_sub(".to_owned(),
),
(rhs_expr.span.shrink_to_hi(), ")".to_owned()),
],
Applicability::MaybeIncorrect
Applicability::MaybeIncorrect,
);
}

if lhs_ty.is_unsafe_ptr() && rhs_ty.is_unsafe_ptr() {
err.multipart_suggestion(
"consider using `offset_from` for pointer - pointer if the pointers point to the same allocation",
"consider using `offset_from` for pointer - pointer if the \
pointers point to the same allocation",
vec![
(lhs_expr.span.shrink_to_lo(), "unsafe { ".to_owned()),
(lhs_expr.span.between(rhs_expr.span), ".offset_from(".to_owned()),
(
lhs_expr.span.between(rhs_expr.span),
".offset_from(".to_owned(),
),
(rhs_expr.span.shrink_to_hi(), ") }".to_owned()),
],
Applicability::MaybeIncorrect
Applicability::MaybeIncorrect,
);
}
}
Expand Down Expand Up @@ -793,14 +808,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Err(errors) => {
let actual = self.resolve_vars_if_possible(operand_ty);
let guar = actual.error_reported().err().unwrap_or_else(|| {
let mut file = None;
let ty_str = self.tcx.short_string(actual, &mut file);
let mut err = struct_span_code_err!(
self.dcx(),
ex.span,
E0600,
"cannot apply unary operator `{}` to type `{}`",
"cannot apply unary operator `{}` to type `{ty_str}`",
op.as_str(),
actual
);
*err.long_ty_path() = file;
err.span_label(
ex.span,
format!("cannot apply unary operator `{}`", op.as_str()),
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,11 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
tcx.ensure_ok().check_coroutine_obligations(
tcx.typeck_root_def_id(def_id.to_def_id()).expect_local(),
);
// Eagerly check the unsubstituted layout for cycles.
tcx.ensure_ok().layout_of(
ty::TypingEnv::post_analysis(tcx, def_id.to_def_id())
.as_query_input(tcx.type_of(def_id).instantiate_identity()),
);
}
});
});
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_lint/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,10 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
hir_visit::walk_pat(self, p);
}

fn visit_lit(&mut self, hir_id: HirId, lit: &'tcx hir::Lit, negated: bool) {
lint_callback!(self, check_lit, hir_id, lit, negated);
}

fn visit_expr_field(&mut self, field: &'tcx hir::ExprField<'tcx>) {
self.with_lint_attrs(field.hir_id, |cx| hir_visit::walk_expr_field(cx, field))
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_lint/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ macro_rules! late_lint_methods {
fn check_stmt(a: &'tcx rustc_hir::Stmt<'tcx>);
fn check_arm(a: &'tcx rustc_hir::Arm<'tcx>);
fn check_pat(a: &'tcx rustc_hir::Pat<'tcx>);
fn check_lit(hir_id: rustc_hir::HirId, a: &'tcx rustc_hir::Lit, negated: bool);
fn check_expr(a: &'tcx rustc_hir::Expr<'tcx>);
fn check_expr_post(a: &'tcx rustc_hir::Expr<'tcx>);
fn check_ty(a: &'tcx rustc_hir::Ty<'tcx, rustc_hir::AmbigArg>);
Expand Down
Loading

0 comments on commit 942db67

Please sign in to comment.