Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 8 pull requests #122190

Merged
merged 20 commits into from
Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
e760c44
Use `ControlFlow` in AST visitors.
Jarcho Feb 24, 2024
822b10d
Use `ControlFlow` in HIR visitors
Jarcho Feb 24, 2024
63091b1
Make `arg_expand_all` not short-circuit on first error
beetrees May 15, 2023
fb87e60
Refactor argument UTF-8 checking into `rustc_driver::args::raw_args()`
beetrees May 15, 2023
d626d13
Use `rustc_driver::args::raw_args()` in Clippy
beetrees May 15, 2023
2d7d0bd
Use `rustc_driver::args::raw_args()` in Miri
beetrees May 15, 2023
bed9d1f
Add known-bug tests for `derive(PartialEq)` mismatches with `#[repr(p…
oli-obk Mar 7, 2024
025ad40
Don't ICE in CTFE if raw/fn-ptr types differ
compiler-errors Mar 8, 2024
ece20f0
Bless tidy issues order
chenyukang Mar 8, 2024
c2f13db
rustc: Fix typo
heiher Mar 8, 2024
2e5f86c
interpret: update comment about read_discriminant on uninhabited vari…
RalfJung Mar 8, 2024
c81521a
Fix crash in late internal checking
chenyukang Mar 8, 2024
075f1c3
Rollup merge of #121025 - oli-obk:taint_after_errors, r=petrochenkov
matthiaskrgr Mar 8, 2024
a8e3543
Rollup merge of #121194 - beetrees:rustc-raw-args, r=petrochenkov
matthiaskrgr Mar 8, 2024
3e634f8
Rollup merge of #121563 - Jarcho:use_cf, r=petrochenkov
matthiaskrgr Mar 8, 2024
3d71bad
Rollup merge of #122173 - compiler-errors:ptr-equality-in-ctfe, r=lcnr
matthiaskrgr Mar 8, 2024
af3d06c
Rollup merge of #122175 - chenyukang:yukang-fix-tidy-issues, r=workin…
matthiaskrgr Mar 8, 2024
9fd60c5
Rollup merge of #122179 - heiher:fix-typo, r=lcnr
matthiaskrgr Mar 8, 2024
a08a5d4
Rollup merge of #122181 - chenyukang:yukang-fix-late-lint-crash, r=ol…
matthiaskrgr Mar 8, 2024
8abeac2
Rollup merge of #122183 - RalfJung:read-discriminant-uninhabited-vari…
matthiaskrgr Mar 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions compiler/rustc_ast_lowering/src/format.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::LoweringContext;
use core::ops::ControlFlow;
use rustc_ast as ast;
use rustc_ast::visit::Visitor;
use rustc_ast::*;
Expand Down Expand Up @@ -594,30 +595,32 @@ fn expand_format_args<'hir>(
}

fn may_contain_yield_point(e: &ast::Expr) -> bool {
struct MayContainYieldPoint(bool);
struct MayContainYieldPoint;

impl Visitor<'_> for MayContainYieldPoint {
fn visit_expr(&mut self, e: &ast::Expr) {
type Result = ControlFlow<()>;

fn visit_expr(&mut self, e: &ast::Expr) -> ControlFlow<()> {
if let ast::ExprKind::Await(_, _) | ast::ExprKind::Yield(_) = e.kind {
self.0 = true;
ControlFlow::Break(())
} else {
visit::walk_expr(self, e);
ControlFlow::Continue(())
}
}

fn visit_mac_call(&mut self, _: &ast::MacCall) {
fn visit_mac_call(&mut self, _: &ast::MacCall) -> ControlFlow<()> {
// Macros should be expanded at this point.
unreachable!("unexpanded macro in ast lowering");
}

fn visit_item(&mut self, _: &ast::Item) {
fn visit_item(&mut self, _: &ast::Item) -> ControlFlow<()> {
// Do not recurse into nested items.
ControlFlow::Continue(())
}
}

let mut visitor = MayContainYieldPoint(false);
visitor.visit_expr(e);
visitor.0
MayContainYieldPoint.visit_expr(e).is_break()
}

fn for_all_argument_indexes(template: &mut [FormatArgsPiece], mut f: impl FnMut(&mut usize)) {
Expand Down
76 changes: 29 additions & 47 deletions compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]

use core::ops::ControlFlow;
use hir::ExprKind;
use rustc_errors::{Applicability, Diag};
use rustc_hir as hir;
Expand Down Expand Up @@ -727,30 +728,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
_ => local_decl.source_info.span,
};

struct BindingFinder {
span: Span,
hir_id: Option<hir::HirId>,
}

impl<'tcx> Visitor<'tcx> for BindingFinder {
fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) {
if let hir::StmtKind::Local(local) = s.kind {
if local.pat.span == self.span {
self.hir_id = Some(local.hir_id);
}
}
hir::intravisit::walk_stmt(self, s);
}
}

let def_id = self.body.source.def_id();
let hir_id = if let Some(local_def_id) = def_id.as_local()
&& let Some(body_id) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id)
{
let body = self.infcx.tcx.hir().body(body_id);
let mut v = BindingFinder { span: pat_span, hir_id: None };
v.visit_body(body);
v.hir_id
BindingFinder { span: pat_span }.visit_body(body).break_value()
} else {
None
};
Expand Down Expand Up @@ -859,17 +842,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
};

let hir_map = self.infcx.tcx.hir();
struct Finder<'tcx> {
struct Finder {
span: Span,
expr: Option<&'tcx Expr<'tcx>>,
}

impl<'tcx> Visitor<'tcx> for Finder<'tcx> {
fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
if e.span == self.span && self.expr.is_none() {
self.expr = Some(e);
impl<'tcx> Visitor<'tcx> for Finder {
type Result = ControlFlow<&'tcx Expr<'tcx>>;
fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) -> Self::Result {
if e.span == self.span {
ControlFlow::Break(e)
} else {
hir::intravisit::walk_expr(self, e)
}
hir::intravisit::walk_expr(self, e);
}
}
if let Some(body_id) = hir_map.maybe_body_owned_by(self.mir_def_id())
Expand All @@ -878,9 +862,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
// `span` corresponds to the expression being iterated, find the `for`-loop desugared
// expression with that span in order to identify potential fixes when encountering a
// read-only iterator that should be mutable.
let mut v = Finder { span, expr: None };
v.visit_block(block);
if let Some(expr) = v.expr
if let ControlFlow::Break(expr) = (Finder { span }).visit_block(block)
&& let Call(_, [expr]) = expr.kind
{
match expr.kind {
Expand Down Expand Up @@ -1179,29 +1161,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
);
}
Some((false, err_label_span, message)) => {
struct BindingFinder {
span: Span,
hir_id: Option<hir::HirId>,
}

impl<'tcx> Visitor<'tcx> for BindingFinder {
fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) {
if let hir::StmtKind::Local(local) = s.kind {
if local.pat.span == self.span {
self.hir_id = Some(local.hir_id);
}
}
hir::intravisit::walk_stmt(self, s);
}
}
let def_id = self.body.source.def_id();
let hir_id = if let Some(local_def_id) = def_id.as_local()
&& let Some(body_id) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id)
{
let body = self.infcx.tcx.hir().body(body_id);
let mut v = BindingFinder { span: err_label_span, hir_id: None };
v.visit_body(body);
v.hir_id
BindingFinder { span: err_label_span }.visit_body(body).break_value()
} else {
None
};
Expand Down Expand Up @@ -1333,6 +1298,23 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
}
}

struct BindingFinder {
span: Span,
}

impl<'tcx> Visitor<'tcx> for BindingFinder {
type Result = ControlFlow<hir::HirId>;
fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) -> Self::Result {
if let hir::StmtKind::Local(local) = s.kind
&& local.pat.span == self.span
{
ControlFlow::Break(local.hir_id)
} else {
hir::intravisit::walk_stmt(self, s)
}
}
}

pub fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option<Symbol>) -> bool {
debug!("local_info: {:?}, ty.kind(): {:?}", local_decl.local_info, local_decl.ty.kind());

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#![feature(assert_matches)]
#![feature(associated_type_bounds)]
#![feature(box_patterns)]
#![feature(control_flow_enum)]
#![feature(let_chains)]
#![feature(min_specialization)]
#![feature(never_type)]
Expand Down
66 changes: 33 additions & 33 deletions compiler/rustc_builtin_macros/src/cfg_eval.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::util::{check_builtin_macro_attribute, warn_on_duplicate_attribute};

use core::ops::ControlFlow;
use rustc_ast as ast;
use rustc_ast::mut_visit::MutVisitor;
use rustc_ast::ptr::P;
Expand Down Expand Up @@ -87,41 +88,40 @@ fn flat_map_annotatable(
}
}

struct CfgFinder {
has_cfg_or_cfg_attr: bool,
}

impl CfgFinder {
fn has_cfg_or_cfg_attr(annotatable: &Annotatable) -> bool {
let mut finder = CfgFinder { has_cfg_or_cfg_attr: false };
match annotatable {
Annotatable::Item(item) => finder.visit_item(item),
Annotatable::TraitItem(item) => finder.visit_assoc_item(item, visit::AssocCtxt::Trait),
Annotatable::ImplItem(item) => finder.visit_assoc_item(item, visit::AssocCtxt::Impl),
Annotatable::ForeignItem(item) => finder.visit_foreign_item(item),
Annotatable::Stmt(stmt) => finder.visit_stmt(stmt),
Annotatable::Expr(expr) => finder.visit_expr(expr),
Annotatable::Arm(arm) => finder.visit_arm(arm),
Annotatable::ExprField(field) => finder.visit_expr_field(field),
Annotatable::PatField(field) => finder.visit_pat_field(field),
Annotatable::GenericParam(param) => finder.visit_generic_param(param),
Annotatable::Param(param) => finder.visit_param(param),
Annotatable::FieldDef(field) => finder.visit_field_def(field),
Annotatable::Variant(variant) => finder.visit_variant(variant),
Annotatable::Crate(krate) => finder.visit_crate(krate),
};
finder.has_cfg_or_cfg_attr
}
}
fn has_cfg_or_cfg_attr(annotatable: &Annotatable) -> bool {
struct CfgFinder;

impl<'ast> visit::Visitor<'ast> for CfgFinder {
fn visit_attribute(&mut self, attr: &'ast Attribute) {
// We want short-circuiting behavior, so don't use the '|=' operator.
self.has_cfg_or_cfg_attr = self.has_cfg_or_cfg_attr
|| attr
impl<'ast> visit::Visitor<'ast> for CfgFinder {
type Result = ControlFlow<()>;
fn visit_attribute(&mut self, attr: &'ast Attribute) -> ControlFlow<()> {
if attr
.ident()
.is_some_and(|ident| ident.name == sym::cfg || ident.name == sym::cfg_attr);
.is_some_and(|ident| ident.name == sym::cfg || ident.name == sym::cfg_attr)
{
ControlFlow::Break(())
} else {
ControlFlow::Continue(())
}
}
}

let res = match annotatable {
Annotatable::Item(item) => CfgFinder.visit_item(item),
Annotatable::TraitItem(item) => CfgFinder.visit_assoc_item(item, visit::AssocCtxt::Trait),
Annotatable::ImplItem(item) => CfgFinder.visit_assoc_item(item, visit::AssocCtxt::Impl),
Annotatable::ForeignItem(item) => CfgFinder.visit_foreign_item(item),
Annotatable::Stmt(stmt) => CfgFinder.visit_stmt(stmt),
Annotatable::Expr(expr) => CfgFinder.visit_expr(expr),
Annotatable::Arm(arm) => CfgFinder.visit_arm(arm),
Annotatable::ExprField(field) => CfgFinder.visit_expr_field(field),
Annotatable::PatField(field) => CfgFinder.visit_pat_field(field),
Annotatable::GenericParam(param) => CfgFinder.visit_generic_param(param),
Annotatable::Param(param) => CfgFinder.visit_param(param),
Annotatable::FieldDef(field) => CfgFinder.visit_field_def(field),
Annotatable::Variant(variant) => CfgFinder.visit_variant(variant),
Annotatable::Crate(krate) => CfgFinder.visit_crate(krate),
};
res.is_break()
}

impl CfgEval<'_, '_> {
Expand All @@ -132,7 +132,7 @@ impl CfgEval<'_, '_> {
fn configure_annotatable(&mut self, mut annotatable: Annotatable) -> Option<Annotatable> {
// Tokenizing and re-parsing the `Annotatable` can have a significant
// performance impact, so try to avoid it if possible
if !CfgFinder::has_cfg_or_cfg_attr(&annotatable) {
if !has_cfg_or_cfg_attr(&annotatable) {
return Some(annotatable);
}

Expand Down
18 changes: 9 additions & 9 deletions compiler/rustc_builtin_macros/src/deriving/default.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::deriving::generic::ty::*;
use crate::deriving::generic::*;
use crate::errors;
use core::ops::ControlFlow;
use rustc_ast as ast;
use rustc_ast::visit::walk_list;
use rustc_ast::{attr, EnumDef, VariantData};
Expand Down Expand Up @@ -231,20 +232,19 @@ impl<'a, 'b> rustc_ast::visit::Visitor<'a> for DetectNonVariantDefaultAttr<'a, '
}

fn has_a_default_variant(item: &Annotatable) -> bool {
struct HasDefaultAttrOnVariant {
found: bool,
}
struct HasDefaultAttrOnVariant;

impl<'ast> rustc_ast::visit::Visitor<'ast> for HasDefaultAttrOnVariant {
fn visit_variant(&mut self, v: &'ast rustc_ast::Variant) {
type Result = ControlFlow<()>;
fn visit_variant(&mut self, v: &'ast rustc_ast::Variant) -> ControlFlow<()> {
if v.attrs.iter().any(|attr| attr.has_name(kw::Default)) {
self.found = true;
ControlFlow::Break(())
} else {
// no need to subrecurse.
ControlFlow::Continue(())
}
// no need to subrecurse.
}
}

let mut visitor = HasDefaultAttrOnVariant { found: false };
item.visit_with(&mut visitor);
visitor.found
item.visit_with(&mut HasDefaultAttrOnVariant).is_break()
}
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/back/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
"ilp32s" | "lp64s" => e_flags |= elf::EF_LARCH_ABI_SOFT_FLOAT,
"ilp32f" | "lp64f" => e_flags |= elf::EF_LARCH_ABI_SINGLE_FLOAT,
"ilp32d" | "lp64d" => e_flags |= elf::EF_LARCH_ABI_DOUBLE_FLOAT,
_ => bug!("unknown RISC-V ABI name"),
_ => bug!("unknown LoongArch ABI name"),
}

e_flags
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_const_eval/src/interpret/discriminant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use super::{ImmTy, InterpCx, InterpResult, Machine, Readable, Scalar, Writeable}

impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// Writes the discriminant of the given variant.
///
/// If the variant is uninhabited, this is UB.
#[instrument(skip(self), level = "trace")]
pub fn write_discriminant(
&mut self,
Expand Down Expand Up @@ -102,6 +104,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {

/// Read discriminant, return the runtime value as well as the variant index.
/// Can also legally be called on non-enums (e.g. through the discriminant_value intrinsic)!
///
/// Will never return an uninhabited variant.
#[instrument(skip(self), level = "trace")]
pub fn read_discriminant(
&self,
Expand Down Expand Up @@ -244,7 +248,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
variant
}
};
// For consistency with `write_discriminant`, and to make sure that `project_downcast` cannot fail due to strange layouts, we declare immediate UB for uninhabited variants.
// Reading the discriminant of an uninhabited variant is UB. This is the basis for the
// `uninhabited_enum_branching` MIR pass. It also ensures consistency with
// `write_discriminant`.
if op.layout().for_variant(self, index).abi.is_uninhabited() {
throw_ub!(UninhabitedEnumVariantRead(index))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
if is_int_bool_or_char(lhs_ty) && is_int_bool_or_char(rhs_ty) {
// Int, bool, and char operations are fine.
} else if lhs_ty.is_fn_ptr() || lhs_ty.is_unsafe_ptr() {
assert_eq!(lhs_ty, rhs_ty);
assert!(matches!(
op,
BinOp::Eq
Expand Down
Loading
Loading