From e760c440633b06236967d76e18acd191001887ce Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Sat, 24 Feb 2024 02:52:59 -0500 Subject: [PATCH 01/12] Use `ControlFlow` in AST visitors. --- compiler/rustc_ast_lowering/src/format.rs | 19 +++--- compiler/rustc_builtin_macros/src/cfg_eval.rs | 66 +++++++++---------- .../src/deriving/default.rs | 18 ++--- compiler/rustc_lint/src/unused.rs | 18 +++-- compiler/rustc_parse/src/parser/expr.rs | 16 +++-- 5 files changed, 70 insertions(+), 67 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index 00cb09d7a541a..3f84e6b100d11 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -1,4 +1,5 @@ use super::LoweringContext; +use core::ops::ControlFlow; use rustc_ast as ast; use rustc_ast::visit::Visitor; use rustc_ast::*; @@ -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)) { diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs index 1de95ca81f729..93f7d09546b70 100644 --- a/compiler/rustc_builtin_macros/src/cfg_eval.rs +++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs @@ -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; @@ -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<'_, '_> { @@ -132,7 +132,7 @@ impl CfgEval<'_, '_> { fn configure_annotatable(&mut self, mut annotatable: Annotatable) -> Option { // 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); } diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index fae0e1d380c0c..292a916e2a78b 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -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}; @@ -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() } diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 3481c66da702e..f84d1c6c2d0aa 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -20,6 +20,7 @@ use rustc_span::symbol::Symbol; use rustc_span::symbol::{kw, sym}; use rustc_span::{BytePos, Span}; use std::iter; +use std::ops::ControlFlow; declare_lint! { /// The `unused_must_use` lint detects unused result of a type flagged as @@ -753,21 +754,18 @@ trait UnusedDelimLint { // fn f(){(print!(รก // ``` use rustc_ast::visit::{walk_expr, Visitor}; - struct ErrExprVisitor { - has_error: bool, - } + struct ErrExprVisitor; impl<'ast> Visitor<'ast> for ErrExprVisitor { - fn visit_expr(&mut self, expr: &'ast ast::Expr) { + type Result = ControlFlow<()>; + fn visit_expr(&mut self, expr: &'ast ast::Expr) -> ControlFlow<()> { if let ExprKind::Err(_) = expr.kind { - self.has_error = true; - return; + ControlFlow::Break(()) + } else { + walk_expr(self, expr) } - walk_expr(self, expr) } } - let mut visitor = ErrExprVisitor { has_error: false }; - visitor.visit_expr(value); - if visitor.has_error { + if ErrExprVisitor.visit_expr(value).is_break() { return; } let spans = match value.kind { diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 6cc358db9fcae..7a34bc7890c98 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -13,13 +13,14 @@ use ast::mut_visit::{noop_visit_expr, MutVisitor}; use ast::token::IdentIsRaw; use ast::{CoroutineKind, ForLoopKind, GenBlockKind, Pat, Path, PathSegment}; use core::mem; +use core::ops::ControlFlow; use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter, Token, TokenKind}; use rustc_ast::tokenstream::Spacing; use rustc_ast::util::case::Case; use rustc_ast::util::classify; use rustc_ast::util::parser::{prec_let_scrutinee_needs_par, AssocOp, Fixity}; -use rustc_ast::visit::Visitor; +use rustc_ast::visit::{walk_expr, Visitor}; use rustc_ast::{self as ast, AttrStyle, AttrVec, CaptureBy, ExprField, UnOp, DUMMY_NODE_ID}; use rustc_ast::{AnonConst, BinOp, BinOpKind, FnDecl, FnRetTy, MacCall, Param, Ty, TyKind}; use rustc_ast::{Arm, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits}; @@ -1703,19 +1704,20 @@ impl<'a> Parser<'a> { let span = expr.span; let found_labeled_breaks = { - struct FindLabeledBreaksVisitor(bool); + struct FindLabeledBreaksVisitor; impl<'ast> Visitor<'ast> for FindLabeledBreaksVisitor { - fn visit_expr_post(&mut self, ex: &'ast Expr) { + type Result = ControlFlow<()>; + fn visit_expr(&mut self, ex: &'ast Expr) -> ControlFlow<()> { if let ExprKind::Break(Some(_label), _) = ex.kind { - self.0 = true; + ControlFlow::Break(()) + } else { + walk_expr(self, ex) } } } - let mut vis = FindLabeledBreaksVisitor(false); - vis.visit_expr(&expr); - vis.0 + FindLabeledBreaksVisitor.visit_expr(&expr).is_break() }; // Suggestion involves adding a labeled block. From 822b10d4288cc32e5914b1874b585e6f24ef0c28 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Sat, 24 Feb 2024 02:53:05 -0500 Subject: [PATCH 02/12] Use `ControlFlow` in HIR visitors --- .../src/diagnostics/mutability_errors.rs | 76 ++++++---------- compiler/rustc_borrowck/src/lib.rs | 1 + .../src/check/compare_impl_item.rs | 21 ++--- .../src/collect/resolve_bound_vars.rs | 22 ++--- .../rustc_hir_analysis/src/collect/type_of.rs | 16 ++-- .../rustc_hir_typeck/src/method/suggest.rs | 21 +++-- .../src/infer/error_reporting/mod.rs | 21 ++--- .../nice_region_error/find_anon_type.rs | 69 +++++++-------- .../src/infer/error_reporting/suggest.rs | 88 +++++++++---------- compiler/rustc_infer/src/lib.rs | 1 + .../error_reporting/type_err_ctxt_ext.rs | 27 +++--- tests/ui/issues/issue-20831-debruijn.stderr | 6 +- 12 files changed, 168 insertions(+), 201 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index c327e591f3cdd..ebc9f1d109ee7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -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; @@ -727,30 +728,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { _ => local_decl.source_info.span, }; - struct BindingFinder { - span: Span, - hir_id: Option, - } - - 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 }; @@ -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()) @@ -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 { @@ -1179,29 +1161,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ); } Some((false, err_label_span, message)) => { - struct BindingFinder { - span: Span, - hir_id: Option, - } - - 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 }; @@ -1333,6 +1298,23 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } +struct BindingFinder { + span: Span, +} + +impl<'tcx> Visitor<'tcx> for BindingFinder { + type Result = ControlFlow; + 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) -> bool { debug!("local_info: {:?}, ty.kind(): {:?}", local_decl.local_info, local_decl.ty.kind()); diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index ef582033c4ea1..840d07a897768 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -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)] diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 435e251b130ea..f708c66cfa444 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1,5 +1,6 @@ use super::potentially_plural_count; use crate::errors::{LifetimesOrBoundsMismatchOnTrait, MethodShouldReturnFuture}; +use core::ops::ControlFlow; use hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, ErrorGuaranteed}; @@ -1565,24 +1566,24 @@ fn compare_synthetic_generics<'tcx>( let (sig, _) = impl_m.expect_fn(); let input_tys = sig.decl.inputs; - struct Visitor(Option, hir::def_id::LocalDefId); + struct Visitor(hir::def_id::LocalDefId); impl<'v> intravisit::Visitor<'v> for Visitor { - fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) { - intravisit::walk_ty(self, ty); + type Result = ControlFlow; + fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) -> Self::Result { if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = ty.kind && let Res::Def(DefKind::TyParam, def_id) = path.res - && def_id == self.1.to_def_id() + && def_id == self.0.to_def_id() { - self.0 = Some(ty.span); + ControlFlow::Break(ty.span) + } else { + intravisit::walk_ty(self, ty) } } } - let mut visitor = Visitor(None, impl_def_id); - for ty in input_tys { - intravisit::Visitor::visit_ty(&mut visitor, ty); - } - let span = visitor.0?; + let span = input_tys.iter().find_map(|ty| { + intravisit::Visitor::visit_ty(&mut Visitor(impl_def_id), ty).break_value() + })?; let bounds = impl_m.generics.bounds_for_param(impl_def_id).next()?.bounds; let bounds = bounds.first()?.span().to(bounds.last()?.span()); diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index ad8ec1036efee..368cde782193e 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -6,6 +6,7 @@ //! the types in HIR to identify late-bound lifetimes and assign their Debruijn indices. This file //! is also responsible for assigning their semantics to implicit lifetimes in trait objects. +use core::ops::ControlFlow; use rustc_ast::visit::walk_list; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::{codes::*, struct_span_code_err}; @@ -417,23 +418,18 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { { if let &hir::ClosureBinder::For { span: for_sp, .. } = binder { fn span_of_infer(ty: &hir::Ty<'_>) -> Option { - struct V(Option); - + struct V; impl<'v> Visitor<'v> for V { - fn visit_ty(&mut self, t: &'v hir::Ty<'v>) { - match t.kind { - _ if self.0.is_some() => (), - hir::TyKind::Infer => { - self.0 = Some(t.span); - } - _ => intravisit::walk_ty(self, t), + type Result = ControlFlow; + fn visit_ty(&mut self, t: &'v hir::Ty<'v>) -> Self::Result { + if matches!(t.kind, hir::TyKind::Infer) { + ControlFlow::Break(t.span) + } else { + intravisit::walk_ty(self, t) } } } - - let mut v = V(None); - v.visit_ty(ty); - v.0 + V.visit_ty(ty).break_value() } let infer_in_rt_sp = match fn_decl.output { diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 417f0fceaa81f..2335b0005b726 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -1,3 +1,4 @@ +use core::ops::ControlFlow; use rustc_errors::{Applicability, StashKey}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -666,19 +667,16 @@ pub fn type_alias_is_lazy<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool { if tcx.features().lazy_type_alias { return true; } - struct HasTait { - has_type_alias_impl_trait: bool, - } + struct HasTait; impl<'tcx> Visitor<'tcx> for HasTait { - fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) { + type Result = ControlFlow<()>; + fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) -> Self::Result { if let hir::TyKind::OpaqueDef(..) = t.kind { - self.has_type_alias_impl_trait = true; + ControlFlow::Break(()) } else { - hir::intravisit::walk_ty(self, t); + hir::intravisit::walk_ty(self, t) } } } - let mut has_tait = HasTait { has_type_alias_impl_trait: false }; - has_tait.visit_ty(tcx.hir().expect_item(def_id).expect_ty_alias().0); - has_tait.has_type_alias_impl_trait + HasTait.visit_ty(tcx.hir().expect_item(def_id).expect_ty_alias().0).is_break() } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 893b3f9534de9..7f7629b1de976 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -6,6 +6,7 @@ use crate::errors::{self, CandidateTraitNote, NoAssociatedItem}; use crate::Expectation; use crate::FnCtxt; +use core::ops::ControlFlow; use rustc_ast::ast::Mutability; use rustc_attr::parse_confusables; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; @@ -2212,30 +2213,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let map = self.infcx.tcx.hir(); let body_id = self.tcx.hir().body_owned_by(self.body_id); let body = map.body(body_id); - struct LetVisitor<'a> { - result: Option<&'a hir::Expr<'a>>, + struct LetVisitor { ident_name: Symbol, } // FIXME: This really should be taking scoping, etc into account. - impl<'v> Visitor<'v> for LetVisitor<'v> { - fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) { - if let hir::StmtKind::Local(hir::Local { pat, init, .. }) = &ex.kind + impl<'v> Visitor<'v> for LetVisitor { + type Result = ControlFlow>>; + fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) -> Self::Result { + if let hir::StmtKind::Local(&hir::Local { pat, init, .. }) = ex.kind && let Binding(_, _, ident, ..) = pat.kind && ident.name == self.ident_name { - self.result = *init; + ControlFlow::Break(init) } else { - hir::intravisit::walk_stmt(self, ex); + hir::intravisit::walk_stmt(self, ex) } } } - let mut visitor = LetVisitor { result: None, ident_name: seg1.ident.name }; - visitor.visit_body(body); - if let Node::Expr(call_expr) = self.tcx.parent_hir_node(seg1.hir_id) - && let Some(expr) = visitor.result + && let ControlFlow::Break(Some(expr)) = + (LetVisitor { ident_name: seg1.ident.name }).visit_body(body) && let Some(self_ty) = self.node_ty_opt(expr.hir_id) { let probe = self.lookup_probe_for_diagnostic( diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 362ca3b4833ea..ea5c6b8c057ce 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -79,7 +79,7 @@ use rustc_middle::ty::{ use rustc_span::{sym, symbol::kw, BytePos, DesugaringKind, Pos, Span}; use rustc_target::spec::abi; use std::borrow::Cow; -use std::ops::Deref; +use std::ops::{ControlFlow, Deref}; use std::path::PathBuf; use std::{cmp, fmt, iter}; @@ -2129,15 +2129,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let tykind = match self.tcx.opt_hir_node_by_def_id(trace.cause.body_id) { Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })) => { let body = hir.body(*body_id); - struct LetVisitor<'v> { + struct LetVisitor { span: Span, - result: Option<&'v hir::Ty<'v>>, } - impl<'v> Visitor<'v> for LetVisitor<'v> { - fn visit_stmt(&mut self, s: &'v hir::Stmt<'v>) { - if self.result.is_some() { - return; - } + impl<'v> Visitor<'v> for LetVisitor { + type Result = ControlFlow<&'v hir::TyKind<'v>>; + fn visit_stmt(&mut self, s: &'v hir::Stmt<'v>) -> Self::Result { // Find a local statement where the initializer has // the same span as the error and the type is specified. if let hir::Stmt { @@ -2151,13 +2148,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } = s && init_span == &self.span { - self.result = Some(*array_ty); + ControlFlow::Break(&array_ty.peel_refs().kind) + } else { + ControlFlow::Continue(()) } } } - let mut visitor = LetVisitor { span, result: None }; - visitor.visit_body(body); - visitor.result.map(|r| &r.peel_refs().kind) + LetVisitor { span }.visit_body(body).break_value() } Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(ty, _, _), .. })) => { Some(&ty.peel_refs().kind) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs index 4f74365d06c47..265a315a55979 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs @@ -1,3 +1,4 @@ +use core::ops::ControlFlow; use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::hir::map::Map; @@ -43,14 +44,9 @@ fn find_component_for_bound_region<'tcx>( arg: &'tcx hir::Ty<'tcx>, br: &ty::BoundRegionKind, ) -> Option<&'tcx hir::Ty<'tcx>> { - let mut nested_visitor = FindNestedTypeVisitor { - tcx, - bound_region: *br, - found_type: None, - current_index: ty::INNERMOST, - }; - nested_visitor.visit_ty(arg); - nested_visitor.found_type + FindNestedTypeVisitor { tcx, bound_region: *br, current_index: ty::INNERMOST } + .visit_ty(arg) + .break_value() } // The FindNestedTypeVisitor captures the corresponding `hir::Ty` of the @@ -65,26 +61,24 @@ struct FindNestedTypeVisitor<'tcx> { // The bound_region corresponding to the Refree(freeregion) // associated with the anonymous region we are looking for. bound_region: ty::BoundRegionKind, - // The type where the anonymous lifetime appears - // for e.g., Vec<`&u8`> and <`&u8`> - found_type: Option<&'tcx hir::Ty<'tcx>>, current_index: ty::DebruijnIndex, } impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { + type Result = ControlFlow<&'tcx hir::Ty<'tcx>>; type NestedFilter = nested_filter::OnlyBodies; fn nested_visit_map(&mut self) -> Self::Map { self.tcx.hir() } - fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) { + fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) -> Self::Result { match arg.kind { hir::TyKind::BareFn(_) => { self.current_index.shift_in(1); intravisit::walk_ty(self, arg); self.current_index.shift_out(1); - return; + return ControlFlow::Continue(()); } hir::TyKind::TraitObject(bounds, ..) => { @@ -105,8 +99,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { (Some(rbv::ResolvedArg::EarlyBound(id)), ty::BrNamed(def_id, _)) => { debug!("EarlyBound id={:?} def_id={:?}", id, def_id); if id == def_id { - self.found_type = Some(arg); - return; // we can stop visiting now + return ControlFlow::Break(arg); } } @@ -123,8 +116,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { ); debug!("LateBound id={:?} def_id={:?}", id, def_id); if debruijn_index == self.current_index && id == def_id { - self.found_type = Some(arg); - return; // we can stop visiting now + return ControlFlow::Break(arg); } } @@ -145,23 +137,30 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { } // Checks if it is of type `hir::TyKind::Path` which corresponds to a struct. hir::TyKind::Path(_) => { - let subvisitor = &mut TyPathVisitor { - tcx: self.tcx, - found_it: false, - bound_region: self.bound_region, - current_index: self.current_index, + // Prefer using the lifetime in type arguments rather than lifetime arguments. + intravisit::walk_ty(self, arg)?; + + // Call `walk_ty` as `visit_ty` is empty. + return if intravisit::walk_ty( + &mut TyPathVisitor { + tcx: self.tcx, + bound_region: self.bound_region, + current_index: self.current_index, + }, + arg, + ) + .is_break() + { + ControlFlow::Break(arg) + } else { + ControlFlow::Continue(()) }; - intravisit::walk_ty(subvisitor, arg); // call walk_ty; as visit_ty is empty, - // this will visit only outermost type - if subvisitor.found_it { - self.found_type = Some(arg); - } } _ => {} } // walk the embedded contents: e.g., if we are visiting `Vec<&Foo>`, // go on to visit `&Foo` - intravisit::walk_ty(self, arg); + intravisit::walk_ty(self, arg) } } @@ -173,26 +172,25 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { // specific part of the type in the error message. struct TyPathVisitor<'tcx> { tcx: TyCtxt<'tcx>, - found_it: bool, bound_region: ty::BoundRegionKind, current_index: ty::DebruijnIndex, } impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> { + type Result = ControlFlow<()>; type NestedFilter = nested_filter::OnlyBodies; fn nested_visit_map(&mut self) -> Map<'tcx> { self.tcx.hir() } - fn visit_lifetime(&mut self, lifetime: &hir::Lifetime) { + fn visit_lifetime(&mut self, lifetime: &hir::Lifetime) -> Self::Result { match (self.tcx.named_bound_var(lifetime.hir_id), self.bound_region) { // the lifetime of the TyPath! (Some(rbv::ResolvedArg::EarlyBound(id)), ty::BrNamed(def_id, _)) => { debug!("EarlyBound id={:?} def_id={:?}", id, def_id); if id == def_id { - self.found_it = true; - return; // we can stop visiting now + return ControlFlow::Break(()); } } @@ -201,8 +199,7 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> { debug!("id={:?}", id); debug!("def_id={:?}", def_id); if debruijn_index == self.current_index && id == def_id { - self.found_it = true; - return; // we can stop visiting now + return ControlFlow::Break(()); } } @@ -220,9 +217,10 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> { debug!("no arg found"); } } + ControlFlow::Continue(()) } - fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) { + fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) -> Self::Result { // ignore nested types // // If you have a type like `Foo<'a, &Ty>` we @@ -231,5 +229,6 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> { // Making `visit_ty` empty will ignore the `&Ty` embedded // inside, it will get reached by the outer visitor. debug!("`Ty` corresponding to a struct is {:?}", arg); + ControlFlow::Continue(()) } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index 472dab639d590..8cdf39b173987 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -1,4 +1,5 @@ use crate::infer::error_reporting::hir::Path; +use core::ops::ControlFlow; use hir::def::CtorKind; use hir::intravisit::{walk_expr, walk_stmt, Visitor}; use hir::{Local, QPath}; @@ -563,62 +564,55 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { cause: &ObligationCause<'_>, span: Span, ) -> Option { - let hir = self.tcx.hir(); - if let Some(body_id) = self.tcx.hir().maybe_body_owned_by(cause.body_id) { - let body = hir.body(body_id); - - /// Find the if expression with given span - struct IfVisitor { - pub result: bool, - pub found_if: bool, - pub err_span: Span, - } - - impl<'v> Visitor<'v> for IfVisitor { - fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { - if self.result { - return; - } - match ex.kind { - hir::ExprKind::If(cond, _, _) => { - self.found_if = true; - walk_expr(self, cond); - self.found_if = false; - } - _ => walk_expr(self, ex), - } - } + /// Find the if expression with given span + struct IfVisitor { + pub found_if: bool, + pub err_span: Span, + } - fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) { - if let hir::StmtKind::Local(hir::Local { - span, - pat: hir::Pat { .. }, - ty: None, - init: Some(_), - .. - }) = &ex.kind - && self.found_if - && span.eq(&self.err_span) - { - self.result = true; + impl<'v> Visitor<'v> for IfVisitor { + type Result = ControlFlow<()>; + fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) -> Self::Result { + match ex.kind { + hir::ExprKind::If(cond, _, _) => { + self.found_if = true; + walk_expr(self, cond)?; + self.found_if = false; + ControlFlow::Continue(()) } - walk_stmt(self, ex); + _ => walk_expr(self, ex), } + } - fn visit_body(&mut self, body: &'v hir::Body<'v>) { - hir::intravisit::walk_body(self, body); + fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) -> Self::Result { + if let hir::StmtKind::Local(hir::Local { + span, + pat: hir::Pat { .. }, + ty: None, + init: Some(_), + .. + }) = &ex.kind + && self.found_if + && span.eq(&self.err_span) + { + ControlFlow::Break(()) + } else { + walk_stmt(self, ex) } } - let mut visitor = IfVisitor { err_span: span, found_if: false, result: false }; - visitor.visit_body(body); - if visitor.result { - return Some(TypeErrorAdditionalDiags::AddLetForLetChains { - span: span.shrink_to_lo(), - }); + fn visit_body(&mut self, body: &'v hir::Body<'v>) -> Self::Result { + hir::intravisit::walk_body(self, body) } } - None + + self.tcx.hir().maybe_body_owned_by(cause.body_id).and_then(|body_id| { + let body = self.tcx.hir().body(body_id); + IfVisitor { err_span: span, found_if: false } + .visit_body(body) + .is_break() + .then(|| TypeErrorAdditionalDiags::AddLetForLetChains { span: span.shrink_to_lo() }) + }) } /// For "one type is more general than the other" errors on closures, suggest changing the lifetime diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 97f9a4b291d09..029bddda1e1c5 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -20,6 +20,7 @@ #![allow(rustc::untranslatable_diagnostic)] #![feature(associated_type_bounds)] #![feature(box_patterns)] +#![feature(control_flow_enum)] #![feature(extend_one)] #![feature(let_chains)] #![feature(if_let_guard)] diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 7a930937255b9..3d2e3115bdead 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -19,6 +19,7 @@ use crate::traits::{ ObligationCause, ObligationCauseCode, ObligationCtxt, Overflow, PredicateObligation, SelectionError, SignatureMismatch, TraitNotObjectSafe, }; +use core::ops::ControlFlow; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_errors::codes::*; use rustc_errors::{pluralize, struct_span_code_err, Applicability, MultiSpan, StringPart}; @@ -1126,22 +1127,20 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err: &mut Diag<'_>, ) -> bool { let span = obligation.cause.span; - struct V<'v> { + struct V { search_span: Span, - found: Option<&'v hir::Expr<'v>>, } - impl<'v> Visitor<'v> for V<'v> { - fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { + impl<'v> Visitor<'v> for V { + type Result = ControlFlow<&'v hir::Expr<'v>>; + fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) -> Self::Result { if let hir::ExprKind::Match(expr, _arms, hir::MatchSource::TryDesugar(_)) = ex.kind + && ex.span.with_lo(ex.span.hi() - BytePos(1)).source_equal(self.search_span) + && let hir::ExprKind::Call(_, [expr, ..]) = expr.kind { - if ex.span.with_lo(ex.span.hi() - BytePos(1)).source_equal(self.search_span) { - if let hir::ExprKind::Call(_, [expr, ..]) = expr.kind { - self.found = Some(expr); - return; - } - } + ControlFlow::Break(expr) + } else { + hir::intravisit::walk_expr(self, ex) } - hir::intravisit::walk_expr(self, ex); } } let hir_id = self.tcx.local_def_id_to_hir_id(obligation.cause.body_id); @@ -1149,9 +1148,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. }) => body_id, _ => return false, }; - let mut v = V { search_span: span, found: None }; - v.visit_body(self.tcx.hir().body(*body_id)); - let Some(expr) = v.found else { + let ControlFlow::Break(expr) = + (V { search_span: span }).visit_body(self.tcx.hir().body(*body_id)) + else { return false; }; let Some(typeck) = &self.typeck_results else { diff --git a/tests/ui/issues/issue-20831-debruijn.stderr b/tests/ui/issues/issue-20831-debruijn.stderr index 7d1e19b7e4759..60721f001b738 100644 --- a/tests/ui/issues/issue-20831-debruijn.stderr +++ b/tests/ui/issues/issue-20831-debruijn.stderr @@ -4,11 +4,11 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d LL | fn subscribe(&mut self, t : Box::Output> + 'a>) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: first, the lifetime cannot outlive the anonymous lifetime defined here... - --> $DIR/issue-20831-debruijn.rs:28:58 +note: first, the lifetime cannot outlive the anonymous lifetime as defined here... + --> $DIR/issue-20831-debruijn.rs:28:18 | LL | fn subscribe(&mut self, t : Box::Output> + 'a>) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ note: ...but the lifetime must also be valid for the lifetime `'a` as defined here... --> $DIR/issue-20831-debruijn.rs:26:6 | From 63091b105d08b7b0db19d699d3be3060acde04ad Mon Sep 17 00:00:00 2001 From: beetrees Date: Mon, 15 May 2023 18:34:32 +0000 Subject: [PATCH 03/12] Make `arg_expand_all` not short-circuit on first error --- compiler/rustc_driver_impl/src/args.rs | 27 ++++++++++++------- compiler/rustc_driver_impl/src/lib.rs | 2 +- src/librustdoc/lib.rs | 2 +- src/tools/tidy/src/ui_tests.rs | 6 ++--- .../commandline-argfile-badutf8-windows.rs | 17 ++++++++++++ ...commandline-argfile-badutf8-windows.stderr | 2 ++ .../commandline-argfile-badutf8.args | 0 .../argfile/commandline-argfile-badutf8.rs | 18 +++++++++++++ .../commandline-argfile-badutf8.stderr | 2 ++ .../commandline-argfile-missing-windows.rs} | 7 ++++- ...commandline-argfile-missing-windows.stderr | 2 ++ .../argfile/commandline-argfile-missing.rs | 20 ++++++++++++++ .../commandline-argfile-missing.stderr | 2 ++ .../commandline-argfile-multiple-windows.rs | 20 ++++++++++++++ ...ommandline-argfile-multiple-windows.stderr | 6 +++++ .../argfile/commandline-argfile-multiple.rs | 21 +++++++++++++++ .../commandline-argfile-multiple.stderr | 6 +++++ .../{ => argfile}/commandline-argfile.args | 0 .../{ => argfile}/commandline-argfile.rs | 2 +- .../rustdoc-ui/commandline-argfile-badutf8.rs | 12 --------- .../commandline-argfile-badutf8.stderr | 2 -- .../commandline-argfile-missing.stderr | 2 -- .../commandline-argfile-badutf8-windows.rs | 17 ++++++++++++ ...commandline-argfile-badutf8-windows.stderr | 2 ++ .../commandline-argfile-badutf8.args | 0 .../ui/argfile/commandline-argfile-badutf8.rs | 18 +++++++++++++ .../commandline-argfile-badutf8.stderr | 2 ++ .../commandline-argfile-missing-windows.rs} | 7 ++++- ...commandline-argfile-missing-windows.stderr | 2 ++ .../ui/argfile/commandline-argfile-missing.rs | 20 ++++++++++++++ .../commandline-argfile-missing.stderr | 2 ++ .../commandline-argfile-multiple-windows.rs | 20 ++++++++++++++ ...ommandline-argfile-multiple-windows.stderr | 6 +++++ .../argfile/commandline-argfile-multiple.rs | 21 +++++++++++++++ .../commandline-argfile-multiple.stderr | 6 +++++ .../ui/{ => argfile}/commandline-argfile.args | 0 tests/ui/{ => argfile}/commandline-argfile.rs | 2 +- tests/ui/commandline-argfile-badutf8.rs | 12 --------- tests/ui/commandline-argfile-badutf8.stderr | 2 -- tests/ui/commandline-argfile-missing.stderr | 2 -- .../shell-argfiles-badquotes-windows.stderr | 2 +- .../shell-argfiles-badquotes.stderr | 2 +- 42 files changed, 270 insertions(+), 53 deletions(-) create mode 100644 tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.rs create mode 100644 tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.stderr rename tests/rustdoc-ui/{ => argfile}/commandline-argfile-badutf8.args (100%) create mode 100644 tests/rustdoc-ui/argfile/commandline-argfile-badutf8.rs create mode 100644 tests/rustdoc-ui/argfile/commandline-argfile-badutf8.stderr rename tests/{ui/commandline-argfile-missing.rs => rustdoc-ui/argfile/commandline-argfile-missing-windows.rs} (55%) create mode 100644 tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.stderr create mode 100644 tests/rustdoc-ui/argfile/commandline-argfile-missing.rs create mode 100644 tests/rustdoc-ui/argfile/commandline-argfile-missing.stderr create mode 100644 tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.rs create mode 100644 tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.stderr create mode 100644 tests/rustdoc-ui/argfile/commandline-argfile-multiple.rs create mode 100644 tests/rustdoc-ui/argfile/commandline-argfile-multiple.stderr rename tests/rustdoc-ui/{ => argfile}/commandline-argfile.args (100%) rename tests/rustdoc-ui/{ => argfile}/commandline-argfile.rs (72%) delete mode 100644 tests/rustdoc-ui/commandline-argfile-badutf8.rs delete mode 100644 tests/rustdoc-ui/commandline-argfile-badutf8.stderr delete mode 100644 tests/rustdoc-ui/commandline-argfile-missing.stderr create mode 100644 tests/ui/argfile/commandline-argfile-badutf8-windows.rs create mode 100644 tests/ui/argfile/commandline-argfile-badutf8-windows.stderr rename tests/ui/{ => argfile}/commandline-argfile-badutf8.args (100%) create mode 100644 tests/ui/argfile/commandline-argfile-badutf8.rs create mode 100644 tests/ui/argfile/commandline-argfile-badutf8.stderr rename tests/{rustdoc-ui/commandline-argfile-missing.rs => ui/argfile/commandline-argfile-missing-windows.rs} (55%) create mode 100644 tests/ui/argfile/commandline-argfile-missing-windows.stderr create mode 100644 tests/ui/argfile/commandline-argfile-missing.rs create mode 100644 tests/ui/argfile/commandline-argfile-missing.stderr create mode 100644 tests/ui/argfile/commandline-argfile-multiple-windows.rs create mode 100644 tests/ui/argfile/commandline-argfile-multiple-windows.stderr create mode 100644 tests/ui/argfile/commandline-argfile-multiple.rs create mode 100644 tests/ui/argfile/commandline-argfile-multiple.stderr rename tests/ui/{ => argfile}/commandline-argfile.args (100%) rename tests/ui/{ => argfile}/commandline-argfile.rs (72%) delete mode 100644 tests/ui/commandline-argfile-badutf8.rs delete mode 100644 tests/ui/commandline-argfile-badutf8.stderr delete mode 100644 tests/ui/commandline-argfile-missing.stderr diff --git a/compiler/rustc_driver_impl/src/args.rs b/compiler/rustc_driver_impl/src/args.rs index 8b6fb5fd660f3..8c03f54bb5993 100644 --- a/compiler/rustc_driver_impl/src/args.rs +++ b/compiler/rustc_driver_impl/src/args.rs @@ -4,6 +4,7 @@ use std::fs; use std::io; use rustc_session::EarlyDiagCtxt; +use rustc_span::ErrorGuaranteed; /// Expands argfiles in command line arguments. #[derive(Default)] @@ -86,7 +87,7 @@ impl Expander { fn read_file(path: &str) -> Result { fs::read_to_string(path).map_err(|e| { if e.kind() == io::ErrorKind::InvalidData { - Error::Utf8Error(Some(path.to_string())) + Error::Utf8Error(path.to_string()) } else { Error::IOError(path.to_string(), e) } @@ -94,23 +95,30 @@ impl Expander { } } +/// Replaces any `@file` arguments with the contents of `file`, with each line of `file` as a +/// separate argument. +/// /// **Note:** This function doesn't interpret argument 0 in any special way. /// If this function is intended to be used with command line arguments, /// `argv[0]` must be removed prior to calling it manually. #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable -pub fn arg_expand_all(early_dcx: &EarlyDiagCtxt, at_args: &[String]) -> Vec { +pub fn arg_expand_all( + early_dcx: &EarlyDiagCtxt, + at_args: &[String], +) -> Result, ErrorGuaranteed> { let mut expander = Expander::default(); + let mut result = Ok(()); for arg in at_args { if let Err(err) = expander.arg(arg) { - early_dcx.early_fatal(format!("Failed to load argument file: {err}")); + result = Err(early_dcx.early_err(format!("failed to load argument file: {err}"))); } } - expander.finish() + result.map(|()| expander.finish()) } #[derive(Debug)] -pub enum Error { - Utf8Error(Option), +enum Error { + Utf8Error(String), IOError(String, io::Error), ShellParseError(String), } @@ -118,10 +126,9 @@ pub enum Error { impl fmt::Display for Error { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Error::Utf8Error(None) => write!(fmt, "Utf8 error"), - Error::Utf8Error(Some(path)) => write!(fmt, "Utf8 error in {path}"), - Error::IOError(path, err) => write!(fmt, "IO Error: {path}: {err}"), - Error::ShellParseError(path) => write!(fmt, "Invalid shell-style arguments in {path}"), + Error::Utf8Error(path) => write!(fmt, "UTF-8 error in {path}"), + Error::IOError(path, err) => write!(fmt, "IO error: {path}: {err}"), + Error::ShellParseError(path) => write!(fmt, "invalid shell-style arguments in {path}"), } } } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 3b6bf0005a3b1..3831bbc1e15c0 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -292,7 +292,7 @@ fn run_compiler( // the compiler with @empty_file as argv[0] and no more arguments. let at_args = at_args.get(1..).unwrap_or_default(); - let args = args::arg_expand_all(&default_early_dcx, at_args); + let args = args::arg_expand_all(&default_early_dcx, at_args)?; let Some(matches) = handle_options(&default_early_dcx, &args) else { return Ok(()) }; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 33837fe5652ce..faa92c9d15a75 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -705,7 +705,7 @@ fn main_args( // the compiler with @empty_file as argv[0] and no more arguments. let at_args = at_args.get(1..).unwrap_or_default(); - let args = rustc_driver::args::arg_expand_all(early_dcx, at_args); + let args = rustc_driver::args::arg_expand_all(early_dcx, at_args)?; let mut options = getopts::Options::new(); for option in opts() { diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index a9c5be913ba1e..b4540f146271a 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -18,7 +18,7 @@ const ENTRY_LIMIT: usize = 900; // FIXME: The following limits should be reduced eventually. const ISSUES_ENTRY_LIMIT: usize = 1750; -const ROOT_ENTRY_LIMIT: usize = 872; +const ROOT_ENTRY_LIMIT: usize = 866; const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ "rs", // test source files @@ -34,8 +34,8 @@ const EXTENSION_EXCEPTION_PATHS: &[&str] = &[ "tests/ui/asm/named-asm-labels.s", // loading an external asm file to test named labels lint "tests/ui/codegen/mismatched-data-layout.json", // testing mismatched data layout w/ custom targets "tests/ui/check-cfg/my-awesome-platform.json", // testing custom targets with cfgs - "tests/ui/commandline-argfile-badutf8.args", // passing args via a file - "tests/ui/commandline-argfile.args", // passing args via a file + "tests/ui/argfile/commandline-argfile-badutf8.args", // passing args via a file + "tests/ui/argfile/commandline-argfile.args", // passing args via a file "tests/ui/crate-loading/auxiliary/libfoo.rlib", // testing loading a manually created rlib "tests/ui/include-macros/data.bin", // testing including data with the include macros "tests/ui/include-macros/file.txt", // testing including data with the include macros diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.rs b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.rs new file mode 100644 index 0000000000000..eba17ca6f7e92 --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.rs @@ -0,0 +1,17 @@ +// Check to see if we can get parameters from an @argsfile file +// +// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path +// separators. This test uses backslash as the path separator for the command +// line arguments and is only run on windows. +// +//@ only-windows +//@ compile-flags: --cfg cmdline_set @{{src-base}}\argfile\commandline-argfile-badutf8.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.stderr b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.stderr new file mode 100644 index 0000000000000..b4c0d4c20d75f --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.stderr @@ -0,0 +1,2 @@ +error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args + diff --git a/tests/rustdoc-ui/commandline-argfile-badutf8.args b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.args similarity index 100% rename from tests/rustdoc-ui/commandline-argfile-badutf8.args rename to tests/rustdoc-ui/argfile/commandline-argfile-badutf8.args diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.rs b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.rs new file mode 100644 index 0000000000000..1b2e52af762f1 --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.rs @@ -0,0 +1,18 @@ +// Check to see if we can get parameters from an @argsfile file +// +// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path +// separators. We have a duplicated version of this test that uses backslash as +// the path separator for the command line arguments that is only run on +// windows. +// +//@ ignore-windows +//@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile-badutf8.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.stderr b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.stderr new file mode 100644 index 0000000000000..b4c0d4c20d75f --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.stderr @@ -0,0 +1,2 @@ +error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args + diff --git a/tests/ui/commandline-argfile-missing.rs b/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.rs similarity index 55% rename from tests/ui/commandline-argfile-missing.rs rename to tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.rs index bb9644d66ce10..24cfd25ccadb9 100644 --- a/tests/ui/commandline-argfile-missing.rs +++ b/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.rs @@ -1,8 +1,13 @@ // Check to see if we can get parameters from an @argsfile file // +// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path +// separators. This test uses backslash as the path separator for the command +// line arguments and is only run on windows. +// +//@ only-windows //@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" //@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " -//@ compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-missing.args +//@ compile-flags: --cfg cmdline_set @{{src-base}}\argfile\commandline-argfile-missing.args #[cfg(not(cmdline_set))] compile_error!("cmdline_set not set"); diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.stderr b/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.stderr new file mode 100644 index 0000000000000..28a20debf1cca --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.stderr @@ -0,0 +1,2 @@ +error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR) + diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-missing.rs b/tests/rustdoc-ui/argfile/commandline-argfile-missing.rs new file mode 100644 index 0000000000000..fe6a849b0c8b6 --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-missing.rs @@ -0,0 +1,20 @@ +// Check to see if we can get parameters from an @argsfile file +// +// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path +// separators. We have a duplicated version of this test that uses backslash as +// the path separator for the command line arguments that is only run on +// windows. +// +//@ ignore-windows +//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile-missing.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-missing.stderr b/tests/rustdoc-ui/argfile/commandline-argfile-missing.stderr new file mode 100644 index 0000000000000..28a20debf1cca --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-missing.stderr @@ -0,0 +1,2 @@ +error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR) + diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.rs b/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.rs new file mode 100644 index 0000000000000..84c050d84e25b --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.rs @@ -0,0 +1,20 @@ +// Check to see if we can get parameters from an @argsfile file +// +// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path +// separators. This test uses backslash as the path separator for the command +// line arguments and is only run on windows. +// +//@ only-windows +//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ normalize-stderr-test: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING " +//@ compile-flags: --cfg cmdline_set @{{src-base}}\argfile\commandline-argfile-missing.args @{{src-base}}\argfile\commandline-argfile-badutf8.args @{{src-base}}\argfile\commandline-argfile-missing2.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.stderr b/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.stderr new file mode 100644 index 0000000000000..ad3b445c958fd --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.stderr @@ -0,0 +1,6 @@ +error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR) + +error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args + +error: failed to load argument file: IO error: $DIR/commandline-argfile-missing2.args: $FILE_MISSING (os error $ERR) + diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-multiple.rs b/tests/rustdoc-ui/argfile/commandline-argfile-multiple.rs new file mode 100644 index 0000000000000..f658ee34fbb08 --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-multiple.rs @@ -0,0 +1,21 @@ +// Check to see if we can get parameters from an @argsfile file +// +// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path +// separators. We have a duplicated version of this test that uses backslash as +// the path separator for the command line arguments that is only run on +// windows. +// +//@ ignore-windows +//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ normalize-stderr-test: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING " +//@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile-missing.args @{{src-base}}/argfile/commandline-argfile-badutf8.args @{{src-base}}/argfile/commandline-argfile-missing2.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-multiple.stderr b/tests/rustdoc-ui/argfile/commandline-argfile-multiple.stderr new file mode 100644 index 0000000000000..ad3b445c958fd --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-multiple.stderr @@ -0,0 +1,6 @@ +error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR) + +error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args + +error: failed to load argument file: IO error: $DIR/commandline-argfile-missing2.args: $FILE_MISSING (os error $ERR) + diff --git a/tests/rustdoc-ui/commandline-argfile.args b/tests/rustdoc-ui/argfile/commandline-argfile.args similarity index 100% rename from tests/rustdoc-ui/commandline-argfile.args rename to tests/rustdoc-ui/argfile/commandline-argfile.args diff --git a/tests/rustdoc-ui/commandline-argfile.rs b/tests/rustdoc-ui/argfile/commandline-argfile.rs similarity index 72% rename from tests/rustdoc-ui/commandline-argfile.rs rename to tests/rustdoc-ui/argfile/commandline-argfile.rs index d71bc72562b75..b0b314f53ceb7 100644 --- a/tests/rustdoc-ui/commandline-argfile.rs +++ b/tests/rustdoc-ui/argfile/commandline-argfile.rs @@ -1,7 +1,7 @@ // Check to see if we can get parameters from an @argsfile file // //@ check-pass -//@ compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile.args +//@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile.args #[cfg(not(cmdline_set))] compile_error!("cmdline_set not set"); diff --git a/tests/rustdoc-ui/commandline-argfile-badutf8.rs b/tests/rustdoc-ui/commandline-argfile-badutf8.rs deleted file mode 100644 index b3a19fa62741d..0000000000000 --- a/tests/rustdoc-ui/commandline-argfile-badutf8.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Check to see if we can get parameters from an @argsfile file -// -//@ compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-badutf8.args - -#[cfg(not(cmdline_set))] -compile_error!("cmdline_set not set"); - -#[cfg(not(unbroken))] -compile_error!("unbroken not set"); - -fn main() { -} diff --git a/tests/rustdoc-ui/commandline-argfile-badutf8.stderr b/tests/rustdoc-ui/commandline-argfile-badutf8.stderr deleted file mode 100644 index 9af6fc0a518df..0000000000000 --- a/tests/rustdoc-ui/commandline-argfile-badutf8.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: Failed to load argument file: Utf8 error in $DIR/commandline-argfile-badutf8.args - diff --git a/tests/rustdoc-ui/commandline-argfile-missing.stderr b/tests/rustdoc-ui/commandline-argfile-missing.stderr deleted file mode 100644 index 179ad83100419..0000000000000 --- a/tests/rustdoc-ui/commandline-argfile-missing.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: Failed to load argument file: IO Error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR) - diff --git a/tests/ui/argfile/commandline-argfile-badutf8-windows.rs b/tests/ui/argfile/commandline-argfile-badutf8-windows.rs new file mode 100644 index 0000000000000..eba17ca6f7e92 --- /dev/null +++ b/tests/ui/argfile/commandline-argfile-badutf8-windows.rs @@ -0,0 +1,17 @@ +// Check to see if we can get parameters from an @argsfile file +// +// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path +// separators. This test uses backslash as the path separator for the command +// line arguments and is only run on windows. +// +//@ only-windows +//@ compile-flags: --cfg cmdline_set @{{src-base}}\argfile\commandline-argfile-badutf8.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} diff --git a/tests/ui/argfile/commandline-argfile-badutf8-windows.stderr b/tests/ui/argfile/commandline-argfile-badutf8-windows.stderr new file mode 100644 index 0000000000000..b4c0d4c20d75f --- /dev/null +++ b/tests/ui/argfile/commandline-argfile-badutf8-windows.stderr @@ -0,0 +1,2 @@ +error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args + diff --git a/tests/ui/commandline-argfile-badutf8.args b/tests/ui/argfile/commandline-argfile-badutf8.args similarity index 100% rename from tests/ui/commandline-argfile-badutf8.args rename to tests/ui/argfile/commandline-argfile-badutf8.args diff --git a/tests/ui/argfile/commandline-argfile-badutf8.rs b/tests/ui/argfile/commandline-argfile-badutf8.rs new file mode 100644 index 0000000000000..1b2e52af762f1 --- /dev/null +++ b/tests/ui/argfile/commandline-argfile-badutf8.rs @@ -0,0 +1,18 @@ +// Check to see if we can get parameters from an @argsfile file +// +// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path +// separators. We have a duplicated version of this test that uses backslash as +// the path separator for the command line arguments that is only run on +// windows. +// +//@ ignore-windows +//@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile-badutf8.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} diff --git a/tests/ui/argfile/commandline-argfile-badutf8.stderr b/tests/ui/argfile/commandline-argfile-badutf8.stderr new file mode 100644 index 0000000000000..b4c0d4c20d75f --- /dev/null +++ b/tests/ui/argfile/commandline-argfile-badutf8.stderr @@ -0,0 +1,2 @@ +error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args + diff --git a/tests/rustdoc-ui/commandline-argfile-missing.rs b/tests/ui/argfile/commandline-argfile-missing-windows.rs similarity index 55% rename from tests/rustdoc-ui/commandline-argfile-missing.rs rename to tests/ui/argfile/commandline-argfile-missing-windows.rs index bb9644d66ce10..24cfd25ccadb9 100644 --- a/tests/rustdoc-ui/commandline-argfile-missing.rs +++ b/tests/ui/argfile/commandline-argfile-missing-windows.rs @@ -1,8 +1,13 @@ // Check to see if we can get parameters from an @argsfile file // +// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path +// separators. This test uses backslash as the path separator for the command +// line arguments and is only run on windows. +// +//@ only-windows //@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" //@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " -//@ compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-missing.args +//@ compile-flags: --cfg cmdline_set @{{src-base}}\argfile\commandline-argfile-missing.args #[cfg(not(cmdline_set))] compile_error!("cmdline_set not set"); diff --git a/tests/ui/argfile/commandline-argfile-missing-windows.stderr b/tests/ui/argfile/commandline-argfile-missing-windows.stderr new file mode 100644 index 0000000000000..28a20debf1cca --- /dev/null +++ b/tests/ui/argfile/commandline-argfile-missing-windows.stderr @@ -0,0 +1,2 @@ +error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR) + diff --git a/tests/ui/argfile/commandline-argfile-missing.rs b/tests/ui/argfile/commandline-argfile-missing.rs new file mode 100644 index 0000000000000..fe6a849b0c8b6 --- /dev/null +++ b/tests/ui/argfile/commandline-argfile-missing.rs @@ -0,0 +1,20 @@ +// Check to see if we can get parameters from an @argsfile file +// +// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path +// separators. We have a duplicated version of this test that uses backslash as +// the path separator for the command line arguments that is only run on +// windows. +// +//@ ignore-windows +//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile-missing.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} diff --git a/tests/ui/argfile/commandline-argfile-missing.stderr b/tests/ui/argfile/commandline-argfile-missing.stderr new file mode 100644 index 0000000000000..28a20debf1cca --- /dev/null +++ b/tests/ui/argfile/commandline-argfile-missing.stderr @@ -0,0 +1,2 @@ +error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR) + diff --git a/tests/ui/argfile/commandline-argfile-multiple-windows.rs b/tests/ui/argfile/commandline-argfile-multiple-windows.rs new file mode 100644 index 0000000000000..84c050d84e25b --- /dev/null +++ b/tests/ui/argfile/commandline-argfile-multiple-windows.rs @@ -0,0 +1,20 @@ +// Check to see if we can get parameters from an @argsfile file +// +// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path +// separators. This test uses backslash as the path separator for the command +// line arguments and is only run on windows. +// +//@ only-windows +//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ normalize-stderr-test: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING " +//@ compile-flags: --cfg cmdline_set @{{src-base}}\argfile\commandline-argfile-missing.args @{{src-base}}\argfile\commandline-argfile-badutf8.args @{{src-base}}\argfile\commandline-argfile-missing2.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} diff --git a/tests/ui/argfile/commandline-argfile-multiple-windows.stderr b/tests/ui/argfile/commandline-argfile-multiple-windows.stderr new file mode 100644 index 0000000000000..ad3b445c958fd --- /dev/null +++ b/tests/ui/argfile/commandline-argfile-multiple-windows.stderr @@ -0,0 +1,6 @@ +error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR) + +error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args + +error: failed to load argument file: IO error: $DIR/commandline-argfile-missing2.args: $FILE_MISSING (os error $ERR) + diff --git a/tests/ui/argfile/commandline-argfile-multiple.rs b/tests/ui/argfile/commandline-argfile-multiple.rs new file mode 100644 index 0000000000000..f658ee34fbb08 --- /dev/null +++ b/tests/ui/argfile/commandline-argfile-multiple.rs @@ -0,0 +1,21 @@ +// Check to see if we can get parameters from an @argsfile file +// +// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path +// separators. We have a duplicated version of this test that uses backslash as +// the path separator for the command line arguments that is only run on +// windows. +// +//@ ignore-windows +//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ normalize-stderr-test: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING " +//@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile-missing.args @{{src-base}}/argfile/commandline-argfile-badutf8.args @{{src-base}}/argfile/commandline-argfile-missing2.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} diff --git a/tests/ui/argfile/commandline-argfile-multiple.stderr b/tests/ui/argfile/commandline-argfile-multiple.stderr new file mode 100644 index 0000000000000..ad3b445c958fd --- /dev/null +++ b/tests/ui/argfile/commandline-argfile-multiple.stderr @@ -0,0 +1,6 @@ +error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR) + +error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args + +error: failed to load argument file: IO error: $DIR/commandline-argfile-missing2.args: $FILE_MISSING (os error $ERR) + diff --git a/tests/ui/commandline-argfile.args b/tests/ui/argfile/commandline-argfile.args similarity index 100% rename from tests/ui/commandline-argfile.args rename to tests/ui/argfile/commandline-argfile.args diff --git a/tests/ui/commandline-argfile.rs b/tests/ui/argfile/commandline-argfile.rs similarity index 72% rename from tests/ui/commandline-argfile.rs rename to tests/ui/argfile/commandline-argfile.rs index 8577312a3c406..387a8d033b3cd 100644 --- a/tests/ui/commandline-argfile.rs +++ b/tests/ui/argfile/commandline-argfile.rs @@ -1,7 +1,7 @@ // Check to see if we can get parameters from an @argsfile file // //@ build-pass -//@ compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile.args +//@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile.args #[cfg(not(cmdline_set))] compile_error!("cmdline_set not set"); diff --git a/tests/ui/commandline-argfile-badutf8.rs b/tests/ui/commandline-argfile-badutf8.rs deleted file mode 100644 index b3a19fa62741d..0000000000000 --- a/tests/ui/commandline-argfile-badutf8.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Check to see if we can get parameters from an @argsfile file -// -//@ compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-badutf8.args - -#[cfg(not(cmdline_set))] -compile_error!("cmdline_set not set"); - -#[cfg(not(unbroken))] -compile_error!("unbroken not set"); - -fn main() { -} diff --git a/tests/ui/commandline-argfile-badutf8.stderr b/tests/ui/commandline-argfile-badutf8.stderr deleted file mode 100644 index 9af6fc0a518df..0000000000000 --- a/tests/ui/commandline-argfile-badutf8.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: Failed to load argument file: Utf8 error in $DIR/commandline-argfile-badutf8.args - diff --git a/tests/ui/commandline-argfile-missing.stderr b/tests/ui/commandline-argfile-missing.stderr deleted file mode 100644 index 179ad83100419..0000000000000 --- a/tests/ui/commandline-argfile-missing.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: Failed to load argument file: IO Error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR) - diff --git a/tests/ui/shell-argfiles/shell-argfiles-badquotes-windows.stderr b/tests/ui/shell-argfiles/shell-argfiles-badquotes-windows.stderr index 14adb1f740abb..dc219c153f781 100644 --- a/tests/ui/shell-argfiles/shell-argfiles-badquotes-windows.stderr +++ b/tests/ui/shell-argfiles/shell-argfiles-badquotes-windows.stderr @@ -1,2 +1,2 @@ -error: Failed to load argument file: Invalid shell-style arguments in $DIR/shell-argfiles-badquotes.args +error: failed to load argument file: invalid shell-style arguments in $DIR/shell-argfiles-badquotes.args diff --git a/tests/ui/shell-argfiles/shell-argfiles-badquotes.stderr b/tests/ui/shell-argfiles/shell-argfiles-badquotes.stderr index 14adb1f740abb..dc219c153f781 100644 --- a/tests/ui/shell-argfiles/shell-argfiles-badquotes.stderr +++ b/tests/ui/shell-argfiles/shell-argfiles-badquotes.stderr @@ -1,2 +1,2 @@ -error: Failed to load argument file: Invalid shell-style arguments in $DIR/shell-argfiles-badquotes.args +error: failed to load argument file: invalid shell-style arguments in $DIR/shell-argfiles-badquotes.args From fb87e606cc6951cb41044b23f8f723abd9ad7fce Mon Sep 17 00:00:00 2001 From: beetrees Date: Mon, 15 May 2023 18:35:14 +0000 Subject: [PATCH 04/12] Refactor argument UTF-8 checking into `rustc_driver::args::raw_args()` --- compiler/rustc_driver_impl/src/args.rs | 28 ++++++++++++++++++++++---- compiler/rustc_driver_impl/src/lib.rs | 10 +-------- src/librustdoc/lib.rs | 13 +++--------- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_driver_impl/src/args.rs b/compiler/rustc_driver_impl/src/args.rs index 8c03f54bb5993..28574457389fe 100644 --- a/compiler/rustc_driver_impl/src/args.rs +++ b/compiler/rustc_driver_impl/src/args.rs @@ -1,7 +1,4 @@ -use std::error; -use std::fmt; -use std::fs; -use std::io; +use std::{env, error, fmt, fs, io}; use rustc_session::EarlyDiagCtxt; use rustc_span::ErrorGuaranteed; @@ -116,6 +113,29 @@ pub fn arg_expand_all( result.map(|()| expander.finish()) } +/// Gets the raw unprocessed command-line arguments as Unicode strings, without doing any further +/// processing (e.g., without `@file` expansion). +/// +/// This function is identical to [`env::args()`] except that it emits an error when it encounters +/// non-Unicode arguments instead of panicking. +pub fn raw_args(early_dcx: &EarlyDiagCtxt) -> Result, ErrorGuaranteed> { + let mut res = Ok(Vec::new()); + for (i, arg) in env::args_os().enumerate() { + match arg.into_string() { + Ok(arg) => { + if let Ok(args) = &mut res { + args.push(arg); + } + } + Err(arg) => { + res = + Err(early_dcx.early_err(format!("argument {i} is not valid Unicode: {arg:?}"))) + } + } + } + res +} + #[derive(Debug)] enum Error { Utf8Error(String), diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 3831bbc1e15c0..cd296c9662a3d 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -1515,15 +1515,7 @@ pub fn main() -> ! { let mut callbacks = TimePassesCallbacks::default(); let using_internal_features = install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ()); let exit_code = catch_with_exit_code(|| { - let args = env::args_os() - .enumerate() - .map(|(i, arg)| { - arg.into_string().unwrap_or_else(|arg| { - early_dcx.early_fatal(format!("argument {i} is not valid Unicode: {arg:?}")) - }) - }) - .collect::>(); - RunCompiler::new(&args, &mut callbacks) + RunCompiler::new(&args::raw_args(&early_dcx)?, &mut callbacks) .set_using_internal_features(using_internal_features) .run() }); diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index faa92c9d15a75..39d27b104cdde 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -179,21 +179,14 @@ pub fn main() { rustc_driver::init_logger(&early_dcx, rustc_log::LoggerConfig::from_env("RUSTDOC_LOG")); let exit_code = rustc_driver::catch_with_exit_code(|| { - let args = env::args_os() - .enumerate() - .map(|(i, arg)| { - arg.into_string().unwrap_or_else(|arg| { - early_dcx.early_fatal(format!("argument {i} is not valid Unicode: {arg:?}")) - }) - }) - .collect::>(); - main_args(&mut early_dcx, &args, using_internal_features) + let at_args = rustc_driver::args::raw_args(&early_dcx)?; + main_args(&mut early_dcx, &at_args, using_internal_features) }); process::exit(exit_code); } fn init_logging(early_dcx: &EarlyDiagCtxt) { - let color_logs = match std::env::var("RUSTDOC_LOG_COLOR").as_deref() { + let color_logs = match env::var("RUSTDOC_LOG_COLOR").as_deref() { Ok("always") => true, Ok("never") => false, Ok("auto") | Err(VarError::NotPresent) => io::stdout().is_terminal(), From d626d135bc9c2867e029365c51d75a5f7c15e0e8 Mon Sep 17 00:00:00 2001 From: beetrees Date: Mon, 15 May 2023 18:37:47 +0000 Subject: [PATCH 05/12] Use `rustc_driver::args::raw_args()` in Clippy --- src/tools/clippy/src/driver.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index 8fc66644632cd..9e42abbc9aa9e 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -190,7 +190,7 @@ pub fn main() { }); exit(rustc_driver::catch_with_exit_code(move || { - let mut orig_args: Vec = env::args().collect(); + let mut orig_args = rustc_driver::args::raw_args(&early_dcx)?; let has_sysroot_arg = |args: &mut [String]| -> bool { if arg_value(args, "--sysroot", |_| true).is_some() { From 2d7d0bda4334b1b7be951ff45c4397dab0a1dd32 Mon Sep 17 00:00:00 2001 From: beetrees Date: Mon, 15 May 2023 21:22:18 +0100 Subject: [PATCH 06/12] Use `rustc_driver::args::raw_args()` in Miri --- src/tools/miri/src/bin/miri.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 2f37a64576e4e..a9b5aa5f1efcc 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -342,6 +342,8 @@ fn main() { // (`install_ice_hook` might change `RUST_BACKTRACE`.) let env_snapshot = env::vars_os().collect::>(); + let args = rustc_driver::args::raw_args(&early_dcx).unwrap_or_else(|_| std::process::exit(rustc_driver::EXIT_FAILURE)); + // If the environment asks us to actually be rustc, then do that. if let Some(crate_kind) = env::var_os("MIRI_BE_RUSTC") { // Earliest rustc setup. @@ -359,7 +361,7 @@ fn main() { // We cannot use `rustc_driver::main` as we need to adjust the CLI arguments. run_compiler( - env::args().collect(), + args, target_crate, &mut MiriBeRustCompilerCalls { target_crate }, using_internal_features, @@ -382,7 +384,7 @@ fn main() { // If user has explicitly enabled/disabled isolation let mut isolation_enabled: Option = None; - for arg in env::args() { + for arg in args { if rustc_args.is_empty() { // Very first arg: binary name. rustc_args.push(arg); From bed9d1fb7d9d19e985bc8a6ef2d82804f3d2e49a Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 7 Mar 2024 21:40:11 +0000 Subject: [PATCH 07/12] Add known-bug tests for `derive(PartialEq)` mismatches with `#[repr(packed)]` attributes that are not visible before macro expansion --- .../auxiliary/proc_macro_generate_packed.rs | 27 +++++++++++++++++++ .../multiple_definitions_attribute_merging.rs | 19 +++++++++++++ ...tiple_definitions_attribute_merging.stderr | 26 ++++++++++++++++++ .../ui/resolve/proc_macro_generated_packed.rs | 20 ++++++++++++++ .../proc_macro_generated_packed.stderr | 16 +++++++++++ 5 files changed, 108 insertions(+) create mode 100644 tests/ui/resolve/auxiliary/proc_macro_generate_packed.rs create mode 100644 tests/ui/resolve/multiple_definitions_attribute_merging.rs create mode 100644 tests/ui/resolve/multiple_definitions_attribute_merging.stderr create mode 100644 tests/ui/resolve/proc_macro_generated_packed.rs create mode 100644 tests/ui/resolve/proc_macro_generated_packed.stderr diff --git a/tests/ui/resolve/auxiliary/proc_macro_generate_packed.rs b/tests/ui/resolve/auxiliary/proc_macro_generate_packed.rs new file mode 100644 index 0000000000000..c0b24706dcba6 --- /dev/null +++ b/tests/ui/resolve/auxiliary/proc_macro_generate_packed.rs @@ -0,0 +1,27 @@ +//@ force-host +//@ no-prefer-dynamic +//@ compile-flags: --crate-type proc-macro + +extern crate proc_macro; + +use proc_macro::*; + +#[proc_macro_attribute] +pub fn proc_macro_attribute_that_generates_repr_packed( + _attr: TokenStream, + item: TokenStream, +) -> TokenStream { + let repr = vec![TokenTree::Ident(Ident::new("packed", Span::call_site()))].into_iter(); + let attr = vec![ + TokenTree::Ident(Ident::new("repr", Span::call_site())), + TokenTree::Group(Group::new(Delimiter::Parenthesis, repr.collect())), + ] + .into_iter(); + vec![ + TokenTree::Punct(Punct::new('#', Spacing::Alone)), + TokenTree::Group(Group::new(Delimiter::Bracket, attr.collect())), + ] + .into_iter() + .chain(item) + .collect() +} diff --git a/tests/ui/resolve/multiple_definitions_attribute_merging.rs b/tests/ui/resolve/multiple_definitions_attribute_merging.rs new file mode 100644 index 0000000000000..523717861e1ba --- /dev/null +++ b/tests/ui/resolve/multiple_definitions_attribute_merging.rs @@ -0,0 +1,19 @@ +//! This test ICEs because the `repr(packed)` attributes +//! end up on the `Dealigned` struct's attribute list, but the +//! derive didn't see that. + +//@known-bug: #120873 +//@ failure-status: 101 +//@ normalize-stderr-test "note: .*\n\n" -> "" +//@ normalize-stderr-test "thread 'rustc' panicked.*\n" -> "" +//@ normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@ rustc-env:RUST_BACKTRACE=0 + +#[repr(packed)] +struct Dealigned(u8, T); + +#[derive(PartialEq)] +#[repr(C)] +struct Dealigned(u8, T); + +fn main() {} diff --git a/tests/ui/resolve/multiple_definitions_attribute_merging.stderr b/tests/ui/resolve/multiple_definitions_attribute_merging.stderr new file mode 100644 index 0000000000000..b2d20af883abb --- /dev/null +++ b/tests/ui/resolve/multiple_definitions_attribute_merging.stderr @@ -0,0 +1,26 @@ +error[E0428]: the name `Dealigned` is defined multiple times + --> $DIR/multiple_definitions_attribute_merging.rs:17:1 + | +LL | struct Dealigned(u8, T); + | --------------------------- previous definition of the type `Dealigned` here +... +LL | struct Dealigned(u8, T); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Dealigned` redefined here + | + = error: internal compiler error: compiler/rustc_mir_transform/src/check_packed_ref.rs:LL:CC: builtin derive created an unaligned reference + --> $DIR/multiple_definitions_attribute_merging.rs:17:25 + | +LL | #[derive(PartialEq)] + | --------- in this derive macro expansion +LL | #[repr(C)] +LL | struct Dealigned(u8, T); + | ^ + | + = Box +query stack during panic: +#0 [mir_const] preparing `::eq` for borrow checking +#1 [mir_promoted] promoting constants in MIR for `::eq` +end of query stack +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0428`. diff --git a/tests/ui/resolve/proc_macro_generated_packed.rs b/tests/ui/resolve/proc_macro_generated_packed.rs new file mode 100644 index 0000000000000..34a7e4db6030d --- /dev/null +++ b/tests/ui/resolve/proc_macro_generated_packed.rs @@ -0,0 +1,20 @@ +//! This test ICEs because the `repr(packed)` attribute +//! was generated by a proc macro, so `#[derive]` didn't see it. + +//@aux-build: proc_macro_generate_packed.rs +//@known-bug: #120873 +//@ failure-status: 101 +//@ normalize-stderr-test "note: .*\n\n" -> "" +//@ normalize-stderr-test "thread 'rustc' panicked.*\n" -> "" +//@ normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@ rustc-env:RUST_BACKTRACE=0 + +extern crate proc_macro_generate_packed; +use proc_macro_generate_packed::proc_macro_attribute_that_generates_repr_packed; + +#[derive(PartialEq)] +#[repr(C)] +#[proc_macro_attribute_that_generates_repr_packed] +struct Dealigned(u8, T); + +fn main() {} diff --git a/tests/ui/resolve/proc_macro_generated_packed.stderr b/tests/ui/resolve/proc_macro_generated_packed.stderr new file mode 100644 index 0000000000000..507e5867c904b --- /dev/null +++ b/tests/ui/resolve/proc_macro_generated_packed.stderr @@ -0,0 +1,16 @@ +error: internal compiler error: compiler/rustc_mir_transform/src/check_packed_ref.rs:LL:CC: builtin derive created an unaligned reference + --> $DIR/proc_macro_generated_packed.rs:18:25 + | +LL | #[derive(PartialEq)] + | --------- in this derive macro expansion +... +LL | struct Dealigned(u8, T); + | ^ + | + = Box +query stack during panic: +#0 [mir_const] preparing `::eq` for borrow checking +#1 [mir_promoted] promoting constants in MIR for `::eq` +end of query stack +error: aborting due to 1 previous error + From 025ad403a976cbb80a3a472e333f4544baef9261 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 8 Mar 2024 02:57:02 +0000 Subject: [PATCH 08/12] Don't ICE in CTFE if raw/fn-ptr types differ --- .../src/transform/check_consts/check.rs | 1 - .../ui/consts/different-fn-ptr-binders-during-ctfe.rs | 6 ++++++ .../consts/different-fn-ptr-binders-during-ctfe.stderr | 10 ++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 tests/ui/consts/different-fn-ptr-binders-during-ctfe.rs create mode 100644 tests/ui/consts/different-fn-ptr-binders-during-ctfe.stderr diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 0b41b4f96820b..7ec78e7b9cfd6 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -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 diff --git a/tests/ui/consts/different-fn-ptr-binders-during-ctfe.rs b/tests/ui/consts/different-fn-ptr-binders-during-ctfe.rs new file mode 100644 index 0000000000000..b378542e5730c --- /dev/null +++ b/tests/ui/consts/different-fn-ptr-binders-during-ctfe.rs @@ -0,0 +1,6 @@ +const fn cmp(x: fn(&'static ()), y: for<'a> fn(&'a ())) -> bool { + x == y + //~^ ERROR pointers cannot be reliably compared during const eval +} + +fn main() {} diff --git a/tests/ui/consts/different-fn-ptr-binders-during-ctfe.stderr b/tests/ui/consts/different-fn-ptr-binders-during-ctfe.stderr new file mode 100644 index 0000000000000..43a7b9ce66ce0 --- /dev/null +++ b/tests/ui/consts/different-fn-ptr-binders-during-ctfe.stderr @@ -0,0 +1,10 @@ +error: pointers cannot be reliably compared during const eval + --> $DIR/different-fn-ptr-binders-during-ctfe.rs:2:5 + | +LL | x == y + | ^^^^^^ + | + = note: see issue #53020 for more information + +error: aborting due to 1 previous error + From ece20f0d595b6a0c0e61e88a6d76dcccae1f5b2a Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 8 Mar 2024 12:02:31 +0800 Subject: [PATCH 09/12] Bless tidy issues order --- src/tools/tidy/src/issues.txt | 194 ++++++++++++++++----------------- src/tools/tidy/src/ui_tests.rs | 15 ++- 2 files changed, 109 insertions(+), 100 deletions(-) diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index cd3976ea6575d..91bbf5041ff58 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -183,8 +183,8 @@ "ui/async-await/issue-67651.rs", "ui/async-await/issue-67765-async-diagnostic.rs", "ui/async-await/issue-68112.rs", -"ui/async-await/issue-68523.rs", "ui/async-await/issue-68523-start.rs", +"ui/async-await/issue-68523.rs", "ui/async-await/issue-69446-fnmut-capture.rs", "ui/async-await/issue-70594.rs", "ui/async-await/issue-70818.rs", @@ -342,8 +342,8 @@ "ui/borrowck/issue-52967-edition-2018-needs-two-phase-borrows.rs", "ui/borrowck/issue-53432-nested-closure-outlives-borrowed-value.rs", "ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs", -"ui/borrowck/issue-54499-field-mutation-of-moved-out.rs", "ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.rs", +"ui/borrowck/issue-54499-field-mutation-of-moved-out.rs", "ui/borrowck/issue-54499-field-mutation-of-never-init.rs", "ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs", "ui/borrowck/issue-55492-borrowck-migrate-scans-parents.rs", @@ -360,9 +360,9 @@ "ui/borrowck/issue-71546.rs", "ui/borrowck/issue-7573.rs", "ui/borrowck/issue-80772.rs", +"ui/borrowck/issue-81365-1.rs", "ui/borrowck/issue-81365-10.rs", "ui/borrowck/issue-81365-11.rs", -"ui/borrowck/issue-81365-1.rs", "ui/borrowck/issue-81365-2.rs", "ui/borrowck/issue-81365-3.rs", "ui/borrowck/issue-81365-4.rs", @@ -392,6 +392,9 @@ "ui/borrowck/issue-95079-missing-move-in-nested-closure.rs", "ui/box/issue-82446.rs", "ui/box/issue-95036.rs", +"ui/c-variadic/issue-32201.rs", +"ui/c-variadic/issue-86053-1.rs", +"ui/c-variadic/issue-86053-2.rs", "ui/cast/issue-106883-is-empty.rs", "ui/cast/issue-10991.rs", "ui/cast/issue-17444.rs", @@ -399,19 +402,19 @@ "ui/cast/issue-85586.rs", "ui/cast/issue-88621.rs", "ui/cast/issue-89497.rs", +"ui/closure-expected-type/issue-24421.rs", "ui/closure_context/issue-26046-fn-mut.rs", "ui/closure_context/issue-26046-fn-once.rs", "ui/closure_context/issue-42065.rs", -"ui/closure-expected-type/issue-24421.rs", "ui/closures/2229_closure_analysis/issue-118144.rs", "ui/closures/2229_closure_analysis/issue-87378.rs", "ui/closures/2229_closure_analysis/issue-87987.rs", "ui/closures/2229_closure_analysis/issue-88118-2.rs", -"ui/closures/2229_closure_analysis/issue_88118.rs", "ui/closures/2229_closure_analysis/issue-88476.rs", "ui/closures/2229_closure_analysis/issue-89606.rs", "ui/closures/2229_closure_analysis/issue-90465.rs", "ui/closures/2229_closure_analysis/issue-92724-needsdrop-query-cycle.rs", +"ui/closures/2229_closure_analysis/issue_88118.rs", "ui/closures/2229_closure_analysis/match/issue-87097.rs", "ui/closures/2229_closure_analysis/match/issue-87426.rs", "ui/closures/2229_closure_analysis/match/issue-87988.rs", @@ -644,8 +647,8 @@ "ui/const-generics/issues/issue-99641.rs", "ui/const-generics/parser-error-recovery/issue-89013-no-assoc.rs", "ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs", -"ui/const-generics/parser-error-recovery/issue-89013.rs", "ui/const-generics/parser-error-recovery/issue-89013-type.rs", +"ui/const-generics/parser-error-recovery/issue-89013.rs", "ui/const-generics/type-dependent/issue-61936.rs", "ui/const-generics/type-dependent/issue-63695.rs", "ui/const-generics/type-dependent/issue-67144-1.rs", @@ -689,13 +692,13 @@ "ui/consts/const-eval/issue-91827-extern-types-field-offset.rs", "ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier-2.rs", "ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier.rs", +"ui/consts/const-mut-refs/issue-76510.rs", "ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.rs", "ui/consts/const_in_pattern/issue-44333.rs", "ui/consts/const_in_pattern/issue-53708.rs", "ui/consts/const_in_pattern/issue-62614.rs", "ui/consts/const_in_pattern/issue-65466.rs", "ui/consts/const_in_pattern/issue-73431.rs", -"ui/consts/const-mut-refs/issue-76510.rs", "ui/consts/control-flow/issue-46843.rs", "ui/consts/control-flow/issue-50577.rs", "ui/consts/extra-const-ub/issue-100771.rs", @@ -714,9 +717,9 @@ "ui/consts/issue-17074.rs", "ui/consts/issue-17458.rs", "ui/consts/issue-17718-borrow-interior.rs", -"ui/consts/issue-17718-constants-not-static.rs", "ui/consts/issue-17718-const-bad-values.rs", "ui/consts/issue-17718-const-borrow.rs", +"ui/consts/issue-17718-constants-not-static.rs", "ui/consts/issue-17718-references.rs", "ui/consts/issue-17718.rs", "ui/consts/issue-17756.rs", @@ -841,9 +844,6 @@ "ui/coroutine/issue-91477.rs", "ui/coroutine/issue-93161.rs", "ui/cross-crate/issue-64872/issue-64872.rs", -"ui/c-variadic/issue-32201.rs", -"ui/c-variadic/issue-86053-1.rs", -"ui/c-variadic/issue-86053-2.rs", "ui/cycle-trait/issue-12511.rs", "ui/debuginfo/issue-105386-debuginfo-ub.rs", "ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.rs", @@ -902,15 +902,6 @@ "ui/did_you_mean/issue-56028-there-is-an-enum-variant.rs", "ui/did_you_mean/issue-87830-try-brackets-for-arrays.rs", "ui/drop/auxiliary/issue-10028.rs", -"ui/dropck/issue-24805-dropck-itemless.rs", -"ui/dropck/issue-28498-ugeh-with-lifetime-param.rs", -"ui/dropck/issue-28498-ugeh-with-passed-to-fn.rs", -"ui/dropck/issue-28498-ugeh-with-trait-bound.rs", -"ui/dropck/issue-29844.rs", -"ui/dropck/issue-34053.rs", -"ui/dropck/issue-38868.rs", -"ui/dropck/issue-54943-1.rs", -"ui/dropck/issue-54943-2.rs", "ui/drop/issue-100276.rs", "ui/drop/issue-10028.rs", "ui/drop/issue-103107.rs", @@ -929,6 +920,15 @@ "ui/drop/issue-90752-raw-ptr-shenanigans.rs", "ui/drop/issue-90752.rs", "ui/drop/issue-979.rs", +"ui/dropck/issue-24805-dropck-itemless.rs", +"ui/dropck/issue-28498-ugeh-with-lifetime-param.rs", +"ui/dropck/issue-28498-ugeh-with-passed-to-fn.rs", +"ui/dropck/issue-28498-ugeh-with-trait-bound.rs", +"ui/dropck/issue-29844.rs", +"ui/dropck/issue-34053.rs", +"ui/dropck/issue-38868.rs", +"ui/dropck/issue-54943-1.rs", +"ui/dropck/issue-54943-2.rs", "ui/dst/issue-113447.rs", "ui/dst/issue-90528-unsizing-not-suggestion-110063.rs", "ui/dst/issue-90528-unsizing-suggestion-1.rs", @@ -1014,14 +1014,14 @@ "ui/fn/issue-3904.rs", "ui/fn/issue-39259.rs", "ui/fn/issue-80179.rs", -"ui/foreign/issue-74120-lowering-of-ffi-block-bodies.rs", -"ui/foreign/issue-91370-foreign-fn-block-impl.rs", -"ui/foreign/issue-99276-same-type-lifetimes.rs", -"ui/for/issue-20605.rs", "ui/for-loop-while/issue-1257.rs", "ui/for-loop-while/issue-2216.rs", "ui/for-loop-while/issue-51345.rs", "ui/for-loop-while/issue-69841.rs", +"ui/for/issue-20605.rs", +"ui/foreign/issue-74120-lowering-of-ffi-block-bodies.rs", +"ui/foreign/issue-91370-foreign-fn-block-impl.rs", +"ui/foreign/issue-99276-same-type-lifetimes.rs", "ui/function-pointer/issue-102289.rs", "ui/functions-closures/closure-expected-type/issue-38714.rs", "ui/generic-associated-types/bugs/issue-100013.rs", @@ -1084,8 +1084,8 @@ "ui/generic-associated-types/issue-87258_b.rs", "ui/generic-associated-types/issue-87429-2.rs", "ui/generic-associated-types/issue-87429-associated-type-default.rs", -"ui/generic-associated-types/issue-87429.rs", "ui/generic-associated-types/issue-87429-specialization.rs", +"ui/generic-associated-types/issue-87429.rs", "ui/generic-associated-types/issue-87748.rs", "ui/generic-associated-types/issue-87750.rs", "ui/generic-associated-types/issue-88287.rs", @@ -1095,9 +1095,9 @@ "ui/generic-associated-types/issue-88595.rs", "ui/generic-associated-types/issue-89008.rs", "ui/generic-associated-types/issue-89352.rs", -"ui/generic-associated-types/issue-90014.rs", -"ui/generic-associated-types/issue-90014-tait2.rs", "ui/generic-associated-types/issue-90014-tait.rs", +"ui/generic-associated-types/issue-90014-tait2.rs", +"ui/generic-associated-types/issue-90014.rs", "ui/generic-associated-types/issue-90729.rs", "ui/generic-associated-types/issue-91139.rs", "ui/generic-associated-types/issue-91883.rs", @@ -1119,8 +1119,8 @@ "ui/generics/issue-333.rs", "ui/generics/issue-59508-1.rs", "ui/generics/issue-59508.rs", -"ui/generics/issue-61631-default-type-param-cannot-reference-self.rs", "ui/generics/issue-61631-default-type-param-can-reference-self-in-trait.rs", +"ui/generics/issue-61631-default-type-param-cannot-reference-self.rs", "ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.rs", "ui/generics/issue-79605.rs", "ui/generics/issue-80512-param-reordering-with-defaults.rs", @@ -1179,9 +1179,6 @@ "ui/hygiene/issue-47312.rs", "ui/hygiene/issue-61574-const-parameters.rs", "ui/hygiene/issue-77523-def-site-async-await.rs", -"ui/implied-bounds/issue-100690.rs", -"ui/implied-bounds/issue-101951.rs", -"ui/implied-bounds/issue-110161.rs", "ui/impl-trait/explicit-generic-args-with-impl-trait/issue-87718.rs", "ui/impl-trait/in-trait/issue-102140.rs", "ui/impl-trait/in-trait/issue-102301.rs", @@ -1261,6 +1258,9 @@ "ui/impl-trait/issues/issue-92305.rs", "ui/impl-trait/issues/issue-93788.rs", "ui/impl-trait/issues/issue-99348-impl-compatibility.rs", +"ui/implied-bounds/issue-100690.rs", +"ui/implied-bounds/issue-101951.rs", +"ui/implied-bounds/issue-110161.rs", "ui/imports/auxiliary/issue-114682-2-extern.rs", "ui/imports/auxiliary/issue-114682-3-extern.rs", "ui/imports/auxiliary/issue-114682-4-extern.rs", @@ -1368,8 +1368,8 @@ "ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.rs", "ui/inference/need_type_info/issue-109905.rs", "ui/inference/need_type_info/issue-113264-incorrect-impl-trait-in-path-suggestion.rs", -"ui/infinite/issue-41731-infinite-macro-println.rs", "ui/infinite/issue-41731-infinite-macro-print.rs", +"ui/infinite/issue-41731-infinite-macro-println.rs", "ui/intrinsics/issue-28575.rs", "ui/intrinsics/issue-84297-reifying-copy.rs", "ui/invalid/issue-114435-layout-type-err.rs", @@ -1386,8 +1386,8 @@ "ui/issues/auxiliary/issue-11508.rs", "ui/issues/auxiliary/issue-11529.rs", "ui/issues/auxiliary/issue-11680.rs", -"ui/issues/auxiliary/issue-12133-dylib2.rs", "ui/issues/auxiliary/issue-12133-dylib.rs", +"ui/issues/auxiliary/issue-12133-dylib2.rs", "ui/issues/auxiliary/issue-12133-rlib.rs", "ui/issues/auxiliary/issue-12612-1.rs", "ui/issues/auxiliary/issue-12612-2.rs", @@ -1554,8 +1554,8 @@ "ui/issues/issue-13497-2.rs", "ui/issues/issue-13497.rs", "ui/issues/issue-13507-2.rs", -"ui/issues/issue-13620.rs", "ui/issues/issue-1362.rs", +"ui/issues/issue-13620.rs", "ui/issues/issue-13665.rs", "ui/issues/issue-13703.rs", "ui/issues/issue-13763.rs", @@ -1649,8 +1649,8 @@ "ui/issues/issue-16819.rs", "ui/issues/issue-16922-rpass.rs", "ui/issues/issue-16939.rs", -"ui/issues/issue-16966.rs", "ui/issues/issue-1696.rs", +"ui/issues/issue-16966.rs", "ui/issues/issue-16994.rs", "ui/issues/issue-17001.rs", "ui/issues/issue-17033.rs", @@ -1729,8 +1729,8 @@ "ui/issues/issue-18952.rs", "ui/issues/issue-18959.rs", "ui/issues/issue-18988.rs", -"ui/issues/issue-19001.rs", "ui/issues/issue-1900.rs", +"ui/issues/issue-19001.rs", "ui/issues/issue-19037.rs", "ui/issues/issue-19086.rs", "ui/issues/issue-19097.rs", @@ -1826,8 +1826,8 @@ "ui/issues/issue-21622.rs", "ui/issues/issue-21634.rs", "ui/issues/issue-21655.rs", -"ui/issues/issue-21701.rs", "ui/issues/issue-2170-exe.rs", +"ui/issues/issue-21701.rs", "ui/issues/issue-21763.rs", "ui/issues/issue-21891.rs", "ui/issues/issue-2190-1.rs", @@ -1863,15 +1863,15 @@ "ui/issues/issue-22777.rs", "ui/issues/issue-22781.rs", "ui/issues/issue-22789.rs", -"ui/issues/issue-22814.rs", "ui/issues/issue-2281-part1.rs", +"ui/issues/issue-22814.rs", "ui/issues/issue-2284.rs", "ui/issues/issue-22864-1.rs", "ui/issues/issue-22864-2.rs", "ui/issues/issue-22872.rs", "ui/issues/issue-22874.rs", -"ui/issues/issue-22886.rs", "ui/issues/issue-2288.rs", +"ui/issues/issue-22886.rs", "ui/issues/issue-22894.rs", "ui/issues/issue-22933-1.rs", "ui/issues/issue-22933-2.rs", @@ -1884,9 +1884,9 @@ "ui/issues/issue-23073.rs", "ui/issues/issue-2311-2.rs", "ui/issues/issue-2311.rs", +"ui/issues/issue-2312.rs", "ui/issues/issue-23122-1.rs", "ui/issues/issue-23122-2.rs", -"ui/issues/issue-2312.rs", "ui/issues/issue-2316-c.rs", "ui/issues/issue-23173.rs", "ui/issues/issue-23189.rs", @@ -1917,8 +1917,8 @@ "ui/issues/issue-23649-2.rs", "ui/issues/issue-23649-3.rs", "ui/issues/issue-23699.rs", -"ui/issues/issue-23808.rs", "ui/issues/issue-2380-b.rs", +"ui/issues/issue-23808.rs", "ui/issues/issue-2383.rs", "ui/issues/issue-23891.rs", "ui/issues/issue-23898.rs", @@ -1981,8 +1981,8 @@ "ui/issues/issue-25746-bool-transmute.rs", "ui/issues/issue-25757.rs", "ui/issues/issue-25810.rs", -"ui/issues/issue-25901.rs", "ui/issues/issue-2590.rs", +"ui/issues/issue-25901.rs", "ui/issues/issue-26056.rs", "ui/issues/issue-26093.rs", "ui/issues/issue-26095.rs", @@ -2041,10 +2041,10 @@ "ui/issues/issue-28433.rs", "ui/issues/issue-28472.rs", "ui/issues/issue-2848.rs", +"ui/issues/issue-2849.rs", "ui/issues/issue-28498-must-work-ex1.rs", "ui/issues/issue-28498-must-work-ex2.rs", "ui/issues/issue-28498-ugeh-ex1.rs", -"ui/issues/issue-2849.rs", "ui/issues/issue-28550.rs", "ui/issues/issue-28561.rs", "ui/issues/issue-28568.rs", @@ -2062,8 +2062,8 @@ "ui/issues/issue-28999.rs", "ui/issues/issue-29030.rs", "ui/issues/issue-29037.rs", -"ui/issues/issue-29048.rs", "ui/issues/issue-2904.rs", +"ui/issues/issue-29048.rs", "ui/issues/issue-29053.rs", "ui/issues/issue-29071-2.rs", "ui/issues/issue-29071.rs", @@ -2075,8 +2075,8 @@ "ui/issues/issue-2935.rs", "ui/issues/issue-29466.rs", "ui/issues/issue-29485.rs", -"ui/issues/issue-29516.rs", "ui/issues/issue-2951.rs", +"ui/issues/issue-29516.rs", "ui/issues/issue-29522.rs", "ui/issues/issue-29540.rs", "ui/issues/issue-29663.rs", @@ -2101,10 +2101,10 @@ "ui/issues/issue-30255.rs", "ui/issues/issue-3026.rs", "ui/issues/issue-3029.rs", -"ui/issues/issue-30371.rs", "ui/issues/issue-3037.rs", -"ui/issues/issue-30380.rs", +"ui/issues/issue-30371.rs", "ui/issues/issue-3038.rs", +"ui/issues/issue-30380.rs", "ui/issues/issue-3052.rs", "ui/issues/issue-30530.rs", "ui/issues/issue-30589.rs", @@ -2226,8 +2226,8 @@ "ui/issues/issue-37131.rs", "ui/issues/issue-37311-type-length-limit/issue-37311.rs", "ui/issues/issue-37510.rs", -"ui/issues/issue-37534.rs", "ui/issues/issue-3753.rs", +"ui/issues/issue-37534.rs", "ui/issues/issue-37576.rs", "ui/issues/issue-3763.rs", "ui/issues/issue-37665.rs", @@ -2254,8 +2254,8 @@ "ui/issues/issue-3888-2.rs", "ui/issues/issue-38919.rs", "ui/issues/issue-38942.rs", -"ui/issues/issue-38954.rs", "ui/issues/issue-3895.rs", +"ui/issues/issue-38954.rs", "ui/issues/issue-38987.rs", "ui/issues/issue-39089.rs", "ui/issues/issue-39175.rs", @@ -2265,8 +2265,8 @@ "ui/issues/issue-39687.rs", "ui/issues/issue-39709.rs", "ui/issues/issue-3979-2.rs", -"ui/issues/issue-3979.rs", "ui/issues/issue-3979-xcrate.rs", +"ui/issues/issue-3979.rs", "ui/issues/issue-39808.rs", "ui/issues/issue-39827.rs", "ui/issues/issue-39848.rs", @@ -2341,9 +2341,9 @@ "ui/issues/issue-43250.rs", "ui/issues/issue-43291.rs", "ui/issues/issue-4333.rs", +"ui/issues/issue-4335.rs", "ui/issues/issue-43355.rs", "ui/issues/issue-43357.rs", -"ui/issues/issue-4335.rs", "ui/issues/issue-43420-no-over-suggest.rs", "ui/issues/issue-43424.rs", "ui/issues/issue-43431.rs", @@ -2372,8 +2372,8 @@ "ui/issues/issue-44851.rs", "ui/issues/issue-4517.rs", "ui/issues/issue-4541.rs", -"ui/issues/issue-45425.rs", "ui/issues/issue-4542.rs", +"ui/issues/issue-45425.rs", "ui/issues/issue-4545.rs", "ui/issues/issue-45510.rs", "ui/issues/issue-45562.rs", @@ -2402,8 +2402,8 @@ "ui/issues/issue-47309.rs", "ui/issues/issue-4734.rs", "ui/issues/issue-4735.rs", -"ui/issues/issue-47364.rs", "ui/issues/issue-4736.rs", +"ui/issues/issue-47364.rs", "ui/issues/issue-47377.rs", "ui/issues/issue-47380.rs", "ui/issues/issue-47486.rs", @@ -2412,8 +2412,8 @@ "ui/issues/issue-47638.rs", "ui/issues/issue-47673.rs", "ui/issues/issue-47703-1.rs", -"ui/issues/issue-47703.rs", "ui/issues/issue-47703-tuple.rs", +"ui/issues/issue-47703.rs", "ui/issues/issue-47715.rs", "ui/issues/issue-47722.rs", "ui/issues/issue-48006.rs", @@ -2561,8 +2561,8 @@ "ui/issues/issue-59756.rs", "ui/issues/issue-5988.rs", "ui/issues/issue-5997-outer-generic-parameter/issue-5997-enum.rs", -"ui/issues/issue-5997-outer-generic-parameter/issue-5997.rs", "ui/issues/issue-5997-outer-generic-parameter/issue-5997-struct.rs", +"ui/issues/issue-5997-outer-generic-parameter/issue-5997.rs", "ui/issues/issue-60218.rs", "ui/issues/issue-60622.rs", "ui/issues/issue-60989.rs", @@ -2837,8 +2837,8 @@ "ui/lint/unused/issue-103320-must-use-ops.rs", "ui/lint/unused/issue-104397.rs", "ui/lint/unused/issue-105061-array-lint.rs", -"ui/lint/unused/issue-105061.rs", "ui/lint/unused/issue-105061-should-lint.rs", +"ui/lint/unused/issue-105061.rs", "ui/lint/unused/issue-117142-invalid-remove-parens.rs", "ui/lint/unused/issue-117284-arg-in-macro.rs", "ui/lint/unused/issue-119383-if-let-guard.rs", @@ -2862,8 +2862,8 @@ "ui/lint/use-redundant/issue-92904.rs", "ui/loops/issue-43162.rs", "ui/loops/issue-50576.rs", -"ui/loops/issue-69225-layout-repeated-checked-add.rs", "ui/loops/issue-69225-SCEVAddExpr-wrap-flag.rs", +"ui/loops/issue-69225-layout-repeated-checked-add.rs", "ui/loops/issue-82916.rs", "ui/lowering/issue-121108.rs", "ui/lowering/issue-96847.rs", @@ -3016,7 +3016,6 @@ "ui/mir/issue-29227.rs", "ui/mir/issue-46845.rs", "ui/mir/issue-60390.rs", -"ui/mir/issue66339.rs", "ui/mir/issue-66851.rs", "ui/mir/issue-66930.rs", "ui/mir/issue-67639-normalization-ice.rs", @@ -3043,6 +3042,7 @@ "ui/mir/issue-92893.rs", "ui/mir/issue-99852.rs", "ui/mir/issue-99866.rs", +"ui/mir/issue66339.rs", "ui/mir/validate/issue-95978-validator-lifetime-comparison.rs", "ui/mismatched_types/issue-106182.rs", "ui/mismatched_types/issue-112036.rs", @@ -3053,10 +3053,10 @@ "ui/mismatched_types/issue-26480.rs", "ui/mismatched_types/issue-35030.rs", "ui/mismatched_types/issue-36053-2.rs", -"ui/mismatched_types/issue-38371.rs", "ui/mismatched_types/issue-38371-unfixable.rs", -"ui/mismatched_types/issue-47706.rs", +"ui/mismatched_types/issue-38371.rs", "ui/mismatched_types/issue-47706-trait.rs", +"ui/mismatched_types/issue-47706.rs", "ui/mismatched_types/issue-74918-missing-lifetime.rs", "ui/mismatched_types/issue-75361-mismatched-impl.rs", "ui/mismatched_types/issue-84976.rs", @@ -3414,8 +3414,8 @@ "ui/parser/issues/issue-73568-lifetime-after-mut.rs", "ui/parser/issues/issue-75599.rs", "ui/parser/issues/issue-76437-async.rs", -"ui/parser/issues/issue-76437-const-async.rs", "ui/parser/issues/issue-76437-const-async-unsafe.rs", +"ui/parser/issues/issue-76437-const-async.rs", "ui/parser/issues/issue-76437-const.rs", "ui/parser/issues/issue-76437-pub-crate-unsafe.rs", "ui/parser/issues/issue-76437-unsafe.rs", @@ -3561,16 +3561,10 @@ "ui/privacy/issue-57264-2.rs", "ui/privacy/issue-75062-fieldless-tuple-struct.rs", "ui/privacy/issue-75906.rs", -"ui/privacy/issue-75907_b.rs", "ui/privacy/issue-75907.rs", +"ui/privacy/issue-75907_b.rs", "ui/privacy/issue-79593.rs", "ui/privacy/issue-92755.rs", -"ui/process/issue-13304.rs", -"ui/process/issue-14456.rs", -"ui/process/issue-14940.rs", -"ui/process/issue-16272.rs", -"ui/process/issue-20091.rs", -"ui/process/issue-30490.rs", "ui/proc-macro/auxiliary/issue-104884.rs", "ui/proc-macro/auxiliary/issue-107113.rs", "ui/proc-macro/auxiliary/issue-118809.rs", @@ -3619,8 +3613,14 @@ "ui/proc-macro/issue-86781-bad-inner-doc.rs", "ui/proc-macro/issue-89566-suggest-fix-invalid-top-level-macro-attr.rs", "ui/proc-macro/issue-91800.rs", -"ui/ptr_ops/issue-80309.rs", +"ui/process/issue-13304.rs", +"ui/process/issue-14456.rs", +"ui/process/issue-14940.rs", +"ui/process/issue-16272.rs", +"ui/process/issue-20091.rs", +"ui/process/issue-30490.rs", "ui/ptr_ops/issue-80309-safe.rs", +"ui/ptr_ops/issue-80309.rs", "ui/pub/issue-33174-restricted-type-in-public-interface.rs", "ui/query-system/issue-83479.rs", "ui/range/issue-54505-no-literals.rs", @@ -3698,8 +3698,8 @@ "ui/resolve/issue-21221-3.rs", "ui/resolve/issue-21221-4.rs", "ui/resolve/issue-22692.rs", -"ui/resolve/issue-23305.rs", "ui/resolve/issue-2330.rs", +"ui/resolve/issue-23305.rs", "ui/resolve/issue-2356.rs", "ui/resolve/issue-23716.rs", "ui/resolve/issue-24968.rs", @@ -3820,10 +3820,6 @@ "ui/span/issue-25199.rs", "ui/span/issue-26656.rs", "ui/span/issue-27522.rs", -"ui/span/issue28498-reject-ex1.rs", -"ui/span/issue28498-reject-lifetime-param.rs", -"ui/span/issue28498-reject-passed-to-fn.rs", -"ui/span/issue28498-reject-trait-bound.rs", "ui/span/issue-29106.rs", "ui/span/issue-29595.rs", "ui/span/issue-33884.rs", @@ -3838,6 +3834,10 @@ "ui/span/issue-43927-non-ADT-derive.rs", "ui/span/issue-71363.rs", "ui/span/issue-81800.rs", +"ui/span/issue28498-reject-ex1.rs", +"ui/span/issue28498-reject-lifetime-param.rs", +"ui/span/issue28498-reject-passed-to-fn.rs", +"ui/span/issue28498-reject-trait-bound.rs", "ui/specialization/issue-111232.rs", "ui/specialization/issue-33017.rs", "ui/specialization/issue-35376.rs", @@ -4124,8 +4124,8 @@ "ui/traits/object/issue-44454-3.rs", "ui/traits/suggest-dereferences/issue-39029.rs", "ui/traits/suggest-dereferences/issue-62530.rs", -"ui/traits/trait-upcasting/issue-11515.rs", "ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs", +"ui/traits/trait-upcasting/issue-11515.rs", "ui/traits/vtable/issue-91807.rs", "ui/traits/vtable/issue-97381.rs", "ui/transmutability/arrays/issue-103783-array-length.rs", @@ -4163,8 +4163,8 @@ "ui/type-alias-impl-trait/issue-58951.rs", "ui/type-alias-impl-trait/issue-60371.rs", "ui/type-alias-impl-trait/issue-60407.rs", -"ui/type-alias-impl-trait/issue-60564.rs", "ui/type-alias-impl-trait/issue-60564-working.rs", +"ui/type-alias-impl-trait/issue-60564.rs", "ui/type-alias-impl-trait/issue-60662.rs", "ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs", "ui/type-alias-impl-trait/issue-63263-closure-return.rs", @@ -4208,10 +4208,26 @@ "ui/type-alias/issue-62263-self-in-atb.rs", "ui/type-alias/issue-62305-self-assoc-ty.rs", "ui/type-alias/issue-62364-self-ty-arg.rs", +"ui/type-inference/issue-113283-alllocator-trait-eq.rs", +"ui/type-inference/issue-30225.rs", "ui/type/ascription/issue-34255-1.rs", "ui/type/ascription/issue-47666.rs", "ui/type/ascription/issue-54516.rs", "ui/type/ascription/issue-60933.rs", +"ui/type/issue-100584.rs", +"ui/type/issue-101866.rs", +"ui/type/issue-102598.rs", +"ui/type/issue-103271.rs", +"ui/type/issue-58355.rs", +"ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs", +"ui/type/issue-91268.rs", +"ui/type/issue-94187-verbose-type-name.rs", +"ui/type/type-check/issue-116967-cannot-coerce-returned-result.rs", +"ui/type/type-check/issue-22897.rs", +"ui/type/type-check/issue-40294.rs", +"ui/type/type-check/issue-41314.rs", +"ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs", +"ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.rs", "ui/typeck/auxiliary/issue-29181.rs", "ui/typeck/auxiliary/issue-36708.rs", "ui/typeck/auxiliary/issue-81943-lib.rs", @@ -4316,25 +4332,9 @@ "ui/typeck/issue-96738.rs", "ui/typeck/issue-98260.rs", "ui/typeck/issue-98982.rs", -"ui/type-inference/issue-113283-alllocator-trait-eq.rs", -"ui/type-inference/issue-30225.rs", -"ui/type/issue-100584.rs", -"ui/type/issue-101866.rs", -"ui/type/issue-102598.rs", -"ui/type/issue-103271.rs", -"ui/type/issue-58355.rs", -"ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs", -"ui/type/issue-91268.rs", -"ui/type/issue-94187-verbose-type-name.rs", "ui/typeof/issue-100183.rs", "ui/typeof/issue-29184.rs", "ui/typeof/issue-42060.rs", -"ui/type/type-check/issue-116967-cannot-coerce-returned-result.rs", -"ui/type/type-check/issue-22897.rs", -"ui/type/type-check/issue-40294.rs", -"ui/type/type-check/issue-41314.rs", -"ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs", -"ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.rs", "ui/unboxed-closures/issue-18652.rs", "ui/unboxed-closures/issue-18661.rs", "ui/unboxed-closures/issue-30906.rs", @@ -4355,6 +4355,11 @@ "ui/unsafe/issue-47412.rs", "ui/unsafe/issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs", "ui/unsafe/issue-87414-query-cycle.rs", +"ui/unsized-locals/issue-30276-feature-flagged.rs", +"ui/unsized-locals/issue-30276.rs", +"ui/unsized-locals/issue-50940-with-feature.rs", +"ui/unsized-locals/issue-50940.rs", +"ui/unsized-locals/issue-67981.rs", "ui/unsized/issue-115203.rs", "ui/unsized/issue-115809.rs", "ui/unsized/issue-30355.rs", @@ -4367,11 +4372,6 @@ "ui/unsized/issue-91801.rs", "ui/unsized/issue-91803.rs", "ui/unsized/issue-97732.rs", -"ui/unsized-locals/issue-30276-feature-flagged.rs", -"ui/unsized-locals/issue-30276.rs", -"ui/unsized-locals/issue-50940.rs", -"ui/unsized-locals/issue-50940-with-feature.rs", -"ui/unsized-locals/issue-67981.rs", "ui/use/issue-18986.rs", "ui/use/issue-60976-extern-use-primitive-type.rs", "ui/wf/issue-103573.rs", diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 1a53637ad42f9..dd3692c07d94c 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -104,9 +104,18 @@ pub fn check(path: &Path, bless: bool, bad: &mut bool) { // the list of files in ui tests that are allowed to start with `issue-XXXX` // BTreeSet because we would like a stable ordering so --bless works - let allowed_issue_names = BTreeSet::from( - include!("issues.txt").map(|path| path.replace("/", std::path::MAIN_SEPARATOR_STR)), - ); + let issues_list = + include!("issues.txt").map(|path| path.replace("/", std::path::MAIN_SEPARATOR_STR)); + let issues: Vec = Vec::from(issues_list.clone()); + let is_sorted = issues.windows(2).all(|w| w[0] < w[1]); + if !is_sorted && !bless { + tidy_error!( + bad, + "`src/tools/tidy/src/issues.txt` is not in order, mostly because you modified it manually, + please only update it with command `x test tidy --bless`" + ); + } + let allowed_issue_names = BTreeSet::from(issues_list); let mut remaining_issue_names: BTreeSet = allowed_issue_names.clone(); From c2f13db2b5bf80a670f86a4c3a3b61c2652a1018 Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Fri, 8 Mar 2024 14:25:11 +0800 Subject: [PATCH 10/12] rustc: Fix typo --- compiler/rustc_codegen_ssa/src/back/metadata.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index acdf3475f4e67..ab1bc0b6cd2eb 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -339,7 +339,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option 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 From 2e5f86c6a7e2e24ab390e046c70c5b65c750da30 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 8 Mar 2024 08:49:58 +0100 Subject: [PATCH 11/12] interpret: update comment about read_discriminant on uninhabited variants --- compiler/rustc_const_eval/src/interpret/discriminant.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs index e951a77611c21..6d4f6d0cb3c52 100644 --- a/compiler/rustc_const_eval/src/interpret/discriminant.rs +++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs @@ -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, @@ -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, @@ -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)) } From c81521ae545faf9e2b6c212f9e3faea69fde4d01 Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 8 Mar 2024 15:09:53 +0800 Subject: [PATCH 12/12] Fix crash in late internal checking --- compiler/rustc_lint/src/internal.rs | 10 ++++--- ...stderr => infinite_loop.eval_limit.stderr} | 4 +-- .../const-eval/infinite_loop.no_ice.stderr | 27 +++++++++++++++++++ tests/ui/consts/const-eval/infinite_loop.rs | 5 +++- 4 files changed, 39 insertions(+), 7 deletions(-) rename tests/ui/consts/const-eval/{infinite_loop.stderr => infinite_loop.eval_limit.stderr} (91%) create mode 100644 tests/ui/consts/const-eval/infinite_loop.no_ice.stderr diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 3a8c8e79b4f28..e8fcf4132ea73 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -379,13 +379,15 @@ impl LateLintPass<'_> for Diagnostics { _ => return, // occurs for fns passed as args } } - ExprKind::MethodCall(segment, _recv, args, _span) => { - let def_id = cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap(); - let fn_gen_args = cx.typeck_results().node_args(expr.hir_id); + ExprKind::MethodCall(_segment, _recv, args, _span) => { + let Some((span, def_id, fn_gen_args)) = typeck_results_of_method_fn(cx, expr) + else { + return; + }; let mut call_tys: Vec<_> = args.iter().map(|arg| cx.typeck_results().expr_ty(arg)).collect(); call_tys.insert(0, cx.tcx.types.self_param); // dummy inserted for `self` - (segment.ident.span, def_id, fn_gen_args, call_tys) + (span, def_id, fn_gen_args, call_tys) } _ => return, }; diff --git a/tests/ui/consts/const-eval/infinite_loop.stderr b/tests/ui/consts/const-eval/infinite_loop.eval_limit.stderr similarity index 91% rename from tests/ui/consts/const-eval/infinite_loop.stderr rename to tests/ui/consts/const-eval/infinite_loop.eval_limit.stderr index 37cd94bf7b7c7..d664ae8832325 100644 --- a/tests/ui/consts/const-eval/infinite_loop.stderr +++ b/tests/ui/consts/const-eval/infinite_loop.eval_limit.stderr @@ -1,5 +1,5 @@ error: constant evaluation is taking a long time - --> $DIR/infinite_loop.rs:12:9 + --> $DIR/infinite_loop.rs:15:9 | LL | / while n != 0 { LL | | @@ -10,7 +10,7 @@ LL | | } = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval. If your compilation actually takes a long time, you can safely allow the lint. help: the constant being evaluated - --> $DIR/infinite_loop.rs:10:18 + --> $DIR/infinite_loop.rs:13:18 | LL | let s = [(); { | __________________^ diff --git a/tests/ui/consts/const-eval/infinite_loop.no_ice.stderr b/tests/ui/consts/const-eval/infinite_loop.no_ice.stderr new file mode 100644 index 0000000000000..d664ae8832325 --- /dev/null +++ b/tests/ui/consts/const-eval/infinite_loop.no_ice.stderr @@ -0,0 +1,27 @@ +error: constant evaluation is taking a long time + --> $DIR/infinite_loop.rs:15:9 + | +LL | / while n != 0 { +LL | | +LL | | n = if n % 2 == 0 { n / 2 } else { 3 * n + 1 }; +LL | | } + | |_________^ + | + = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval. + If your compilation actually takes a long time, you can safely allow the lint. +help: the constant being evaluated + --> $DIR/infinite_loop.rs:13:18 + | +LL | let s = [(); { + | __________________^ +LL | | let mut n = 113383; // #20 in https://oeis.org/A006884 +LL | | while n != 0 { +LL | | +... | +LL | | n +LL | | }]; + | |_____^ + = note: `#[deny(long_running_const_eval)]` on by default + +error: aborting due to 1 previous error + diff --git a/tests/ui/consts/const-eval/infinite_loop.rs b/tests/ui/consts/const-eval/infinite_loop.rs index 44456f1ce47d9..f8cb79b63db55 100644 --- a/tests/ui/consts/const-eval/infinite_loop.rs +++ b/tests/ui/consts/const-eval/infinite_loop.rs @@ -1,8 +1,11 @@ //! This test tests two things at once: //! 1. we error if a const evaluation hits the deny-by-default lint limit //! 2. we do not ICE on invalid follow-up code +//! 3. no ICE when run with `-Z unstable-options` (issue 122177) -//@ compile-flags: -Z tiny-const-eval-limit +//@revisions: eval_limit no_ice +//@[no_ice] compile-flags: -Z tiny-const-eval-limit -Z unstable-options +//@[eval_limit] compile-flags: -Z tiny-const-eval-limit fn main() { // Tests the Collatz conjecture with an incorrect base case (0 instead of 1).