diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 872b671b031e7..3651ef2c614ef 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -88,82 +88,57 @@ jobs: run: "echo \"[CI_PR_NUMBER=$num]\"" env: num: "${{ github.event.number }}" - if: "success() && !env.SKIP_JOB && github.event_name == 'pull_request'" + if: "success() && github.event_name == 'pull_request'" - name: add extra environment variables run: src/ci/scripts/setup-environment.sh env: EXTRA_VARIABLES: "${{ toJson(matrix.env) }}" - if: success() && !env.SKIP_JOB - - name: decide whether to skip this job - run: src/ci/scripts/should-skip-this.sh - if: success() && !env.SKIP_JOB - name: ensure the channel matches the target branch run: src/ci/scripts/verify-channel.sh - if: success() && !env.SKIP_JOB - name: collect CPU statistics run: src/ci/scripts/collect-cpu-stats.sh - if: success() && !env.SKIP_JOB - name: show the current environment run: src/ci/scripts/dump-environment.sh - if: success() && !env.SKIP_JOB - name: install awscli run: src/ci/scripts/install-awscli.sh - if: success() && !env.SKIP_JOB - name: install sccache run: src/ci/scripts/install-sccache.sh - if: success() && !env.SKIP_JOB - name: select Xcode run: src/ci/scripts/select-xcode.sh - if: success() && !env.SKIP_JOB - name: install clang run: src/ci/scripts/install-clang.sh - if: success() && !env.SKIP_JOB - name: install tidy run: src/ci/scripts/install-tidy.sh - if: success() && !env.SKIP_JOB - name: install WIX run: src/ci/scripts/install-wix.sh - if: success() && !env.SKIP_JOB - name: disable git crlf conversion run: src/ci/scripts/disable-git-crlf-conversion.sh - if: success() && !env.SKIP_JOB - name: checkout submodules run: src/ci/scripts/checkout-submodules.sh - if: success() && !env.SKIP_JOB - name: install MSYS2 run: src/ci/scripts/install-msys2.sh - if: success() && !env.SKIP_JOB - name: install MinGW run: src/ci/scripts/install-mingw.sh - if: success() && !env.SKIP_JOB - name: install ninja run: src/ci/scripts/install-ninja.sh - if: success() && !env.SKIP_JOB - name: enable ipv6 on Docker run: src/ci/scripts/enable-docker-ipv6.sh - if: success() && !env.SKIP_JOB - name: disable git crlf conversion run: src/ci/scripts/disable-git-crlf-conversion.sh - if: success() && !env.SKIP_JOB - name: ensure line endings are correct run: src/ci/scripts/verify-line-endings.sh - if: success() && !env.SKIP_JOB - name: ensure backported commits are in upstream branches run: src/ci/scripts/verify-backported-commits.sh - if: success() && !env.SKIP_JOB - name: ensure the stable version number is correct run: src/ci/scripts/verify-stable-version-number.sh - if: success() && !env.SKIP_JOB - name: run the build run: src/ci/scripts/run-build-from-ci.sh 2>&1 env: AWS_ACCESS_KEY_ID: "${{ env.CACHES_AWS_ACCESS_KEY_ID }}" AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }}" TOOLSTATE_REPO_ACCESS_TOKEN: "${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}" - if: success() && !env.SKIP_JOB - name: create github artifacts run: src/ci/scripts/create-doc-artifacts.sh - if: success() && !env.SKIP_JOB - name: upload artifacts to github uses: actions/upload-artifact@v4 with: @@ -171,13 +146,12 @@ jobs: path: obj/artifacts/doc if-no-files-found: ignore retention-days: 5 - if: success() && !env.SKIP_JOB - name: upload artifacts to S3 run: src/ci/scripts/upload-artifacts.sh env: AWS_ACCESS_KEY_ID: "${{ env.ARTIFACTS_AWS_ACCESS_KEY_ID }}" AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.ARTIFACTS_AWS_ACCESS_KEY_ID)] }}" - if: "success() && !env.SKIP_JOB && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1')" + if: "success() && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1')" master: name: master runs-on: ubuntu-latest @@ -202,7 +176,6 @@ jobs: shell: bash env: TOOLSTATE_REPO_ACCESS_TOKEN: "${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}" - if: success() && !env.SKIP_JOB try-success: needs: - job diff --git a/Cargo.lock b/Cargo.lock index 552b446a1e753..8a9701acae11f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3343,6 +3343,7 @@ version = "0.0.0" dependencies = [ "object 0.34.0", "regex", + "similar", "wasmparser", ] @@ -5138,6 +5139,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "similar" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa42c91313f1d05da9b26f267f931cf178d4aba455b4c4622dd7355eb80c6640" + [[package]] name = "siphasher" version = "0.3.11" diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 727c6bc82fef9..af246e3137187 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2786,6 +2786,7 @@ pub enum AttrKind { #[derive(Clone, Encodable, Decodable, Debug)] pub struct NormalAttr { pub item: AttrItem, + // Tokens for the full attribute, e.g. `#[foo]`, `#![bar]`. pub tokens: Option, } @@ -2802,6 +2803,7 @@ impl NormalAttr { pub struct AttrItem { pub path: Path, pub args: AttrArgs, + // Tokens for the meta item, e.g. just the `foo` within `#[foo]` or `#![foo]`. pub tokens: Option, } diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 5e3fc7e335775..0f12fd3197520 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -298,7 +298,10 @@ impl MetaItem { } pub fn value_str(&self) -> Option { - self.kind.value_str() + match &self.kind { + MetaItemKind::NameValue(v) => v.kind.str(), + _ => None, + } } fn from_tokens<'a, I>(tokens: &mut iter::Peekable) -> Option @@ -362,13 +365,6 @@ impl MetaItem { } impl MetaItemKind { - pub fn value_str(&self) -> Option { - match self { - MetaItemKind::NameValue(v) => v.kind.str(), - _ => None, - } - } - fn list_from_tokens(tokens: TokenStream) -> Option> { let mut tokens = tokens.trees().peekable(); let mut result = ThinVec::new(); @@ -468,8 +464,9 @@ impl NestedMetaItem { self.meta_item().and_then(|meta_item| meta_item.meta_item_list()) } - /// Returns a name and single literal value tuple of the `MetaItem`. - pub fn name_value_literal(&self) -> Option<(Symbol, &MetaItemLit)> { + /// If it's a singleton list of the form `foo(lit)`, returns the `foo` and + /// the `lit`. + pub fn singleton_lit_list(&self) -> Option<(Symbol, &MetaItemLit)> { self.meta_item().and_then(|meta_item| { meta_item.meta_item_list().and_then(|meta_item_list| { if meta_item_list.len() == 1 diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 7dbfb7c736454..1cceca33c1750 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -335,7 +335,7 @@ pub fn visit_clobber(t: &mut T, f: impl FnOnce(T) -> T) { // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. #[inline] -pub fn visit_vec(elems: &mut Vec, mut visit_elem: F) +fn visit_vec(elems: &mut Vec, mut visit_elem: F) where F: FnMut(&mut T), { @@ -346,7 +346,7 @@ where // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. #[inline] -pub fn visit_thin_vec(elems: &mut ThinVec, mut visit_elem: F) +fn visit_thin_vec(elems: &mut ThinVec, mut visit_elem: F) where F: FnMut(&mut T), { @@ -357,7 +357,7 @@ where // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. #[inline] -pub fn visit_opt(opt: &mut Option, mut visit_elem: F) +fn visit_opt(opt: &mut Option, mut visit_elem: F) where F: FnMut(&mut T), { @@ -367,36 +367,37 @@ where } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_attrs(attrs: &mut AttrVec, vis: &mut T) { +fn visit_attrs(attrs: &mut AttrVec, vis: &mut T) { for attr in attrs.iter_mut() { vis.visit_attribute(attr); } } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_exprs(exprs: &mut Vec>, vis: &mut T) { +#[allow(unused)] +fn visit_exprs(exprs: &mut Vec>, vis: &mut T) { exprs.flat_map_in_place(|expr| vis.filter_map_expr(expr)) } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_thin_exprs(exprs: &mut ThinVec>, vis: &mut T) { +fn visit_thin_exprs(exprs: &mut ThinVec>, vis: &mut T) { exprs.flat_map_in_place(|expr| vis.filter_map_expr(expr)) } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_bounds(bounds: &mut GenericBounds, vis: &mut T) { +fn visit_bounds(bounds: &mut GenericBounds, vis: &mut T) { visit_vec(bounds, |bound| vis.visit_param_bound(bound)); } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_fn_sig(FnSig { header, decl, span }: &mut FnSig, vis: &mut T) { +fn visit_fn_sig(FnSig { header, decl, span }: &mut FnSig, vis: &mut T) { vis.visit_fn_header(header); vis.visit_fn_decl(decl); vis.visit_span(span); } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_attr_args(args: &mut AttrArgs, vis: &mut T) { +fn visit_attr_args(args: &mut AttrArgs, vis: &mut T) { match args { AttrArgs::Empty => {} AttrArgs::Delimited(args) => visit_delim_args(args, vis), @@ -411,7 +412,7 @@ pub fn visit_attr_args(args: &mut AttrArgs, vis: &mut T) { } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_delim_args(args: &mut DelimArgs, vis: &mut T) { +fn visit_delim_args(args: &mut DelimArgs, vis: &mut T) { let DelimArgs { dspan, delim: _, tokens } = args; visit_delim_span(dspan, vis); visit_tts(tokens, vis); @@ -435,7 +436,7 @@ pub fn noop_flat_map_pat_field( smallvec![fp] } -pub fn noop_visit_use_tree(use_tree: &mut UseTree, vis: &mut T) { +fn noop_visit_use_tree(use_tree: &mut UseTree, vis: &mut T) { let UseTree { prefix, kind, span } = use_tree; vis.visit_path(prefix); match kind { @@ -462,7 +463,7 @@ pub fn noop_flat_map_arm(mut arm: Arm, vis: &mut T) -> SmallVec<[ smallvec![arm] } -pub fn noop_visit_constraint( +fn noop_visit_constraint( AssocConstraint { id, ident, gen_args, kind, span }: &mut AssocConstraint, vis: &mut T, ) { @@ -541,7 +542,7 @@ pub fn noop_visit_ty(ty: &mut P, vis: &mut T) { visit_lazy_tts(tokens, vis); } -pub fn noop_visit_foreign_mod(foreign_mod: &mut ForeignMod, vis: &mut T) { +fn noop_visit_foreign_mod(foreign_mod: &mut ForeignMod, vis: &mut T) { let ForeignMod { unsafety, abi: _, items } = foreign_mod; visit_unsafety(unsafety, vis); items.flat_map_in_place(|item| vis.flat_map_foreign_item(item)); @@ -562,11 +563,11 @@ pub fn noop_flat_map_variant( smallvec![variant] } -pub fn noop_visit_ident(Ident { name: _, span }: &mut Ident, vis: &mut T) { +fn noop_visit_ident(Ident { name: _, span }: &mut Ident, vis: &mut T) { vis.visit_span(span); } -pub fn noop_visit_path(Path { segments, span, tokens }: &mut Path, vis: &mut T) { +fn noop_visit_path(Path { segments, span, tokens }: &mut Path, vis: &mut T) { vis.visit_span(span); for PathSegment { ident, id, args } in segments { vis.visit_ident(ident); @@ -576,7 +577,7 @@ pub fn noop_visit_path(Path { segments, span, tokens }: &mut Path visit_lazy_tts(tokens, vis); } -pub fn noop_visit_qself(qself: &mut Option>, vis: &mut T) { +fn noop_visit_qself(qself: &mut Option>, vis: &mut T) { visit_opt(qself, |qself| { let QSelf { ty, path_span, position: _ } = &mut **qself; vis.visit_ty(ty); @@ -584,14 +585,14 @@ pub fn noop_visit_qself(qself: &mut Option>, vis: &mut T }) } -pub fn noop_visit_generic_args(generic_args: &mut GenericArgs, vis: &mut T) { +fn noop_visit_generic_args(generic_args: &mut GenericArgs, vis: &mut T) { match generic_args { GenericArgs::AngleBracketed(data) => vis.visit_angle_bracketed_parameter_data(data), GenericArgs::Parenthesized(data) => vis.visit_parenthesized_parameter_data(data), } } -pub fn noop_visit_generic_arg(arg: &mut GenericArg, vis: &mut T) { +fn noop_visit_generic_arg(arg: &mut GenericArg, vis: &mut T) { match arg { GenericArg::Lifetime(lt) => vis.visit_lifetime(lt), GenericArg::Type(ty) => vis.visit_ty(ty), @@ -599,7 +600,7 @@ pub fn noop_visit_generic_arg(arg: &mut GenericArg, vis: &mut T) } } -pub fn noop_visit_angle_bracketed_parameter_data( +fn noop_visit_angle_bracketed_parameter_data( data: &mut AngleBracketedArgs, vis: &mut T, ) { @@ -611,7 +612,7 @@ pub fn noop_visit_angle_bracketed_parameter_data( vis.visit_span(span); } -pub fn noop_visit_parenthesized_parameter_data( +fn noop_visit_parenthesized_parameter_data( args: &mut ParenthesizedArgs, vis: &mut T, ) { @@ -621,7 +622,7 @@ pub fn noop_visit_parenthesized_parameter_data( vis.visit_span(span); } -pub fn noop_visit_local(local: &mut P, vis: &mut T) { +fn noop_visit_local(local: &mut P, vis: &mut T) { let Local { id, pat, ty, kind, span, colon_sp, attrs, tokens } = local.deref_mut(); vis.visit_id(id); vis.visit_pat(pat); @@ -642,7 +643,7 @@ pub fn noop_visit_local(local: &mut P, vis: &mut T) { visit_lazy_tts(tokens, vis); } -pub fn noop_visit_attribute(attr: &mut Attribute, vis: &mut T) { +fn noop_visit_attribute(attr: &mut Attribute, vis: &mut T) { let Attribute { kind, id: _, style: _, span } = attr; match kind { AttrKind::Normal(normal) => { @@ -658,25 +659,25 @@ pub fn noop_visit_attribute(attr: &mut Attribute, vis: &mut T) { vis.visit_span(span); } -pub fn noop_visit_mac(mac: &mut MacCall, vis: &mut T) { +fn noop_visit_mac(mac: &mut MacCall, vis: &mut T) { let MacCall { path, args } = mac; vis.visit_path(path); visit_delim_args(args, vis); } -pub fn noop_visit_macro_def(macro_def: &mut MacroDef, vis: &mut T) { +fn noop_visit_macro_def(macro_def: &mut MacroDef, vis: &mut T) { let MacroDef { body, macro_rules: _ } = macro_def; visit_delim_args(body, vis); } -pub fn noop_visit_meta_list_item(li: &mut NestedMetaItem, vis: &mut T) { +fn noop_visit_meta_list_item(li: &mut NestedMetaItem, vis: &mut T) { match li { NestedMetaItem::MetaItem(mi) => vis.visit_meta_item(mi), NestedMetaItem::Lit(_lit) => {} } } -pub fn noop_visit_meta_item(mi: &mut MetaItem, vis: &mut T) { +fn noop_visit_meta_item(mi: &mut MetaItem, vis: &mut T) { let MetaItem { path: _, kind, span } = mi; match kind { MetaItemKind::Word => {} @@ -697,7 +698,7 @@ pub fn noop_flat_map_param(mut param: Param, vis: &mut T) -> Smal } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_attr_tt(tt: &mut AttrTokenTree, vis: &mut T) { +fn visit_attr_tt(tt: &mut AttrTokenTree, vis: &mut T) { match tt { AttrTokenTree::Token(token, _) => { visit_token(token, vis); @@ -724,7 +725,7 @@ pub fn visit_attr_tt(tt: &mut AttrTokenTree, vis: &mut T) { } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_tt(tt: &mut TokenTree, vis: &mut T) { +fn visit_tt(tt: &mut TokenTree, vis: &mut T) { match tt { TokenTree::Token(token, _) => { visit_token(token, vis); @@ -738,24 +739,21 @@ pub fn visit_tt(tt: &mut TokenTree, vis: &mut T) { } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_tts(TokenStream(tts): &mut TokenStream, vis: &mut T) { +fn visit_tts(TokenStream(tts): &mut TokenStream, vis: &mut T) { if T::VISIT_TOKENS && !tts.is_empty() { let tts = Lrc::make_mut(tts); visit_vec(tts, |tree| visit_tt(tree, vis)); } } -pub fn visit_attr_tts(AttrTokenStream(tts): &mut AttrTokenStream, vis: &mut T) { +fn visit_attr_tts(AttrTokenStream(tts): &mut AttrTokenStream, vis: &mut T) { if T::VISIT_TOKENS && !tts.is_empty() { let tts = Lrc::make_mut(tts); visit_vec(tts, |tree| visit_attr_tt(tree, vis)); } } -pub fn visit_lazy_tts_opt_mut( - lazy_tts: Option<&mut LazyAttrTokenStream>, - vis: &mut T, -) { +fn visit_lazy_tts_opt_mut(lazy_tts: Option<&mut LazyAttrTokenStream>, vis: &mut T) { if T::VISIT_TOKENS { if let Some(lazy_tts) = lazy_tts { let mut tts = lazy_tts.to_attr_token_stream(); @@ -765,7 +763,7 @@ pub fn visit_lazy_tts_opt_mut( } } -pub fn visit_lazy_tts(lazy_tts: &mut Option, vis: &mut T) { +fn visit_lazy_tts(lazy_tts: &mut Option, vis: &mut T) { visit_lazy_tts_opt_mut(lazy_tts.as_mut(), vis); } @@ -818,7 +816,7 @@ pub fn visit_token(t: &mut Token, vis: &mut T) { // contain multiple items, but decided against it when I looked at // `parse_item_or_view_item` and tried to figure out what I would do with // multiple items there.... -pub fn visit_nonterminal(nt: &mut token::Nonterminal, vis: &mut T) { +fn visit_nonterminal(nt: &mut token::Nonterminal, vis: &mut T) { match nt { token::NtItem(item) => visit_clobber(item, |item| { // This is probably okay, because the only visitors likely to @@ -851,7 +849,7 @@ pub fn visit_nonterminal(nt: &mut token::Nonterminal, vis: &mut T } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_defaultness(defaultness: &mut Defaultness, vis: &mut T) { +fn visit_defaultness(defaultness: &mut Defaultness, vis: &mut T) { match defaultness { Defaultness::Default(span) => vis.visit_span(span), Defaultness::Final => {} @@ -859,7 +857,7 @@ pub fn visit_defaultness(defaultness: &mut Defaultness, vis: &mut } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_unsafety(unsafety: &mut Unsafe, vis: &mut T) { +fn visit_unsafety(unsafety: &mut Unsafe, vis: &mut T) { match unsafety { Unsafe::Yes(span) => vis.visit_span(span), Unsafe::No => {} @@ -867,7 +865,7 @@ pub fn visit_unsafety(unsafety: &mut Unsafe, vis: &mut T) { } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_polarity(polarity: &mut ImplPolarity, vis: &mut T) { +fn visit_polarity(polarity: &mut ImplPolarity, vis: &mut T) { match polarity { ImplPolarity::Positive => {} ImplPolarity::Negative(span) => vis.visit_span(span), @@ -875,14 +873,14 @@ pub fn visit_polarity(polarity: &mut ImplPolarity, vis: &mut T) { } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_constness(constness: &mut Const, vis: &mut T) { +fn visit_constness(constness: &mut Const, vis: &mut T) { match constness { Const::Yes(span) => vis.visit_span(span), Const::No => {} } } -pub fn noop_visit_closure_binder(binder: &mut ClosureBinder, vis: &mut T) { +fn noop_visit_closure_binder(binder: &mut ClosureBinder, vis: &mut T) { match binder { ClosureBinder::NotPresent => {} ClosureBinder::For { span: _, generic_params } => { @@ -891,7 +889,7 @@ pub fn noop_visit_closure_binder(binder: &mut ClosureBinder, vis: } } -pub fn noop_visit_coroutine_kind(coroutine_kind: &mut CoroutineKind, vis: &mut T) { +fn noop_visit_coroutine_kind(coroutine_kind: &mut CoroutineKind, vis: &mut T) { match coroutine_kind { CoroutineKind::Async { span, closure_id, return_impl_trait_id } | CoroutineKind::Gen { span, closure_id, return_impl_trait_id } @@ -903,27 +901,27 @@ pub fn noop_visit_coroutine_kind(coroutine_kind: &mut CoroutineKi } } -pub fn noop_visit_fn_decl(decl: &mut P, vis: &mut T) { +fn noop_visit_fn_decl(decl: &mut P, vis: &mut T) { let FnDecl { inputs, output } = decl.deref_mut(); inputs.flat_map_in_place(|param| vis.flat_map_param(param)); noop_visit_fn_ret_ty(output, vis); } -pub fn noop_visit_fn_ret_ty(fn_ret_ty: &mut FnRetTy, vis: &mut T) { +fn noop_visit_fn_ret_ty(fn_ret_ty: &mut FnRetTy, vis: &mut T) { match fn_ret_ty { FnRetTy::Default(span) => vis.visit_span(span), FnRetTy::Ty(ty) => vis.visit_ty(ty), } } -pub fn noop_visit_param_bound(pb: &mut GenericBound, vis: &mut T) { +fn noop_visit_param_bound(pb: &mut GenericBound, vis: &mut T) { match pb { GenericBound::Trait(ty, _modifier) => vis.visit_poly_trait_ref(ty), GenericBound::Outlives(lifetime) => noop_visit_lifetime(lifetime, vis), } } -pub fn noop_visit_precise_capturing_arg(arg: &mut PreciseCapturingArg, vis: &mut T) { +fn noop_visit_precise_capturing_arg(arg: &mut PreciseCapturingArg, vis: &mut T) { match arg { PreciseCapturingArg::Lifetime(lt) => { vis.visit_lifetime(lt); @@ -960,7 +958,7 @@ pub fn noop_flat_map_generic_param( smallvec![param] } -pub fn noop_visit_label(Label { ident }: &mut Label, vis: &mut T) { +fn noop_visit_label(Label { ident }: &mut Label, vis: &mut T) { vis.visit_ident(ident); } @@ -969,20 +967,20 @@ fn noop_visit_lifetime(Lifetime { id, ident }: &mut Lifetime, vis vis.visit_ident(ident); } -pub fn noop_visit_generics(generics: &mut Generics, vis: &mut T) { +fn noop_visit_generics(generics: &mut Generics, vis: &mut T) { let Generics { params, where_clause, span } = generics; params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); vis.visit_where_clause(where_clause); vis.visit_span(span); } -pub fn noop_visit_where_clause(wc: &mut WhereClause, vis: &mut T) { +fn noop_visit_where_clause(wc: &mut WhereClause, vis: &mut T) { let WhereClause { has_where_token: _, predicates, span } = wc; visit_thin_vec(predicates, |predicate| vis.visit_where_predicate(predicate)); vis.visit_span(span); } -pub fn noop_visit_where_predicate(pred: &mut WherePredicate, vis: &mut T) { +fn noop_visit_where_predicate(pred: &mut WherePredicate, vis: &mut T) { match pred { WherePredicate::BoundPredicate(bp) => { let WhereBoundPredicate { span, bound_generic_params, bounded_ty, bounds } = bp; @@ -1006,7 +1004,7 @@ pub fn noop_visit_where_predicate(pred: &mut WherePredicate, vis: } } -pub fn noop_visit_variant_data(vdata: &mut VariantData, vis: &mut T) { +fn noop_visit_variant_data(vdata: &mut VariantData, vis: &mut T) { match vdata { VariantData::Struct { fields, .. } => { fields.flat_map_in_place(|field| vis.flat_map_field_def(field)); @@ -1019,12 +1017,12 @@ pub fn noop_visit_variant_data(vdata: &mut VariantData, vis: &mut } } -pub fn noop_visit_trait_ref(TraitRef { path, ref_id }: &mut TraitRef, vis: &mut T) { +fn noop_visit_trait_ref(TraitRef { path, ref_id }: &mut TraitRef, vis: &mut T) { vis.visit_path(path); vis.visit_id(ref_id); } -pub fn noop_visit_poly_trait_ref(p: &mut PolyTraitRef, vis: &mut T) { +fn noop_visit_poly_trait_ref(p: &mut PolyTraitRef, vis: &mut T) { let PolyTraitRef { bound_generic_params, trait_ref, span } = p; bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); vis.visit_trait_ref(trait_ref); @@ -1058,7 +1056,7 @@ pub fn noop_flat_map_expr_field( smallvec![f] } -pub fn noop_visit_mt(MutTy { ty, mutbl: _ }: &mut MutTy, vis: &mut T) { +fn noop_visit_mt(MutTy { ty, mutbl: _ }: &mut MutTy, vis: &mut T) { vis.visit_ty(ty); } @@ -1225,7 +1223,7 @@ fn visit_const_item( visit_opt(expr, |expr| visitor.visit_expr(expr)); } -pub fn noop_visit_fn_header(header: &mut FnHeader, vis: &mut T) { +fn noop_visit_fn_header(header: &mut FnHeader, vis: &mut T) { let FnHeader { unsafety, coroutine_kind, constness, ext: _ } = header; visit_constness(constness, vis); coroutine_kind.as_mut().map(|coroutine_kind| vis.visit_coroutine_kind(coroutine_kind)); @@ -1343,12 +1341,12 @@ pub fn noop_visit_pat(pat: &mut P, vis: &mut T) { visit_lazy_tts(tokens, vis); } -pub fn noop_visit_anon_const(AnonConst { id, value }: &mut AnonConst, vis: &mut T) { +fn noop_visit_anon_const(AnonConst { id, value }: &mut AnonConst, vis: &mut T) { vis.visit_id(id); vis.visit_expr(value); } -pub fn noop_visit_inline_asm(asm: &mut InlineAsm, vis: &mut T) { +fn noop_visit_inline_asm(asm: &mut InlineAsm, vis: &mut T) { for (op, _) in &mut asm.operands { match op { InlineAsmOperand::In { expr, .. } @@ -1368,7 +1366,7 @@ pub fn noop_visit_inline_asm(asm: &mut InlineAsm, vis: &mut T) { } } -pub fn noop_visit_inline_asm_sym( +fn noop_visit_inline_asm_sym( InlineAsmSym { id, qself, path }: &mut InlineAsmSym, vis: &mut T, ) { @@ -1377,7 +1375,7 @@ pub fn noop_visit_inline_asm_sym( vis.visit_path(path); } -pub fn noop_visit_format_args(fmt: &mut FormatArgs, vis: &mut T) { +fn noop_visit_format_args(fmt: &mut FormatArgs, vis: &mut T) { for arg in fmt.arguments.all_args_mut() { if let FormatArgumentKind::Named(name) = &mut arg.kind { vis.visit_ident(name); @@ -1594,10 +1592,7 @@ pub fn noop_flat_map_stmt( stmts } -pub fn noop_flat_map_stmt_kind( - kind: StmtKind, - vis: &mut T, -) -> SmallVec<[StmtKind; 1]> { +fn noop_flat_map_stmt_kind(kind: StmtKind, vis: &mut T) -> SmallVec<[StmtKind; 1]> { match kind { StmtKind::Let(mut local) => smallvec![StmtKind::Let({ vis.visit_local(&mut local); @@ -1617,7 +1612,7 @@ pub fn noop_flat_map_stmt_kind( } } -pub fn noop_visit_vis(visibility: &mut Visibility, vis: &mut T) { +fn noop_visit_vis(visibility: &mut Visibility, vis: &mut T) { match &mut visibility.kind { VisibilityKind::Public | VisibilityKind::Inherited => {} VisibilityKind::Restricted { path, id, shorthand: _ } => { @@ -1628,7 +1623,7 @@ pub fn noop_visit_vis(visibility: &mut Visibility, vis: &mut T) { vis.visit_span(&mut visibility.span); } -pub fn noop_visit_capture_by(capture_by: &mut CaptureBy, vis: &mut T) { +fn noop_visit_capture_by(capture_by: &mut CaptureBy, vis: &mut T) { match capture_by { CaptureBy::Ref => {} CaptureBy::Value { move_kw } => { diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 880f92bbe7bdc..08d65a5ffa588 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -140,9 +140,8 @@ impl fmt::Debug for LazyAttrTokenStream { } impl Encodable for LazyAttrTokenStream { - fn encode(&self, s: &mut S) { - // Used by AST json printing. - Encodable::encode(&self.to_attr_token_stream(), s); + fn encode(&self, _s: &mut S) { + panic!("Attempted to encode LazyAttrTokenStream"); } } diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 439f13e763570..1c2077372e1cc 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -986,7 +986,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec { recognised = true; acc.push(h); } - } else if let Some((name, value)) = item.name_value_literal() { + } else if let Some((name, value)) = item.singleton_lit_list() { let mut literal_error = None; let mut err_span = item.span(); if name == sym::align { diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 9c9e134f0337e..c28b0d644e675 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -435,7 +435,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { sym::repr => { codegen_fn_attrs.alignment = if let Some(items) = attr.meta_item_list() && let [item] = items.as_slice() - && let Some((sym::align, literal)) = item.name_value_literal() + && let Some((sym::align, literal)) = item.singleton_lit_list() { rustc_attr::parse_alignment(&literal.kind) .map_err(|msg| { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index d51080589481b..6a556e2a1f517 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1,5 +1,4 @@ use crate::config::*; - use crate::search_paths::SearchPath; use crate::utils::NativeLib; use crate::{lint, EarlyDiagCtxt}; @@ -8,20 +7,17 @@ use rustc_data_structures::profiling::TimePassesFormat; use rustc_data_structures::stable_hasher::Hash64; use rustc_errors::ColorConfig; use rustc_errors::{LanguageIdentifier, TerminalUrl}; +use rustc_feature::UnstableFeatures; +use rustc_span::edition::Edition; +use rustc_span::RealFileName; +use rustc_span::SourceFileHashAlgorithm; use rustc_target::spec::{ CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, SanitizerSet, WasmCAbi, }; use rustc_target::spec::{ RelocModel, RelroLevel, SplitDebuginfo, StackProtector, TargetTriple, TlsModel, }; - -use rustc_feature::UnstableFeatures; -use rustc_span::edition::Edition; -use rustc_span::RealFileName; -use rustc_span::SourceFileHashAlgorithm; - use std::collections::BTreeMap; - use std::hash::{DefaultHasher, Hasher}; use std::num::{IntErrorKind, NonZero}; use std::path::PathBuf; @@ -118,8 +114,8 @@ top_level_options!( /// incremental compilation cache before proceeding. /// /// - `[TRACKED_NO_CRATE_HASH]` - /// Same as `[TRACKED]`, but will not affect the crate hash. This is useful for options that only - /// affect the incremental cache. + /// Same as `[TRACKED]`, but will not affect the crate hash. This is useful for options that + /// only affect the incremental cache. /// /// - `[UNTRACKED]` /// Incremental compilation is not influenced by this option. diff --git a/src/ci/github-actions/calculate-job-matrix.py b/src/ci/github-actions/calculate-job-matrix.py index c24cefa8d8962..124c22bd979f1 100755 --- a/src/ci/github-actions/calculate-job-matrix.py +++ b/src/ci/github-actions/calculate-job-matrix.py @@ -17,10 +17,13 @@ import yaml +CI_DIR = Path(__file__).absolute().parent.parent JOBS_YAML_PATH = Path(__file__).absolute().parent / "jobs.yml" +Job = Dict[str, Any] -def name_jobs(jobs: List[Dict], prefix: str) -> List[Dict]: + +def name_jobs(jobs: List[Dict], prefix: str) -> List[Job]: """ Add a `name` attribute to each job, based on its image and the given `prefix`. """ @@ -29,7 +32,7 @@ def name_jobs(jobs: List[Dict], prefix: str) -> List[Dict]: return jobs -def add_base_env(jobs: List[Dict], environment: Dict[str, str]) -> List[Dict]: +def add_base_env(jobs: List[Job], environment: Dict[str, str]) -> List[Job]: """ Prepends `environment` to the `env` attribute of each job. The `env` of each job has higher precedence than `environment`. @@ -77,7 +80,7 @@ def find_job_type(ctx: GitHubCtx) -> Optional[JobType]: return None -def calculate_jobs(job_type: JobType, job_data: Dict[str, Any]) -> List[Dict[str, Any]]: +def calculate_jobs(job_type: JobType, job_data: Dict[str, Any]) -> List[Job]: if job_type == JobType.PR: return add_base_env(name_jobs(job_data["pr"], "PR"), job_data["envs"]["pr"]) elif job_type == JobType.Try: @@ -88,6 +91,13 @@ def calculate_jobs(job_type: JobType, job_data: Dict[str, Any]) -> List[Dict[str return [] +def skip_jobs(jobs: List[Dict[str, Any]], channel: str) -> List[Job]: + """ + Skip CI jobs that are not supposed to be executed on the given `channel`. + """ + return [j for j in jobs if j.get("only_on_channel", channel) == channel] + + def get_github_ctx() -> GitHubCtx: return GitHubCtx( event_name=os.environ["GITHUB_EVENT_NAME"], @@ -107,9 +117,13 @@ def get_github_ctx() -> GitHubCtx: job_type = find_job_type(github_ctx) logging.info(f"Job type: {job_type}") + with open(CI_DIR / "channel") as f: + channel = f.read().strip() + jobs = [] if job_type is not None: jobs = calculate_jobs(job_type, data) + jobs = skip_jobs(jobs, channel) logging.info(f"Output:\n{yaml.dump(jobs, indent=4)}") print(f"jobs={json.dumps(jobs)}") diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 19d6b517552f4..bc4b1b815cf37 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -107,9 +107,6 @@ x--expand-yaml-anchors--remove: - &job-aarch64-linux os: [self-hosted, ARM64, linux] - - &step - if: success() && !env.SKIP_JOB - - &base-ci-job defaults: run: @@ -151,7 +148,7 @@ x--expand-yaml-anchors--remove: run: echo "[CI_PR_NUMBER=$num]" env: num: ${{ github.event.number }} - if: success() && !env.SKIP_JOB && github.event_name == 'pull_request' + if: success() && github.event_name == 'pull_request' - name: add extra environment variables run: src/ci/scripts/setup-environment.sh @@ -161,71 +158,51 @@ x--expand-yaml-anchors--remove: # are passed to the `setup-environment.sh` script encoded in JSON, # which then uses log commands to actually set them. EXTRA_VARIABLES: ${{ toJson(matrix.env) }} - <<: *step - - - name: decide whether to skip this job - run: src/ci/scripts/should-skip-this.sh - <<: *step - name: ensure the channel matches the target branch run: src/ci/scripts/verify-channel.sh - <<: *step - name: collect CPU statistics run: src/ci/scripts/collect-cpu-stats.sh - <<: *step - name: show the current environment run: src/ci/scripts/dump-environment.sh - <<: *step - name: install awscli run: src/ci/scripts/install-awscli.sh - <<: *step - name: install sccache run: src/ci/scripts/install-sccache.sh - <<: *step - name: select Xcode run: src/ci/scripts/select-xcode.sh - <<: *step - name: install clang run: src/ci/scripts/install-clang.sh - <<: *step - name: install tidy run: src/ci/scripts/install-tidy.sh - <<: *step - name: install WIX run: src/ci/scripts/install-wix.sh - <<: *step - name: disable git crlf conversion run: src/ci/scripts/disable-git-crlf-conversion.sh - <<: *step - name: checkout submodules run: src/ci/scripts/checkout-submodules.sh - <<: *step - name: install MSYS2 run: src/ci/scripts/install-msys2.sh - <<: *step - name: install MinGW run: src/ci/scripts/install-mingw.sh - <<: *step - name: install ninja run: src/ci/scripts/install-ninja.sh - <<: *step - name: enable ipv6 on Docker run: src/ci/scripts/enable-docker-ipv6.sh - <<: *step # Disable automatic line ending conversion (again). On Windows, when we're # installing dependencies, something switches the git configuration directory or @@ -234,19 +211,15 @@ x--expand-yaml-anchors--remove: # appropriate line endings. - name: disable git crlf conversion run: src/ci/scripts/disable-git-crlf-conversion.sh - <<: *step - name: ensure line endings are correct run: src/ci/scripts/verify-line-endings.sh - <<: *step - name: ensure backported commits are in upstream branches run: src/ci/scripts/verify-backported-commits.sh - <<: *step - name: ensure the stable version number is correct run: src/ci/scripts/verify-stable-version-number.sh - <<: *step - name: run the build # Redirect stderr to stdout to avoid reordering the two streams in the GHA logs. @@ -255,11 +228,9 @@ x--expand-yaml-anchors--remove: AWS_ACCESS_KEY_ID: ${{ env.CACHES_AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }} TOOLSTATE_REPO_ACCESS_TOKEN: ${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }} - <<: *step - name: create github artifacts run: src/ci/scripts/create-doc-artifacts.sh - <<: *step - name: upload artifacts to github uses: actions/upload-artifact@v4 @@ -269,7 +240,6 @@ x--expand-yaml-anchors--remove: path: obj/artifacts/doc if-no-files-found: ignore retention-days: 5 - <<: *step - name: upload artifacts to S3 run: src/ci/scripts/upload-artifacts.sh @@ -281,8 +251,7 @@ x--expand-yaml-anchors--remove: # adding the condition is helpful as this way CI will not silently skip # deploying artifacts from a dist builder if the variables are misconfigured, # erroring about invalid credentials instead. - if: success() && !env.SKIP_JOB && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1') - <<: *step + if: success() && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1') # These snippets are used by the try-success, try-failure, auto-success and auto-failure jobs. # Check out their documentation for more information on why they're needed. @@ -399,7 +368,6 @@ jobs: shell: bash env: TOOLSTATE_REPO_ACCESS_TOKEN: ${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }} - <<: *step # These jobs don't actually test anything, but they're used to tell bors the # build completed, as there is no practical way to detect when a workflow is diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index ec58bd0924e86..df6c5d6079d1a 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -79,7 +79,7 @@ pr: <<: *job-linux-16c # Jobs that run when you perform a try build (@bors try) -# These jobs automatically inherit envs.production, to avoid repeating +# These jobs automatically inherit envs.try, to avoid repeating # it in each job definition. try: - image: dist-x86_64-linux @@ -88,7 +88,7 @@ try: <<: *job-linux-16c # Main CI jobs that have to be green to merge a commit into master -# These jobs automatically inherit envs.production, to avoid repeating +# These jobs automatically inherit envs.auto, to avoid repeating # it in each job definition. auto: ############################# @@ -200,24 +200,23 @@ auto: # channel name on the output), and this builder prevents landing # changes that would result in broken builds after a promotion. - image: x86_64-gnu-stable + # Only run this job on the nightly channel. Running this on beta + # could cause failures when `dev: 1` in `stage0.txt`, and running + # this on stable is useless. + only_on_channel: nightly env: IMAGE: x86_64-gnu RUST_CI_OVERRIDE_RELEASE_CHANNEL: stable - # Only run this job on the nightly channel. Running this on beta - # could cause failures when `dev: 1` in `stage0.txt`, and running - # this on stable is useless. - CI_ONLY_WHEN_CHANNEL: nightly <<: *job-linux-4c - image: x86_64-gnu-aux <<: *job-linux-4c - image: x86_64-gnu-integration - env: - # Only run this job on the nightly channel. Fuchsia requires - # nightly features to compile, and this job would fail if - # executed on beta and stable. - CI_ONLY_WHEN_CHANNEL: nightly + # Only run this job on the nightly channel. Fuchsia requires + # nightly features to compile, and this job would fail if + # executed on beta and stable. + only_on_channel: nightly <<: *job-linux-8c - image: x86_64-gnu-debug diff --git a/src/ci/scripts/should-skip-this.sh b/src/ci/scripts/should-skip-this.sh deleted file mode 100755 index 48127166ad080..0000000000000 --- a/src/ci/scripts/should-skip-this.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -# Set the SKIP_JOB environment variable if this job is not supposed to run on the current builder. - -set -euo pipefail -IFS=$'\n\t' - -source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" - -if [[ -n "${CI_ONLY_WHEN_CHANNEL-}" ]]; then - if [[ "${CI_ONLY_WHEN_CHANNEL}" = "$(cat src/ci/channel)" ]]; then - echo "The channel is the expected one" - else - echo "Not executing this job as the channel is not the expected one" - ciCommandSetEnv SKIP_JOB 1 - exit 0 - fi -fi - - -echo "Executing the job since there is no skip rule preventing the execution" -exit 0 diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml index 3ea35c7940c21..61a24c97e77a2 100644 --- a/src/tools/run-make-support/Cargo.toml +++ b/src/tools/run-make-support/Cargo.toml @@ -5,5 +5,6 @@ edition = "2021" [dependencies] object = "0.34.0" +similar = "2.5.0" wasmparser = "0.118.2" regex = "1.8" # 1.8 to avoid memchr 2.6.0, as 2.5.0 is pinned in the workspace diff --git a/src/tools/run-make-support/src/diff/mod.rs b/src/tools/run-make-support/src/diff/mod.rs new file mode 100644 index 0000000000000..54532c6e35bab --- /dev/null +++ b/src/tools/run-make-support/src/diff/mod.rs @@ -0,0 +1,81 @@ +use similar::TextDiff; +use std::path::Path; + +#[cfg(test)] +mod tests; + +pub fn diff() -> Diff { + Diff::new() +} + +#[derive(Debug)] +pub struct Diff { + expected: Option, + expected_name: Option, + actual: Option, + actual_name: Option, +} + +impl Diff { + /// Construct a bare `diff` invocation. + pub fn new() -> Self { + Self { expected: None, expected_name: None, actual: None, actual_name: None } + } + + /// Specify the expected output for the diff from a file. + pub fn expected_file>(&mut self, path: P) -> &mut Self { + let path = path.as_ref(); + let content = std::fs::read_to_string(path).expect("failed to read file"); + let name = path.to_string_lossy().to_string(); + + self.expected = Some(content); + self.expected_name = Some(name); + self + } + + /// Specify the expected output for the diff from a given text string. + pub fn expected_text>(&mut self, name: &str, text: T) -> &mut Self { + self.expected = Some(String::from_utf8_lossy(text.as_ref()).to_string()); + self.expected_name = Some(name.to_string()); + self + } + + /// Specify the actual output for the diff from a file. + pub fn actual_file>(&mut self, path: P) -> &mut Self { + let path = path.as_ref(); + let content = std::fs::read_to_string(path).expect("failed to read file"); + let name = path.to_string_lossy().to_string(); + + self.actual = Some(content); + self.actual_name = Some(name); + self + } + + /// Specify the actual output for the diff from a given text string. + pub fn actual_text>(&mut self, name: &str, text: T) -> &mut Self { + self.actual = Some(String::from_utf8_lossy(text.as_ref()).to_string()); + self.actual_name = Some(name.to_string()); + self + } + + /// Executes the diff process, prints any differences to the standard error. + #[track_caller] + pub fn run(&self) { + let expected = self.expected.as_ref().expect("expected text not set"); + let actual = self.actual.as_ref().expect("actual text not set"); + let expected_name = self.expected_name.as_ref().unwrap(); + let actual_name = self.actual_name.as_ref().unwrap(); + + let output = TextDiff::from_lines(expected, actual) + .unified_diff() + .header(expected_name, actual_name) + .to_string(); + + if !output.is_empty() { + panic!( + "test failed: `{}` is different from `{}`\n\n{}", + expected_name, actual_name, output + ) + } + } +} diff --git a/src/tools/run-make-support/src/diff/tests.rs b/src/tools/run-make-support/src/diff/tests.rs new file mode 100644 index 0000000000000..e6d72544b7ebc --- /dev/null +++ b/src/tools/run-make-support/src/diff/tests.rs @@ -0,0 +1,39 @@ +#[cfg(test)] +mod tests { + use crate::*; + + #[test] + fn test_diff() { + let expected = "foo\nbar\nbaz\n"; + let actual = "foo\nbar\nbaz\n"; + diff().expected_text("EXPECTED_TEXT", expected).actual_text("ACTUAL_TEXT", actual).run(); + } + + #[test] + fn test_should_panic() { + let expected = "foo\nbar\nbaz\n"; + let actual = "foo\nbaz\nbar\n"; + + let output = std::panic::catch_unwind(|| { + diff() + .expected_text("EXPECTED_TEXT", expected) + .actual_text("ACTUAL_TEXT", actual) + .run(); + }) + .unwrap_err(); + + let expected_output = "\ +test failed: `EXPECTED_TEXT` is different from `ACTUAL_TEXT` + +--- EXPECTED_TEXT ++++ ACTUAL_TEXT +@@ -1,3 +1,3 @@ + foo ++baz + bar +-baz +"; + + assert_eq!(output.downcast_ref::().unwrap(), expected_output); + } +} diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index e723e824ed6c8..76e8838d27c72 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -5,6 +5,7 @@ pub mod cc; pub mod clang; +pub mod diff; pub mod llvm_readobj; pub mod run; pub mod rustc; @@ -20,6 +21,7 @@ pub use wasmparser; pub use cc::{cc, extra_c_flags, extra_cxx_flags, Cc}; pub use clang::{clang, Clang}; +pub use diff::{diff, Diff}; pub use llvm_readobj::{llvm_readobj, LlvmReadobj}; pub use run::{run, run_fail}; pub use rustc::{aux_build, rustc, Rustc}; diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index 9bf41c6e2e9a5..ddaae3236c2b5 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -148,6 +148,13 @@ impl Rustc { self } + /// Specify the print request. + pub fn print(&mut self, request: &str) -> &mut Self { + self.cmd.arg("--print"); + self.cmd.arg(request); + self + } + /// Add an extra argument to the linker invocation, via `-Clink-arg`. pub fn link_arg(&mut self, link_arg: &str) -> &mut Self { self.cmd.arg(format!("-Clink-arg={link_arg}")); diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 93188b4fbaebd..9b3c0d0f1a570 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -189,7 +189,6 @@ run-make/no-builtins-attribute/Makefile run-make/no-builtins-lto/Makefile run-make/no-cdylib-as-rdylib/Makefile run-make/no-duplicate-libs/Makefile -run-make/no-input-file/Makefile run-make/no-intermediate-extras/Makefile run-make/obey-crate-type-flag/Makefile run-make/optimization-remarks-dir-pgo/Makefile diff --git a/tests/run-make/no-input-file/Makefile b/tests/run-make/no-input-file/Makefile deleted file mode 100644 index a754573a52410..0000000000000 --- a/tests/run-make/no-input-file/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -include ../tools.mk - -all: - $(RUSTC) --print crate-name 2>&1 | diff - no-input-file.stderr diff --git a/tests/run-make/no-input-file/rmake.rs b/tests/run-make/no-input-file/rmake.rs new file mode 100644 index 0000000000000..26df7e80dfbff --- /dev/null +++ b/tests/run-make/no-input-file/rmake.rs @@ -0,0 +1,9 @@ +extern crate run_make_support; + +use run_make_support::{diff, rustc}; + +fn main() { + let output = rustc().print("crate-name").run_fail_assert_exit_code(1); + + diff().expected_file("no-input-file.stderr").actual_text("output", output.stderr).run(); +}